Medicare Frontend Authentication with JWT & Protected Routes

Business Scenario

In this lab, we will integrate the Medicare React frontend with the existing Spring Boot authentication system by implementing user registration, login, and JWT-based authentication.

Pre-Lab Preparation

Module:

1) React Basics & Backend Integration (Spring Boot)​

React + Vite project
Bootstrap
Axios
createBrowserRouter
Clean folder structure
Central API configuration
Environment variable for backend URL
  • By the end of this phase, we will have:

Phase 12A — React Frontend Foundation

Frontend running successfully
C:\MEDICAREPROJECT\medicare-backend

Go to Your Project Folder

1

  • You currently have:
  • We want frontend and backend side by side:
C:\MEDICARE PROJECT
│
├── medicare-backend
└── medicare-frontend
  • Open CMD/PowerShell/terminal:
Frontend running successfully
C:\MEDICAREPROJECT\medicare-backend

Go to Your Project Folder

1

  • You currently have:
  • We want frontend and backend side by side:
C:\MEDICARE PROJECT
│
├── medicare-backend
└── medicare-frontend
  • Open CMD/PowerShell/terminal:
npm create vite@latest medicare-frontend -- --template react

Create React Project

2

  • Run:
cd "C:\MEDICARE PROJECT"
npm create vite@latest medicare-frontend -- --template react
  • Run:
npm create vite@latest medicare-frontend -- --template react
  • Run:
  • Bootstrap supports installation through npm; its current official 5.x docs list Bootstrap 5.3.8. ​
  • The current React Router installation guide uses:
npm i react-router

and createBrowserRouter. ​

First Run

4

  • Before changing anything, run:
npm run dev
  • You should see something similar to:
Local: http://localhost:5173/
  • Open it in the browser.
  • If the default Vite React page appears:
React + Vite

your frontend setup is working.

Delete Default Vite Files

5

  • Inside: src/ you may have:
  • You may have:
assets/
App.css
App.jsx
index.css
main.jsx
  • Delete:
assets/
App.css
App.jsx
  • We'll create our own structure.

Create .env

6

VITE_API_BASE_URL=http://localhost:8080/api
  • Go to the root of: medicare-frontend/
  • Not inside src.
  • Create: .env
  • Add:
  • Your project becomes:
medicare-frontend/
├── src/
├── public/
├── .env
├── package.json
└── vite.config.js
  • Why? --> Instead of writing this everywhere:
"http://localhost:8080/api"
  • We maintain it once.
  • Later:
Development Backend
http://localhost:8080/api
  • Could be replaced without modifying every service.

Create Central Axios Configuration

7

  • Create:
src/api/api.js
  • Add :
import axios from "axios";

const api = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL,
    headers: {
        "Content-Type": "application/json"
    }
});

export default api;
  • Now later we won't do:
axios.get(
    "http://localhost:8080/api/doctors"
);
  • Instead: api.get("/doctors");

Why We Have api.js

  • Consider:
doctorService
       ↓
      api
       ↓
 Spring Boot
  • Every service can use the same base URL
import api from "../api/api";
  • For example later:
api.get("/doctors");
  • or:
api.post("/auth/login", data);

Configure Bootstrap

8

  • Open: src/main.jsx
  • Replace everything with:
import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider } from "react-router/dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min.js";
import "./index.css";
import router from "./routes/router";

ReactDOM.createRoot(document.getElementById("root")).render(
  
    <React.StrictMode>
        <RouterProvider router={router} />
    </React.StrictMode>

);

Minimal CSS

9

  • Open: src/index.css
  • Replace everything with:
body {
    margin: 0;
    min-height: 100vh;
    background-color: #f8f9fa;
}

#root {
    min-height: 100vh;
}
  • Notice we're not writing hundreds of lines of CSS.
  • Bootstrap will handle most of our design.

Create Home Page

10

  • Create src/pages/common/Home.jsx
import { Link } from "react-router";

function Home() {

    return (
        <div className="container py-5">
            <div className="text-center py-5">
                <h1 className="display-5 fw-bold"> Medicare Healthcare </h1>
                <p className="lead text-secondary mt-3">
                    Book doctor appointments and manage your healthcare easily.
                </p>

                <div className="d-flex justify-content-center gap-3 mt-4">
                    <Link to="/login" className="btn btn-primary" > Login </Link>
                    <Link to="/register" className="btn btn-outline-primary">
                   Register </Link>
                </div>

            </div>
        </div>
    );
}
export default Home;

Create Login Placeholder

11

  • Create: src/pages/auth/Login.jsx
function Login() {
    return (
        <div className="container py-5">
            <div className="row justify-content-center">
                <div className="col-md-6 col-lg-5">
                    <div className="card shadow-sm">
                        <div className="card-body p-4">
                            <h2 className="text-center mb-4">Login</h2>
                            <p className="text-center text-secondary">
                                Login form will be implemented
                                in the authentication phase.
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
   
    );
}

export default Login;
  • Don't worry — this is intentionally a placeholder.
  • We'll build the actual form in Phase 12B.

Register Placeholder

12

  • Create src/pages/auth/Register.jsx
function Register() {
    return (
        <div className="container py-5">
            <div className="row justify-content-center">
                <div className="col-md-7 col-lg-6">
                    <div className="card shadow-sm">
                        <div className="card-body p-4">
                            <h2 className="text-center mb-4">Create Account</h2>
                            <p className="text-center text-secondary">
                                Patient registration form will be implemented next.
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Register;

Patient Dashboard Placeholder

13

  • Create src/pages/patient/PatientDashboard.jsx
function PatientDashboard() {

    return (
        <div className="container py-5">

            <h2> Patient Dashboard </h2>
            <p className="text-secondary">
                Welcome to your Medicare dashboard.
            </p>

        </div>
    );
}

export default PatientDashboard;
  • Later this becomes:
Patient Dashboard
    ├── Find Doctor
    ├── My Appointments
    ├── My Prescriptions
    └── My Profile

which follows the patient modules in your original specification.

Doctor Dashboard Placeholder

14

  • Create src/pages/doctor/DoctorDashboard.jsx
function DoctorDashboard() {

    return (
        <div className="container py-5">
            <h2> Doctor Dashboard </h2>

            <p className="text-secondary">
                View appointments and manage
                patient consultations.
            </p>
        </div>
    );
}

export default DoctorDashboard;
  • This will eventually show the doctor's upcoming appointments and prescription workflow required by the project.

Unauthorized Page

15

  • Create: src/pages/common/Unauthorized.jsx
import { Link } from "react-router";

function Unauthorized() {

    return (
        <div className="container py-5 text-center">

            <h1 className="display-5">
                403
            </h1>

            <h3>
                Access Denied
            </h3>

            <p className="text-secondary">
                You do not have permission to access this page.
          </p>
            <Link to="/" className="btn btn-primary" >
                Go Home
            </Link>

        </div>
    );
}

export default Unauthorized;
  • Later ProtectedRoute will redirect users here when they have the wrong role.

Not Found Page

16

  • Create : src/pages/common/NotFound.jsx
import { Link } from "react-router";

function NotFound() {

    return (
        <div className="container py-5 text-center">
            <h1 className="display-5">
                404
            </h1>

            <h3>
                Page Not Found
            </h3>

            <p className="text-secondary">
                The page you are looking for
                does not exist.
            </p>

            <Link to="/" className="btn btn-primary">
                Go Home
            </Link>

        </div>
    );
}

export default NotFound;

Create Router

17

  • Create:src/routes/router.jsx
import { createBrowserRouter } from "react-router";
import Home from "../pages/common/Home";
import Login from "../pages/auth/Login";
import Register from "../pages/auth/Register";
import PatientDashboard from "../pages/patient/PatientDashboard";
import DoctorDashboard from "../pages/doctor/DoctorDashboard";
import Unauthorized from "../pages/common/Unauthorized";
import NotFound from "../pages/common/NotFound";

const router = createBrowserRouter([

    {
        path: "/",
        element: <Home />
    },

    {
        path: "/login",
        element: <Login />
    },

    {
        path: "/register",
        element: <Register />
    },
    {
        path: "/patient/dashboard",
        element: <PatientDashboard />
    },

    {
        path: "/doctor/dashboard",
        element: <DoctorDashboard />
    },

    {
        path: "/unauthorized",
        element: <Unauthorized />
    },

    {
        path: "*",
        element: <NotFound />
    }
]);
export default router;
  • This is exactly why we chose: createBrowserRouter
  • Instead of scattering route definitions throughout App.jsx. React Router describes the objects passed to createBrowserRouter as route objects

Start Application

18

  • Run
npm run dev
  • Open: http://localhost:5173
  • You should see the Medicare home screen.

Test Every Route

19

  • Manually test: http://localhost:5173/
Medicare Healthcare
  • Test: http://localhost:5173/login
Login
  • Test: http://localhost:5173/register
Create Account
  • Test: http://localhost:5173/doctor/dashboard
Doctor Dashboard
  • Test: http://localhost:5173/patient/dashboard
Patient Dashboard
  • Test: http://localhost:5173/abc
404
Page Not Found

We are done with this lab. The latest source code has been uploaded to GitHub. You can access the latest commit using the link below: 

 

Great job!

You have successfully set up the Medicare React frontend using Vite, Bootstrap, Axios, and React Router.

Checkpoint

   Git Push

git push origin branchName

Next-Lab Preparation

Module:

1) React Basics & Backend Integration (Spring Boot)​

SpringBoot Lab - 14

By Content ITV

SpringBoot Lab - 14

  • 22