Frontend Roadmap
1. React Setup
2. Login Page
3. Register Page
4. JWT Token Storage
5. Protected Routes
6. Product List Page
7. Add To Cart
8. Cart Page
9. Place Order
10. Orders Page
11. Logout
12. Admin Dashboard (optional)
Recommended Folder Structure
src/
│
├── api/
│ └── axios.js
│
├── components/
│ ├── Navbar.jsx
│ └── ProtectedRoute.jsx
│
├── pages/
│ ├── Login.jsx
│ ├── Register.jsx
│ ├── Products.jsx
│ ├── Cart.jsx
│ └── Orders.jsx
│
├── App.jsx
└── main.jsx
Step 1: Axios Configuration
src/api/axios.js
import axios from "axios";
const api = axios.create({
baseURL: "http://127.0.0.1:8000",
});
api.interceptors.request.use((config) => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export default api;
Step 2: Login & Register
Build these first:
Login.jsx
Register.jsx
After successful login:
localStorage.setItem(
"token",
response.data.access_token
);
Redirect:
navigate("/products");
Step 3: Protected Routes
Create:
components/ProtectedRoute.jsx
import { Navigate } from "react-router-dom";
function ProtectedRoute({ children }) {
const token = localStorage.getItem("token");
return token ? children : <Navigate to="/" />;
}
export default ProtectedRoute;
Step 4: Product List
Call:
GET /products
Display:
Product Name
Price
Description
Add To Cart Button
When user clicks:
POST /cart/add
Body:
{
"product_id": "id",
"quantity": 1
}
Step 5: Cart Page
Call:
GET /cart
Display:
Product
Quantity
Place Order Button
Step 6: Place Order
Button click:
POST /orders
Success:
alert("Order Placed");
navigate("/orders");
Step 7: Orders Page
Call:
GET /orders
Display:
Order ID
Status
Total Amount
Start with Login.jsx first, then Register.jsx. Once those two pages are working and storing the JWT token correctly, move to Products.jsx. That keeps the frontend flow aligned with your backend.
=========================================================
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import api from "../api/axios";
function Login() {
const navigate = useNavigate();
const [formData, setFormData] = useState({
email: "",
password: "",
});
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
};
const handleLogin = async (e) => {
e.preventDefault();
try {
const response = await api.post(
"/auth/login",
formData
);
localStorage.setItem(
"token",
response.data.access_token
);
alert("Login Successful");
navigate("/products");
} catch (error) {
alert(
error.response?.data?.detail ||
"Login Failed"
);
}
};
return (
<div>
<h2>Login</h2>
<form onSubmit={handleLogin}>
<input
type="email"
name="email"
placeholder="Email"
onChange={handleChange}
required
/>
<br /><br />
<input
type="password"
name="password"
placeholder="Password"
onChange={handleChange}
required
/>
<br /><br />
<button type="submit">
Login
</button>
</form>
<br />
<p>
Don't have an account?
<Link to="/register"> Register</Link>
</p>
</div>
);
}
export default Login;
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import api from "../api/axios";
function Register() {
const navigate = useNavigate();
const [formData, setFormData] = useState({
name: "",
email: "",
password: "",
});
const handleChange = (e) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
};
const handleRegister = async (e) => {
e.preventDefault();
try {
const response = await api.post(
"/auth/register",
formData
);
alert(response.data.message);
navigate("/");
} catch (error) {
alert(
error.response?.data?.detail ||
"Registration Failed"
);
}
};
return (
<div>
<h2>Register</h2>
<form onSubmit={handleRegister}>
<input
type="text"
name="name"
placeholder="Name"
onChange={handleChange}
required
/>
<br /><br />
<input
type="email"
name="email"
placeholder="Email"
onChange={handleChange}
required
/>
<br /><br />
<input
type="password"
name="password"
placeholder="Password"
onChange={handleChange}
required
/>
<br /><br />
<button type="submit">
Register
</button>
</form>
<br />
<p>
Already have an account?
<Link to="/"> Login</Link>
</p>
</div>
);
}
export default Register;
================================
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Login from "./pages/Login";
import Register from "./pages/Register";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/register" element={<Register />} />
</Routes>
</BrowserRouter>
);
}
export default App;