Fix: Set isLoggedIn state and handle redirects

This commit addresses several issues related to the login flow:

- Corrects the `isLoggedIn` variable to use `setIsLoggedIn` in `App.jsx`.
- Passes `onLogin` and `isLoggedIn` props to `CampfireAppBar`.
- Enables logout functionality in `AppBar.jsx`.
- Modifies `AppRoutes.jsx` to conditionally render `CampfireAppBar`.
- Converts pages to use `React.forwardRef` for page transitions.
- Fixes the `useState` import in `App.jsx`.
- Moves `NotificationGroup` to the top of the form in `LoginComponent.jsx` to prevent overlap.
- Corrects the logo path in `LoginPage.jsx`.
- Improves input accessibility with a border in `LoginComponent.jsx`.
This commit is contained in:
2025-09-15 15:44:56 -05:00
parent 0ce04fb7ac
commit 591b113175
14 changed files with 190 additions and 37 deletions

View File

@@ -1,26 +1,46 @@
import React from 'react';
import { AppBar, AppBarSection, AppBarSpacer } from '@progress/kendo-react-layout';
import { Button } from '@progress/kendo-react-buttons';
import { Link } from 'react-router-dom';
import { Link, useNavigate } from 'react-router-dom';
const CampfireAppBar = ({ isLoggedIn, onLogin }) => {
const navigate = useNavigate();
const handleLogout = () => {
onLogin(false);
navigate('/login');
};
const CampfireAppBar = () => {
return (
<AppBar position="sticky">
<AppBarSection>
<Link to="/dashboard">
<Button look="flat">Dashboard</Button>
</Link>
<Link to="/editor">
<Button look="flat">New Post</Button>
</Link>
</AppBarSection>
<div>
<h1 style={{ color: "#ff5733", textAlign: "center" }}>Campfire Logs</h1>
<AppBar position="sticky" style={{ backgroundColor: "#edbd7d"}}>
<AppBarSection>
<AppBarSpacer style={{ width: 800 }} />
<Link to="/dashboard">
<Button look="flat">Dashboard</Button>
</Link>
<AppBarSpacer style={{ width: 10 }} />
<Link to="/editor">
<Button look="flat">+ New Post</Button>
</Link>
</AppBarSection>
<AppBarSpacer style={{width: 32 }} />
<AppBarSpacer style={{width: 50 }} />
<AppBarSection>
<Button look="flat">Logout</Button>
</AppBarSection>
</AppBar>
<AppBarSection>
{isLoggedIn ? (
<Button look="flat" onClick={handleLogout}>
Logout
</Button>
) : (
<Link to="/login">
<Button look="flat">Login</Button>
</Link>
)}
</AppBarSection>
</AppBar>
</div>
);
};

View File

@@ -0,0 +1,55 @@
import React, { useState } from 'react';
import { Input } from '@progress/kendo-react-inputs';
import { Label } from '@progress/kendo-react-labels';
import { Button } from '@progress/kendo-react-buttons';
import { Link } from 'react-router-dom';
import { Notification, NotificationGroup } from '@progress/kendo-react-notification';
const LoginComponent = ({ onLogin }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
const mockUsername = import.meta.env.VITE_MOCK_USERNAME;
const mockPassword = import.meta.env.VITE_MOCK_PASSWORD;
if (username === mockUsername && password === mockPassword) {
onLogin(true);
} else {
console.error("Invalid username or password");
setError("Invalid username or password. Please try again.");
setTimeout(() => {
setError('');
}, 50000);
}
};
return (
<>
<form onSubmit={handleSubmit}>
<div>
<Label htmlFor="username">Username: </Label>
<Input style={{ border: '1px solid #edbd7d' }} type="text" id="username" value={username} onChange={(e) => setUsername(e.target.value)} autoComplete="username" />
</div>
<div>
<Label htmlFor="password">Password: </Label>
<Input style={{ border: '1px solid #edbd7d' }} type="password" id="password" value={password} onChange={(e) => setPassword(e.target.value)} autoComplete="current-password" />
</div>
<Button look="flat" type="submit">Login</Button>
<div>
<NotificationGroup style={{ textAlign: 'center' }}>
{error && (<Notification type={{ style: 'error', icon: true }} closeable={true} onClose={() => setError('')}>
<span>{error}</span>
</Notification> )}
</NotificationGroup>
</div>
</form>
</>
);
};
export default LoginComponent;