Im implementing a basic login which checks wether a user is in a list or not, if it is, then put the username into localStorage and then redirect to (“/”) based on the console.log it sais that it got redirected but it doesnt actually redirect:
import { useNavigate } from 'react-router-dom';
function Login({ fakeData }) {
const [username, setUsername] = useState('');
const navigate = useNavigate();
const handleSubmit = async (event) => {
event.preventDefault();
console.log('Submitting login form');
console.log('Username: ' + username);
// Check if user with entered username exists
const userExists = fakeData.users.find((user) => user.username === username);
if (userExists) {
console.log('User exists. Redirecting to /');
localStorage.setItem('loggedInUser', username); // Set username in localStorage
navigate('/');
} else {
// Clear username
setUsername('');
console.log('User does not exist.');
// Handle invalid username case (display error message, etc.)
}
};
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<div style={{ padding: '1rem', border: '1px solid black', borderRadius: '8px', width: '300px' }}>
<form onSubmit={handleSubmit}>
<div style={{ marginBottom: '1rem', display: 'flex', alignItems: 'center' }}>
<label htmlFor="username" style={{ marginRight: '0.5rem' }}>
Username:
</label>
<input
type="text"
id="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<button type="submit" className="btn btn-primary">
Login
</button>
</div>
</form>
</div>
</div>
);
}
export default Login;
as you see it gets printed out, but it still stays on /login
import React from 'react';
import {BrowserRouter as Router, Routes, Route, Navigate} from 'react-router-dom';
import Dashboard from "./components/Dashboard";
import DifficultyComparison from "./components/comparisons/DifficultyComparison";
import RestrictionComparison from "./components/comparisons/RestrictionComparison";
import EnvironmentComparison from "./components/comparisons/EnvironmentComparison";
import CurrentContributionComparison from "./components/comparisons/CurrentContributionComparison";
import AllowsMeToComparison from "./components/comparisons/AllowsMeToComparison";
import SustainableDevelopmentComparison from "./components/comparisons/SustainableDevelopmentComparison";
import 'bootstrap/dist/css/bootstrap.min.css';
import {useState} from "react";
import Login from "./components/Login";
const App = () => {
const [fakeData, setFakeData] = useState({
users: [
{
userid: 1,
username: "Max Mustermann",
},
{
userid: 12,
username: "Peter Mueller",
},
{
userid: 3,
username: "Hans Meier",
}, {
userid: 4,
username: "Hans Meier2",
}
],
groups: [
{
groupid: 1,
groupname: "Gruppe 1",
users: [1, 12] // userids
},
{
groupid: 2,
groupname: "Gruppe 2",
users: [4] // userids
},
{
groupid: 3,
groupname: "Gruppe 3",
users: [3] // userids
}
],
commitments: [
{
commitmentid: -1,
commitmentname: "Challenge",
}
, {
commitmentid: 1,
commitmentname: "Ich ernähre mich vegan",
},
{
commitmentid: 2,
commitmentname: "Wasserhahn beim Zähneputzen abstellen",
}
],
diary: [{
diaryid: 1,
userid: 1,
commitmentid: 1,
schluesse: {
selbst: "Ich habe gelernt, dass ich mit kleinen Dingen einen grossen Beitrag leisten kann.",
sozial: "Meine Eltern haben micht erst nicht so unterstützt",
politik: "Politiker ist es eigentlich egal",
produkt: "Diese sind auch nur auf Profit aus",
},
eingeloest: 20,
feelings: [0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1, 0, 0.1, 0.8],
difficulty: [0.4, 0.8],
restriction: [0.2, 0.6],
environment: [0.1, 0.5],
currentContribution: [0.3, 0.7],
allowsMeTo: [0.5, 0.9],
sustainableDevelopment: [0.6, 1],
}, {
diaryid: 2,
userid: 12,
commitmentid: 1,
schluesse: {
selbst: "Ich ernähre mich jetzt gesünder",
sozial: "Meine Freunde haben grad mitgemacht",
politik: "Politiker sind nicht so interessiert",
produkt: "Alles ist 3x verpackt",
},
eingeloest: 28,
feelings: [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5],
difficulty: [0.4, 0.7],
restriction: [0.2, 0.6],
environment: [0.1, 0.5],
currentContribution: [0.3, 0.7],
allowsMeTo: [0.5, 0.9],
sustainableDevelopment: [0.6, 1],
}, {
diaryid: 3,
userid: 3,
commitmentid: 2,
schluesse: {
selbst: "Ich ernähre mich jetzt gesünder",
sozial: "Meine Freunde haben grad mitgemacht",
politik: "Politiker sind nicht so interessiert",
produkt: "Alles ist 3x verpackt",
},
eingeloest: 24,
feelings: [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5],
difficulty: [0.4, 0.8],
restriction: [0.2, 0.6],
environment: [0.1, 0.5],
currentContribution: [0.3, 0.7],
allowsMeTo: [0.5, 0.9],
sustainableDevelopment: [0.6, 1],
}, {
diaryid: 4,
userid: 12,
commitmentid: 2,
schluesse: {
selbst: "Ich ernähre mich jetzt gesünder",
sozial: "Meine Freunde haben grad mitgemacht",
politik: "Politiker sind nicht so interessiert",
produkt: "Alles ist 3x verpackt",
},
eingeloest: 2,
feelings: [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5],
difficulty: [0.4, 0.1],
restriction: [0.2, 0.6],
environment: [0.1, 0.5],
currentContribution: [0.3, 0.7],
allowsMeTo: [0.5, 0.9],
sustainableDevelopment: [0.6, 1],
},
{
diaryid: 5,
userid: 4,
commitmentid: 2,
schluesse: {
selbst: "plartzhalter",
sozial: "plartzhalter",
politik: "plartzhalter",
produkt: "plartzhalter",
},
eingeloest: 6,
feelings: [0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.5, 0.4, 1, 0.3, 0.1, 0.2, 0.3, 0.4, 0.5],
difficulty: [0.4, 0.8],
restriction: [0.2, 0.6],
environment: [0.1, 0.5],
currentContribution: [0.3, 0.7],
allowsMeTo: [0.5, 0.9],
sustainableDevelopment: [0.6, 1],
}
]
});
const [selectedOption1, setSelectedOption1] = useState('Max Mustermann');
const [selectedOption2, setSelectedOption2] = useState('Challenge');
const [selectedOption3, setSelectedOption3] = useState([]);
const loggedInUser = localStorage.getItem('loggedInUser');
return (
<Router>
<Routes>
{!loggedInUser && <Route path="/*" element={<Navigate to="/login"/>}/>}
<Route path="/login" element={<Login fakeData={fakeData}/>}/>
<Route
path="/"
element={
loggedInUser ? (
<Dashboard
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/difficulty"
element={
loggedInUser ? (
<DifficultyComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/restriction"
element={
loggedInUser ? (
<RestrictionComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/environment"
element={
loggedInUser ? (
<EnvironmentComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/currentcontribution"
element={
loggedInUser ? (
<CurrentContributionComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/allowsmeto"
element={
loggedInUser ? (
<AllowsMeToComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
<Route
path="/sustainabledevelopment"
element={
loggedInUser ? (
<SustainableDevelopmentComparison
fakeData={fakeData}
selectedOption1={selectedOption1}
setSelectedOption1={setSelectedOption1}
selectedOption2={selectedOption2}
setSelectedOption2={setSelectedOption2}
selectedOption3={selectedOption3}
setSelectedOption3={setSelectedOption3}
/>
) : (
<Navigate to="/login"/>
)
}
/>
</Routes>
</Router>
);
};
export default App;
it should also be said that in the website i did use d3.js which also changes the virtual dom and im doing refreshes here and there to update charts and such, so what i think happened is that it redirects, but there kinda is a conflict with the dom or so and it reloads? idk ill provide
a code sample aswell:
import * as d3 from 'd3';
function CommitmentsBar({
data,
width,
height,
fakeData,
selectedOption1,
selectedOption2,
selectedOption3,
setSelectedOption1,
setSelectedOption2,
setSelectedOption3
}) {
let eingeloeste = [];
const cId = fakeData.commitments.filter(commitment => commitment.commitmentname === selectedOption2)[0].commitmentid;
if (cId >= 0) {
const cId = fakeData.commitments.filter(commitment => commitment.commitmentname === selectedOption2)[0].commitmentid;
selectedOption3.map(option => {
const groupOfUsers = fakeData.groups.filter(group => group.groupname === option)[0].users;
const diariesFromCiD = fakeData.diary.filter(diary => diary.commitmentid === cId);
const selectedDiaries = diariesFromCiD.filter(diary => groupOfUsers.includes(diary.userid));
const eingeloest = selectedDiaries.map(diary => diary.eingeloest);
const sum = eingeloest.reduce((a, b) => a + b, 0);
const avg = sum / groupOfUsers.length || 0;
eingeloeste.push(avg);
return avg;
});
}
data = eingeloeste.length > 0 ? eingeloeste : [];
const groups = selectedOption3
const colors = ["#85B3B7"];
const svgRef = useRef();
useEffect(() => {
const svg = d3.select(svgRef.current)
.attr("width", width)
.attr("height", height)
.style('overflow', 'visible');
const xScale = d3.scaleBand()
.domain(data.map((value, index) => index))
.range([0, width])
.padding(0.5);
const yScale = d3.scaleLinear()
.domain([0, 28])
.range([height, 0]);
const xAxis = d3.axisBottom(xScale)
.tickFormat((value, index) => groups[index])
.tickSize(0);
const yAxis = d3.axisLeft(yScale)
.ticks(6)
.tickValues([5, 10, 15, 20, 25, 28]);
svg.selectAll('g').remove();
svg.append('g')
.call(xAxis)
.attr('transform', `translate(0, ${height})`)
.selectAll('text')
.style('font-size', '16px');
svg.append('g')
.call(yAxis)
.selectAll('text')
.style('fill', 'black')
.style('font-size', '16px');
const horizontalLines = d3.axisLeft(yScale)
.ticks(5)
.tickSize(-width)
.tickFormat('')
.tickSizeOuter(0);
svg.append('g')
.call(horizontalLines)
.attr('class', 'horizontal-lines')
.selectAll('.tick line')
.attr('stroke', 'lightgrey')
.attr('stroke-width', 1)
.attr('stroke-dasharray', '4 4');
const group = svg.selectAll('.group')
.data(data)
.join('g')
.attr('class', 'group');
group.append('rect')
.attr('class', 'bar')
.attr('x', (value, index) => xScale(index))
.attr('y', yScale)
.attr('width', xScale.bandwidth())
.attr('height', value => height - yScale(value))
.attr('fill', '#85B3B7');
group.each(function (d, i) {
if (i % 4 === 3) {
// Append a line and text to every 4th group
const groupIndex = Math.floor(i / 4);
d3.select(this)
.append('line')
.attr('class', 'line')
.attr('x1', xScale(i) + xScale.bandwidth() / 2 + 15)
.attr('y1', yScale(28))
.attr('x2', xScale(i) + xScale.bandwidth() / 2 + 15)
.attr('y2', yScale(28) - 30)
.attr('stroke', 'grey')
.attr('stroke-width', 1);
d3.select(this)
.append('text')
.attr('class', 'group-label')
.attr('x', xScale(i) + xScale.bandwidth() / 2 + 15)
.attr('y', yScale(28) - 35)
.text(`Klasse ${groupIndex + 1}`)
.style('font-size', '12px')
.style('text-anchor', 'middle');
}
});
const legendWidth = 80 * colors.length;
const legend = svg.append('g')
.attr('transform', `translate(${(width - legendWidth) / 2}, ${height - 20})`);
legend.selectAll('.legend-item')
.data(colors)
.join('g')
.attr('class', 'legend-item')
.attr('transform', (value, index) => `translate(${index * 80}, 0)`)
.call(g => {
g.append('rect')
.attr('x', 0)
.attr('y', -height)
.attr('width', 15)
.attr('height', 15)
.attr('fill', value => value);
g.append('text')
.attr('x', 20)
.attr('y', -height + 13)
.text(`Eingelöste Commitments`)
});
}, [data, groups, height, width, selectedOption3]);
return <svg ref={svgRef}/>;
}
export default CommitmentsBar;