So i have route as below on the app js
import React from "react";
import Login from "./pages/Login";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Dashboard from "./pages/Dashboard";
import "./App.css";
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Dashboard />}>
<Route path="/login" element={<Login />} />
{/* <Route path="*" element={<Login />} /> */}
</Route>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
it works when the path is "/" its only show the dashboard page, but when i change the path with "/login", instead of showing the login pages it still showing the dashboard pages,can someone explain it to me..., even the "*" not working at all, when i change it into unregisterd path it still showing the dashboard page...
Here is what the sidebar component code:
import React, { useState } from "react";
import { Fragment } from "react";
import { Route, Link } from "react-router-dom";
import {
MdOutlineSpaceDashboard,
MdOutlineStorage,
MdOutlineFactCheck,
MdOutlineCalculate,
MdStickyNote2,
MdAssignmentTurnedIn,
MdOutlineDynamicForm,
MdOutlineArrowDropDown,
} from "react-icons/md";
import { BsChevronDown, BsArrowLeftShort } from "react-icons/bs";
import Logo_Nabati from "../assets/logo-nabati.svg";
const menuItems = [
{ id: 1, label: "Dashboard", icon: MdOutlineSpaceDashboard, link: "/" },
{
id: 2,
label: "Master Data",
icon: MdOutlineStorage,
iconArrow: MdOutlineArrowDropDown,
link: "",
subMenu: true,
subMenuItems: [
{ id: 8, label: "KSBT", link: "/MasterData/list/KSBT" },
{ id: 9, label: "SQ01_RM", link: "/MasterData" },
{ id: 10, label: "SQ01_PM", link: "/MasterData" },
{ id: 11, label: "Depre", link: "/MasterData" },
{ id: 12, label: "OMC", link: "/MasterData" },
{ id: 13, label: "Premix", link: "/MasterData" },
{ id: 14, label: "Routing", link: "/MasterData" },
{ id: 15, label: "MP", link: "/MasterData" },
],
},
{ id: 3, label: "Check COGM", icon: MdOutlineFactCheck, link: "/checkcogm" },
{
id: 4,
label: "Calculation",
icon: MdOutlineCalculate,
link: "/calculation",
},
{
id: 5,
label: "Draft Calculation",
icon: MdStickyNote2,
link: "/draft",
},
{ id: 6, label: "Approved", icon: MdAssignmentTurnedIn, link: "/approval" },
{ id: 7, label: "Task Activity", icon: MdOutlineDynamicForm, link: "/task" },
];
const Sidebar = () => {
const [open, setOpen] = useState(false);
const [submenuOpen, setSubmenuOpen] = useState(false);
return (
<div className="flex">
<div
className={` bg-yellow-400 h-screen p-5 pt-8 ${
open
? "w-50 ease-out delay-150 peer-focus:left-0 duration-200"
: "w-20 ease-out delay-150 peer-focus:left-0 duration-200"
} duration-300 relative`}
>
<BsArrowLeftShort
className={` bg-white text-yellow-300 text-3xl rounded-full absolute -right-3 top-9 border border-yellow-300 cursor-pointer delay-150 duration-200 ${
!open && "rotate-180"
}`}
onClick={() => setOpen(!open)}
/>
<div className={`inline-flex`}>
<img src={Logo_Nabati} width={115} height={65} alt="logo Nabati" />
</div>
<ul className="pt-8">
{menuItems.map(
({ icon: Icon, iconArrow: IconArrow, ...menu }, index) => (
<Fragment key={index}>
<Link to={menu.link}>
<li className="text-white text-sm text-justify flex items-center gap-x-4 cursor-pointer p-2 hover:bg-red-600 rounded-md mt-2">
<Icon className="text-2xl text-white group-hover:text-red-600" />
<span
className={`text-base font-mendium flex-1 duration-200 ${
!open && "hidden"
} `}
>
{menu.label}
</span>
{menu.subMenu && (
<BsChevronDown
className={`text-base font-mendium duration-200 ${
!open && "hidden"
} ${submenuOpen && "rotate-180"}`}
onClick={() => {
setSubmenuOpen(!submenuOpen);
}}
/>
)}
</li>{" "}
</Link>
{menu.subMenu && submenuOpen && open && (
<ul>
{menu.subMenuItems.map((subMenuItem, j) => (
<Link to={subMenuItem.link}>
<li
key={subMenuItem.id}
className="text-white text-sm flex items-center gap-x-4 cursor-pointer p-0.5 px-12 hover:bg-red-500 rounded-md"
>
{subMenuItem.label}
</li>{" "}
</Link>
))}
</ul>
)}
</Fragment>
)
)}
</ul>
</div>
</div>
);
};
export default Sidebar;
and here is the dashboard page:
import Layout from "../containers/layout";
const Dashboard = () => {
return (
<Layout>
<>Dasboard</>
</Layout>
);
};
export default Dashboard;
here is the layout page:
import { Sidebar } from "../components";
const Layout = ({ children }) => {
return (
<div className="flex flex-row justify-start">
<Sidebar />
<div className="bg-white flex-1 pl-4 pt-4 w-full text-red-600">
{children}
<Outlet/>
</div>
</div>
);
};
export default Layout;
here is my login page:
import { FaUser, FaLock, FaUserLock } from "react-icons/fa";
import logo_nabati from "../assets/logo-nabati.svg";
import { connect } from "react-redux";
import { useState, useEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
const required = (value) => {
if (!value) {
return (
<div className="alert alert-danger" role="alert">
This field is required!
</div>
);
}
};
const Login = (props) => {
const initState = {
newAttribs: { ...props.test },
};
const form = useRef();
const checkBtn = useRef();
const [userList, setUserList] = useState(initState);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
useEffect(() => {
setUserList((userList) => ({
...userList,
newAttribs: { ...props.test },
}));
}, [props.test]);
const onChangeUsername = (e) => {
const username = e.target.value;
setUsername(username);
};
const onChangePassword = (e) => {
const password = e.target.value;
setPassword(password);
};
console.log("userList now", userList);
const loginSubmit = (e) => {
e.preventDefault();
console.log("====================================");
console.log(username, password);
console.log("====================================");
};
return (
<div>
{/* container */}
<div className="bg-gradient-to-r from-yellow-400 block h-screen items-center justify-center p-4 pt-32 md:flex">
{/* login.card */}
<div className=" bg-no-repeat bg-left bg-image flex flex-col items-center max-w-screen-lg overflow-hidden rounded-lg shadow-lg text-white w-full md:flex-row">
{/* logo */}
<div className="backdrop-blur-sm backdrop-filter flex flex-col items-center justify-center p-4 text-dark w-full md:w-1/2">
<h1 className="font-medium text-3xl">COGM Calculation</h1>
<p className="italic text-lg">For Manufacturing Cost Controller</p>
</div>
{/* form */}
<div className="bg-white flex flex-col items-center p-4 space-y-8 w-full md:w-1/2">
{/* title */}
<div className="flex flex-col items-center">
<h1 className="font-medium text-yellow-500 text-xl">Welcome</h1>{" "}
<img
className="m-2"
src={logo_nabati}
width={123}
height={75}
alt="logo Nabati"
/>
<p className="text-gray-600">
<strong>Login to COGM Page</strong>
</p>
</div>
{/* input */}
<form
onSubmit={loginSubmit}
className="flex flex-col items-center space-y-3 pt-0"
>
<div className="relative">
<span className="absolute flex inset-y-0 items-center pl-4 text-gray-400">
<FaUser></FaUser>
</span>
<input
className="border border-gray-300 outline-none text-black placeholder-gray-400 pl-9 pr-4 py-1 rounded-md transition focus:ring-2 focus:ring-yellow-300"
placeholder="Username...."
type="text"
onChange={onChangeUsername}
validations={[required]}
></input>
</div>
<div className="relative">
<span className="absolute flex inset-y-0 items-center pl-4 text-gray-400">
<FaLock></FaLock>
</span>
<input
className="border border-gray-300 outline-none text-black placeholder-gray-400 pl-9 pr-4 py-1 rounded-md transition focus:ring-2 focus:ring-yellow-300"
placeholder="Password...."
type="password"
onChange={onChangePassword}
validations={[required]}
></input>
</div>
<div className="items-left">
<button
className="bg-yellow-500 font-medium inline-flex items-center px-3 py-1 rounded-md shadow-sm text-white hover:bg-yellow-600 pr-100"
type="submit"
ref={checkBtn}
>
<FaUserLock className="mr-2"></FaUserLock>
Sign In
</button>
</div>
</form>
{/* button Link */}
<div className="flex flex-col items-center text-gray-600">
<p className="italic">Forget password</p>
</div>
</div>
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => ({
test: state.Auth,
});
export default connect(mapStateToProps)(Login);
when i put the outlet on the layout page, it turn my page into this:
CodePudding user response:
(I suppose you're using React Router v6)
Because your login route is inside of the dashboard:
<Route exact path="/" element={<Dashboard />}>
<Route path="/login" element={<Login />} />
</Route>
Just move the nested login outside: (there is no exact
in v6)
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="login" element={<Login />} />
</Routes>
If you want to have some nested routes in your Dashboard, like /dashboard/profile
:
<Routes>
<Route path="/" element={<Dashboard />}>
<Route path="profile" element={<Profile />} />
</Route>
<Route path="login" element={<Login />} />
</Routes>
[Update] I think this is probably what you want:
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Dashboard />} />
</Route>
<Route path="login" element={<Login />} />
</Routes>
In this case you don't need the {children}
in your Layout.