Skip to content

Commit

Permalink
[Task] #77, introduced linearBuffer Bar for login
Browse files Browse the repository at this point in the history
  • Loading branch information
Type-Style committed Jul 3, 2024
1 parent e57e9ba commit 3c01fed
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 44 deletions.
12 changes: 6 additions & 6 deletions httpdocs/css/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,12 @@ Neutral: #131211
/* --mui-palette-FilledInput-bg:rgba(0, 0, 0, 0.06);
--mui-palette-FilledInput-hoverBg:rgba(0, 0, 0, 0.09);
--mui-palette-FilledInput-disabledBg:rgba(0, 0, 0, 0.12); */
--mui-palette-LinearProgress-primaryBg: color-mix(in oklch, var(--mui-palette-primary-main) 85%, transparent);
--mui-palette-LinearProgress-secondaryBg: color-mix(in oklch, var(--mui-palette-secondary-main) 85%, transparent);
--mui-palette-LinearProgress-errorBg: color-mix(in oklch, var(--mui-error-primary-main) 85%, transparent);
--mui-palette-LinearProgress-infoBg: color-mix(in oklch, var(--mui-palette-info-main) 85%, transparent);
--mui-palette-LinearProgress-successBg: color-mix(in oklch, var(--mui-palette-success-main) 85%, transparent);
--mui-palette-LinearProgress-warningBg: color-mix(in oklch, var(--mui-palette-warning-main) 85%, transparent);
--mui-palette-LinearProgress-primaryBg: color-mix(in oklch, var(--mui-palette-primary-main) 50%, transparent);
--mui-palette-LinearProgress-secondaryBg: color-mix(in oklch, var(--mui-palette-secondary-main) 50%, transparent);
--mui-palette-LinearProgress-errorBg: color-mix(in oklch, var(--mui-error-primary-main) 50%, transparent);
--mui-palette-LinearProgress-infoBg: color-mix(in oklch, var(--mui-palette-info-main) 50%, transparent);
--mui-palette-LinearProgress-successBg: color-mix(in oklch, var(--mui-palette-success-main) 50%, transparent);
--mui-palette-LinearProgress-warningBg: color-mix(in oklch, var(--mui-palette-warning-main) 50%, transparent);
--mui-palette-Skeleton-bg: rgba(var(--mui-palette-text-primaryChannel) / 0.11);
--mui-palette-Slider-primaryTrack: var(--mui-palette-primary-main);
--mui-palette-Slider-secondaryTrack: var(--mui-palette-secondary-main);
Expand Down
41 changes: 41 additions & 0 deletions src/client/components/LinearBuffer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import LinearProgress from '@mui/material/LinearProgress';

export default function LinearBuffer({ msStart, msFinish }: { msStart: number, msFinish: number }) {
const [progress, setProgress] = React.useState(0);
const [buffer, setBuffer] = React.useState(10);

const progressRef = React.useRef(() => { });
React.useEffect(() => {
progressRef.current = () => {
const duration = msFinish - msStart; // duration based on input props
const secondPhase = duration == 1000;
const date = new Date();
const now = date.getTime();

const bufferValue = secondPhase ? 100 : 90;
const progressCalcValue = ((now - msStart) / duration) * 100;
const progressValue = secondPhase ? 100 : Math.min(progressCalcValue, bufferValue);

setProgress(progressValue);
setBuffer(bufferValue);
};
});

React.useEffect(() => {
const timer = setInterval(() => {
progressRef.current();
}, 300);

return () => {
clearInterval(timer);
};
}, []);

return (
<Box sx={{ width: '100%' }}>
<LinearProgress variant="buffer" value={progress} valueBuffer={buffer} />
</Box>
);
}
79 changes: 55 additions & 24 deletions src/client/css/start.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,80 @@
.start {
/* theming */
--text: color-mix(in oklch, var(--neutral) 50%, black);

[data-mui-color-scheme="dark"] & {
--text: var(--main);
}

color: var(--text);


/* grid layout */
height: 100%;
display: grid;
grid-template-columns: 1fr 40vmin;
grid-template-columns: 1fr 40vmin;
grid-template-rows: minmax(3em, auto) 1fr 1fr 1fr minmax(3em, auto);
}

.grid-item {
.grid-item {

&.info {

&.info {
display: flex;
width: 100%;
justify-content: space-between;
padding: 0.7em 2em;

}
}

&.map {
grid-column: 1;
grid-row: 2 / span 3;
background-color: darkkhaki;
}
&.map {
grid-column: 1;
grid-row: 2 / span 3;
background-color: darkkhaki;
}

&.status {
grid-column: 2;
grid-row: 1 / span 2;
background-color: gold;
}
&.status {
grid-column: 2;
grid-row: 1 / span 2;
background-color: gold;
}

&.image {
grid-column: 2;
background-color: moccasin;
}

&.image+.image {
background-color: lightgoldenrodyellow;
}

&.image {
grid-column: 2;
background-color: moccasin;
&.subinfo {
grid-column: 1 / -1;
background-color: peachpuff;
}
}

&.image+.image {
background-color: lightgoldenrodyellow;
.error {
display: inline-flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
font-size: 1.3em;

.statusCode {
width: 100%;
text-align: center;
}
}

&.subinfo {
grid-column: 1 / -1;
background-color: peachpuff;
.loginButton {
color: var(--bg);
margin-left: auto;
cursor: pointer;

&.loginButton--loggedIn {
svg {
position: relative;
top: -0.1em; right: 0.1em;
}
}
}
}
24 changes: 19 additions & 5 deletions src/client/pages/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import axios from 'axios';
import qs from 'qs';
import { LoginContext } from '../components/App';
import { useNavigate } from 'react-router-dom';
import LinearBuffer from '../components/LinearBuffer';

function Login() {
const [finish, setFinish] = useState(1);
const [start, setStart] = useState(1);
const navigate = useNavigate();
const [isLoggedIn, setLogin] = useContext(LoginContext);
const [formInfo, updateFormInfo] = useState({
Expand Down Expand Up @@ -47,6 +50,11 @@ function Login() {

async function submit(e) {
e.preventDefault();
const date = new Date();
setStart(date.getTime());
const milliseconds = 9 * 1000; // Estimated bcrypt Time
setFinish(new Date(date.getTime() + milliseconds).getTime());

setLoading(true);
setMessageObj({ isError: null, status: null, message: null });

Expand All @@ -63,8 +71,8 @@ function Login() {
})
updateFormInfo({ ...formInfo, token: token.data });
} catch (error) {
setMessageObj({ isError: true, status: error.response.data.status || error.response.status, message: error.response.data.message || error.message })
console.log(error);
setMessageObj({ isError: true, status: error.response.data.status || error.response.status, message: error.response.data.message || error.message })
}

if (!token) { setLoading(false); return; } // skip when the first request has an error
Expand All @@ -81,14 +89,19 @@ function Login() {
const token = response.data.token;
sessionStorage.setItem("jwt", token);
setLogin(true);
setTimeout(() => { navigate("/") }, 300);
setMessageObj({ isError: false, status: <Check />, message: "Success!" })

// update linearBar for delay until redirect
const date = new Date();
setStart(date.getTime());
setFinish(new Date(date.getTime() + 1000).getTime());

// redirect back to main page
setTimeout(() => { setLoading(false); navigate("/") }, 1000);

setMessageObj({ isError: false, status: <Check />, message: "Success!" })
} catch (error) {
setMessageObj({ isError: true, status: error.response.data.status || error.response.status, message: error.response.data.message || error.message })
console.log(error);
} finally {
setMessageObj({ isError: true, status: error.response.data.status || error.response.status, message: error.response.data.message || error.message })
setLoading(false); // Reset loading after request is complete
}
}
Expand Down Expand Up @@ -180,6 +193,7 @@ function Login() {
Login
</Button>
</div>
{isLoading && <LinearBuffer msStart={start} msFinish={finish} />}
</form>
</div>
<svg className="bg-pattern" xmlns="http://www.w3.org/2000/svg">
Expand Down
31 changes: 22 additions & 9 deletions src/client/pages/Start.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,35 @@ import { LoginContext } from "../components/App";
import { HighlightOff, Check } from '@mui/icons-material';
import { Button } from '@mui/material';


function Start() {
const [isLoggedIn] = useContext(LoginContext);
const [isLoggedIn, setLogin] = useContext(LoginContext);
const [entries, setEntries] = useState<Models.IEntry[]>([]);
const [errorObj, setMessageObj] = React.useState({ isError: null, status: null, message: null });


useEffect(() => {
const token = sessionStorage.getItem("jwt");
let response;

const getData = async () => {
if (!token) {
setLogin(false);
setMessageObj({ isError: true, status: "403", message: "No token / logged out" })
return false;
}

try {
response = await axios({
method: 'get',
url: "/read?index=0",
headers: {
'Authorization': `Bearer ${token}`,
'Authorization': `Bearer ${token}`
}
});
setEntries(response.data.entries);
setMessageObj({ isError: null, status: null, message: null });
} catch (error) {
console.log(error)
setMessageObj({ isError: true, status: error.response.data.status || error.response.status, message: error.response.data.message || error.message });
}
};

Expand All @@ -41,20 +49,25 @@ function Start() {
return (
<div className="start">
<div className="grid-item info">
{errorObj.isError &&
<div className="error">
<strong className="statusCode">{errorObj.status}</strong> <span>{errorObj.message} </span>
</div>
}
<Button
className="cut"
className={`loginButton ${isLoggedIn ? "loginButton--loggedIn" : '' } cut`}
variant="contained"
href={isLoggedIn ? null : "/login"}
onClick={isLoggedIn ? () => { setLogin(false); sessionStorage.clear(); } : null}
endIcon={isLoggedIn ? <Check /> : null}
startIcon={isLoggedIn ? null : <HighlightOff />}
color={isLoggedIn ? "success" : "error"}
color={isLoggedIn ? "success" : "error"}
size="large"
>
{isLoggedIn ? "LoggedIn" : "Locked Out"}
{isLoggedIn ? "Logged In" : "Logged Out"}
</Button>
</div>


{isLoggedIn ? "yes" : "no"} info: {JSON.stringify(entries)}</div>
<div className="grid-item map">map</div>
<div className="grid-item status">status</div>
<div className="grid-item image">image1</div>
Expand Down

0 comments on commit 3c01fed

Please sign in to comment.