feat: initialize dashboard structure with auth, feed management, and activity feed filtering components
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Box, Button, TextField, Typography, Container, Alert } from '@mui/material';
|
||||
import { Box, Button, TextField, Container, Alert, Paper } from '@mui/material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { accountService } from '../../api/accountService';
|
||||
@@ -76,88 +76,138 @@ export const Login: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Container component="main" maxWidth="xs">
|
||||
<Box sx={{ marginTop: 8, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
|
||||
|
||||
{/* Placeholder for Logo */}
|
||||
<Box sx={{ mb: 6, display: 'flex', justifyContent: 'center' }}>
|
||||
<img src="/images/SeekRightLogo.png" alt="Logo" width="250" onError={(e) => { e.currentTarget.style.display = 'none'; }} />
|
||||
</Box>
|
||||
|
||||
<Box component="form" sx={{ mt: 1, width: '100%' }}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="username"
|
||||
placeholder="Admin"
|
||||
name="username"
|
||||
autoFocus
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
InputProps={{
|
||||
sx: { borderRadius: '50px', '& fieldset': { borderColor: '#738ab8' } }
|
||||
}}
|
||||
sx={{
|
||||
mb: 1,
|
||||
'& .MuiInputBase-input': { padding: '10px 14px', fontSize: '0.9rem', color: '#333' }
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
InputProps={{
|
||||
sx: { borderRadius: '50px', '& fieldset': { borderColor: '#738ab8' } }
|
||||
}}
|
||||
sx={{
|
||||
mt: 1,
|
||||
mb: 3,
|
||||
'& .MuiInputBase-input': { padding: '10px 14px', fontSize: '0.9rem', color: '#333' }
|
||||
}}
|
||||
/>
|
||||
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 3, mb: 4 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!username || !password || loading}
|
||||
onClick={handleLogin}
|
||||
sx={{
|
||||
borderRadius: '50px',
|
||||
backgroundColor: '#738ab8',
|
||||
width: '140px',
|
||||
pt: 1, pb: 1,
|
||||
boxShadow: 'none',
|
||||
'&:hover': {
|
||||
backgroundColor: '#5c729c',
|
||||
boxShadow: 'none',
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? '...' : 'LOGIN'}
|
||||
</Button>
|
||||
<Box sx={{
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
background: 'radial-gradient(circle at center, #0f172a 0%, #0b1121 100%)',
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
<Container component="main" maxWidth="xs">
|
||||
<Paper sx={{
|
||||
p: 4,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
bgcolor: 'rgba(15, 23, 42, 0.65)',
|
||||
backdropFilter: 'blur(12px)',
|
||||
border: '1px solid rgba(255, 255, 255, 0.08)',
|
||||
borderRadius: 4,
|
||||
boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.5)'
|
||||
}}>
|
||||
{/* Logo */}
|
||||
<Box sx={{ mb: 4, display: 'flex', justifyContent: 'center' }}>
|
||||
<img
|
||||
src="/assets/images/logo/side-bar-logo.png"
|
||||
alt="Logo"
|
||||
width="220"
|
||||
onError={(e) => {
|
||||
e.currentTarget.src = "/images/SeekRightLogo.png";
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box component="form" sx={{ width: '100%' }}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="username"
|
||||
placeholder="Username"
|
||||
name="username"
|
||||
autoFocus
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
slotProps={{
|
||||
input: {
|
||||
sx: {
|
||||
borderRadius: '50px',
|
||||
color: '#f8fafc',
|
||||
bgcolor: 'rgba(255, 255, 255, 0.02)',
|
||||
'& fieldset': { borderColor: 'rgba(255, 255, 255, 0.12)' },
|
||||
'&:hover fieldset': { borderColor: 'rgba(255, 255, 255, 0.25)' },
|
||||
'&.Mui-focused fieldset': { borderColor: '#3b82f6' }
|
||||
}
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
mb: 1.5,
|
||||
'& .MuiInputBase-input': { padding: '12px 18px', fontSize: '0.9rem' }
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
name="password"
|
||||
placeholder="Password"
|
||||
type="password"
|
||||
id="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && handleLogin()}
|
||||
slotProps={{
|
||||
input: {
|
||||
sx: {
|
||||
borderRadius: '50px',
|
||||
color: '#f8fafc',
|
||||
bgcolor: 'rgba(255, 255, 255, 0.02)',
|
||||
'& fieldset': { borderColor: 'rgba(255, 255, 255, 0.12)' },
|
||||
'&:hover fieldset': { borderColor: 'rgba(255, 255, 255, 0.25)' },
|
||||
'&.Mui-focused fieldset': { borderColor: '#3b82f6' }
|
||||
}
|
||||
}
|
||||
}}
|
||||
sx={{
|
||||
mt: 1.5,
|
||||
mb: 3,
|
||||
'& .MuiInputBase-input': { padding: '12px 18px', fontSize: '0.9rem' }
|
||||
}}
|
||||
/>
|
||||
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', mt: 1, mb: 1 }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
disabled={!username || !password || loading}
|
||||
onClick={handleLogin}
|
||||
sx={{
|
||||
borderRadius: '50px',
|
||||
backgroundColor: '#3b82f6',
|
||||
color: '#fff',
|
||||
fontWeight: 'bold',
|
||||
width: '100%',
|
||||
py: 1.5,
|
||||
boxShadow: 'none',
|
||||
textTransform: 'none',
|
||||
fontSize: '1rem',
|
||||
'&:hover': {
|
||||
backgroundColor: '#2563eb',
|
||||
boxShadow: 'none',
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
backgroundColor: 'rgba(59, 130, 246, 0.3)',
|
||||
color: 'rgba(255, 255, 255, 0.3)'
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? 'Logging in...' : 'LOGIN'}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
|
||||
{isInvalid && (
|
||||
<Alert severity="error" sx={{ mt: 2 }}>
|
||||
Invalid Credentials
|
||||
</Alert>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
{isInvalid && (
|
||||
<Alert severity="error" sx={{ mt: 3, borderRadius: 2 }}>
|
||||
Invalid Credentials
|
||||
</Alert>
|
||||
)}
|
||||
</Box>
|
||||
</Paper>
|
||||
</Container>
|
||||
|
||||
{/* Database Selection Dialog for SR_AUDITOR */}
|
||||
<DbSelectionDialog open={dialogOpen} onClose={handleDbSelection} />
|
||||
</Container>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user