feat: Enhance Login page design and fix UI details

This commit is contained in:
karenvicent
2025-07-31 16:32:30 -04:00
parent f934bbf829
commit 2e675f5dee
8 changed files with 130 additions and 31 deletions

View File

@@ -17,6 +17,7 @@ const FallbackActionButtons = ({ link, type }) => {
<Button
variant="contained"
color="accent"
sx={{ fontWeight: 700 }}
onClick={() => navigate(link)}
>
{t(`${type}.fallback.actionButton`)}

View File

@@ -1,7 +1,7 @@
import { useTheme } from "@emotion/react";
import { Box, Stack } from "@mui/material";
import Skeleton from "../../assets/Images/create-placeholder.svg?react";
import SkeletonDark from "../../assets/Images/create-placeholder-dark.svg?react";
import OutputAnimation from "../../assets/Animations/output.gif";
import DarkmodeOutput from "../../assets/Animations/darkmodeOutput.gif";
import Background from "../../assets/Images/background-grid.svg?react";
import { useSelector } from "react-redux";
@@ -37,11 +37,18 @@ const GenericFallback = ({ children }) => {
marginTop: "100px",
}}
>
{mode === "light" ? (
<Skeleton style={{ zIndex: 1 }} />
) : (
<SkeletonDark style={{ zIndex: 1 }} />
)}
<Box
component="img"
src={mode === "light" ? OutputAnimation : DarkmodeOutput}
Background="transparent"
alt="Loading animation"
sx={{
zIndex: 1,
border: "none",
borderRadius: theme.spacing(8),
width: "100%",
}}
/>
<Box
sx={{
"& svg g g:last-of-type path": {

View File

@@ -70,6 +70,9 @@ const DataTable = ({
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastTextSecondary,
},
"& .MuiTableBody-root .MuiTableRow-root:last-child .MuiTableCell-root": {
borderBottom: "none",
},
}}
>
<TableHead>

View File

@@ -7,7 +7,9 @@ import { PasswordEndAdornment } from "../../../Components/Inputs/TextInput/Adorn
import { loginCredentials } from "../../../Validation/validation";
import TextLink from "../../../Components/TextLink";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import Logo from "../../../assets/icons/checkmate-icon.svg?react";
import Background from "../../../assets/Images/background-grid.svg?react";
// Utils
import { login } from "../../../Features/Auth/authSlice";
import { useNavigate } from "react-router-dom";
@@ -92,34 +94,105 @@ const Login = () => {
<Stack
gap={theme.spacing(10)}
minHeight="100vh"
position="relative"
backgroundColor={theme.palette.primary.main}
sx={{ overflow: "hidden" }}
>
<AuthHeader />
<Stack
margin="auto"
width="100%"
alignItems="center"
gap={theme.spacing(10)}
<Box
sx={{
position: "absolute",
top: 0,
left: "0%",
transform: "translate(-40%, -40%)",
zIndex: 0,
width: "100%",
height: "100%",
"& svg g g:last-of-type path": {
stroke: theme.palette.primary.lowContrast,
},
}}
>
<Typography variant="h1">{t("auth.login.heading")}</Typography>
<Background style={{ width: "100%" }} />
</Box>
<Box
sx={{
position: "absolute",
bottom: 0,
right: 0,
transform: "translate(45%, 55%)",
zIndex: 0,
width: "100%",
height: "100%",
"& svg g g:last-of-type path": {
stroke: theme.palette.primary.lowContrast,
},
}}
>
<Background style={{ width: "100%" }} />
</Box>
<AuthHeader hideLogo={true} />
<Stack
backgroundColor={theme.palette.primary.main}
sx={{
borderRadius: theme.spacing(8),
boxShadow: theme.palette.tertiary.cardShadow,
margin: "auto",
alignItems: "center",
gap: theme.spacing(10),
padding: theme.spacing(20),
zIndex: 1,
position: "relative",
width: {
sm: "60%",
md: "50%",
lg: "40%",
xl: "30%",
},
}}
>
<Box
mb={theme.spacing(10)}
mt={theme.spacing(5)}
>
<Box
sx={{
width: { xs: 60, sm: 80, md: 90 },
}}
/>
<Logo style={{ width: "100%", height: "100%" }} />
</Box>
<Stack
mb={theme.spacing(12)}
textAlign="center"
>
<Typography
variant="h1"
mb={theme.spacing(2)}
>
{t("auth.login.welcome")}
</Typography>
<Typography variant="h1">{t("auth.login.heading")}</Typography>
</Stack>
<Stack
component="form"
width="100%"
maxWidth={600}
alignSelf="center"
justifyContent="center"
borderRadius={theme.spacing(5)}
borderColor={theme.palette.primary.lowContrast}
backgroundColor={theme.palette.primary.main}
padding={theme.spacing(12)}
padding={theme.spacing(8)}
gap={theme.spacing(12)}
onSubmit={onSubmit}
sx={{
width: {
sm: "80%",
md: "70%",
lg: "65%",
xl: "65%",
},
}}
>
<TextInput
type="email"
name="email"
label={t("auth.common.inputs.email.label")}
isRequired={true}
placeholder={t("auth.common.inputs.email.placeholder")}
autoComplete="email"
value={form.email}
@@ -131,7 +204,6 @@ const Login = () => {
type="password"
name="password"
label={t("auth.common.inputs.password.label")}
isRequired={true}
placeholder="••••••••••"
autoComplete="current-password"
value={form.password}
@@ -144,7 +216,7 @@ const Login = () => {
variant="contained"
color="accent"
type="submit"
sx={{ width: "30%", alignSelf: "flex-end" }}
sx={{ width: "100%", alignSelf: "center", fontWeight: 700 }}
>
Login
</Button>

View File

@@ -9,7 +9,7 @@ import ThemeSwitch from "../../../Components/ThemeSwitch";
import { useTheme } from "@mui/material/styles";
import { useTranslation } from "react-i18next";
const AuthHeader = () => {
const AuthHeader = ({ hideLogo = false }) => {
// Hooks
const theme = useTheme();
const { t } = useTranslation();
@@ -27,8 +27,12 @@ const AuthHeader = () => {
alignItems="center"
gap={theme.spacing(4)}
>
<Logo style={{ borderRadius: theme.shape.borderRadius }} />
<Typography sx={{ userSelect: "none" }}>{t("common.appName")}</Typography>
{!hideLogo && (
<>
<Logo style={{ borderRadius: theme.shape.borderRadius }} />
<Typography sx={{ userSelect: "none" }}>{t("common.appName")}</Typography>
</>
)}
</Stack>
<Stack
direction="row"

View File

@@ -216,6 +216,10 @@ const newSemanticColors = {
light: newColors.gray500,
dark: newColors.blueGray600,
},
cardShadow: {
light: "0 0 0 1px rgba(0, 0, 0, 0.04), 0 12px 24px rgba(0, 0, 0, 0.08)",
dark: "0 2px 10px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.04)",
},
},
success: {
main: {

View File

@@ -61,7 +61,6 @@ const baseTheme = (palette) => ({
style: {
backgroundColor: theme.palette.accent.main,
color: theme.palette.primary.contrastTextSecondaryDarkBg,
fontWeight: 700,
letterSpacing: "0.5px",
textShadow: "0 0 1px rgba(0, 0, 0, 0.15)",
"&:hover": {
@@ -723,6 +722,14 @@ const baseTheme = (palette) => ({
},
],
},
MuiTooltip: {
styleOverrides: {
tooltip: () => ({
fontSize: typographyLevels.m,
}),
},
},
},
shape: {
borderRadius: 2,

View File

@@ -154,7 +154,7 @@
"incorrect": "The password you provided does not match our records"
}
},
"heading": "Log In",
"heading": "Log in to continue",
"links": {
"forgotPassword": "Forgot password?",
"forgotPasswordLink": "Reset password",
@@ -168,7 +168,8 @@
"toasts": {
"incorrectPassword": "Incorrect password",
"success": "Welcome back! You're successfully logged in."
}
},
"welcome": "Welcome back to Checkmate!"
},
"registration": {
"description": {