A Modern, High-Performance Content Publishing & Community Reading Platform built with React 19, TypeScript, Vite, and Tailwind CSS v4.
- Overview
- Key Features
- System Architecture
- Technology Stack
- Project Directory Structure
- Routing & Access Control
- Authentication & Token Rotation Lifecycle
- Getting Started
- API Integration
- Design & User Experience
- Contributing
- License
RAD Article Web is the frontend client for the RAD Article Publishing Ecosystem, crafted for speed, user engagement, and clean typography. The platform empowers developers, tech writers, and learners to publish rich articles with cover images, categorize posts with dynamic tags, browse through paginated feeds, and authenticate securely using JWT session management.
Built on the latest cutting-edge web stack (React 19, Vite 8, and Tailwind CSS v4), it features an ultra-responsive UI, instant hot-module replacement (HMR), seamless token rotation interceptors, and strict TypeScript typing.
-
🔐 Dual-Token JWT Authentication:
- Secure login and registration with validation feedback.
- Persistent authentication state via
AuthContextwith automatic user profile hydration. - Transparent silent token renewal using Axios interceptors upon receiving HTTP 401.
-
🛡️ Role-Based Route Protection:
- Centralized
<RequireAuth>route guard preventing unauthorized access. - Role-specific access control supporting
ADMIN,WRITER, andUSERprivileges.
- Centralized
-
📰 Interactive Community Feed:
- Paginated article exploration (
getAllArticles(page, limit)). - Real-time client-side search across article titles and body content.
- Dynamic filter pills generated from active tags across the article database.
- Paginated article exploration (
-
✍️ Dual Publishing Workflows:
- Full Creation Studio (
/create-article): Comprehensive editor with multi-tag support and image preview. - ⚡ Quick Post on Home: Instant accordion drawer on the home feed for rapid publishing without page reloads.
- Full Creation Studio (
-
🖼️ Media Handling with Live Preview:
- Drag-and-drop or file upload for article banner images.
- Instant client-side
URL.createObjectURLpreview with quick removal option. - Automatic
multipart/form-datapayload formatting for backend cloud storage upload.
-
🎨 Modern Glassmorphic Design System:
- Sleek visual polish with subtle gradients, card hover elevation, and responsive flex/grid layouts.
- Dynamic author avatar generation from user initials.
- Mobile-first responsive navigation bar.
flowchart TD
subgraph Browser["Client Browser (React 19 SPA)"]
UI["UI Layer<br/>(Pages & Components)"]
Router["React Router v7<br/>(Route Guards & RBAC)"]
Context["Auth Context<br/>(State: user, loading)"]
Axios["Axios HTTP Client<br/>(BaseURL + Interceptors)"]
end
subgraph Interceptor["Axios Interceptor Pipeline"]
ReqInt["Request Interceptor<br/>Injects Bearer Token"]
ResInt["Response Interceptor<br/>Detects 401 Unauthorized"]
Refresh["Silent Refresh Flow<br/>Calls /auth/refresh & retries request"]
end
subgraph Backend["RAD Article Backend API"]
API["Express 5 REST API Gateway"]
AuthService["Auth Service (JWT)"]
ArticleService["Article Service"]
Supabase["Supabase Storage (Images)"]
Mongo["MongoDB Atlas"]
end
UI --> Router
Router --> Context
UI --> Axios
Axios --> ReqInt
ReqInt --> API
API --> ResInt
ResInt -- "401 Expired" --> Refresh
Refresh --> AuthService
Refresh -- "Success" --> ReqInt
API --> AuthService
API --> ArticleService
ArticleService --> Supabase
ArticleService --> Mongo
| Category | Technology | Version | Purpose |
|---|---|---|---|
| Core Framework | React | ^19.2.8 |
Next-generation React with optimized rendering |
| Language | TypeScript | ~6.0.2 |
End-to-end static typing and interface contracts |
| Build Tool | Vite | ^8.3.0 |
Ultra-fast build tool and dev server with instant HMR |
| Styling | Tailwind CSS | ^4.3.3 |
High-performance CSS engine with @tailwindcss/vite |
| Routing | React Router | ^7.18.4 |
Declarative client-side routing and protected routes |
| HTTP Client | Axios | ^1.20.0 |
Promise-based HTTP client with request/response interceptors |
| Code Quality | ESLint | ^10.10.0 |
Linting & code consistency with React hooks rules |
rad-article-web/
├── public/ # Static public assets
│ └── favicon.svg # Application favicon
├── src/
│ ├── assets/ # Static media and images
│ ├── context/
│ │ └── AuthContext.tsx # Global auth state provider & session restoration
│ ├── hooks/
│ │ └── useAuth.ts # Custom hook consuming AuthContext
│ ├── pages/
│ │ ├── CreateArticle.tsx # Full article creation page with image upload
│ │ ├── Home.tsx # Main dashboard: feed, search, tags & quick post
│ │ ├── Login.tsx # User authentication login view
│ │ └── Register.tsx # New user registration view
│ ├── router/
│ │ └── index.tsx # Route definitions & <RequireAuth> route guard
│ ├── service/
│ │ ├── api.ts # Axios instance with auth interceptor & refresh logic
│ │ ├── article.ts # Article service API calls (fetch all, create)
│ │ └── auth.ts # Auth service API calls (login, register, me, refresh)
│ ├── App.css # Custom UI styles, glassmorphism & responsive rules
│ ├── App.tsx # Root component wrapping AuthProvider and Router
│ ├── index.css # Global CSS and Tailwind CSS v4 entry
│ ├── main.tsx # React DOM root bootstrapping
│ └── vite-env.d.ts # Vite client TypeScript definitions
├── eslint.config.js # ESLint configuration
├── index.html # Single Page Application HTML template
├── package.json # Dependencies and execution scripts
├── tsconfig.app.json # App TypeScript compiler options
├── tsconfig.json # Root TypeScript configuration
├── tsconfig.node.json # Node/Vite TypeScript compiler options
└── vite.config.ts # Vite configuration with React & Tailwind plugins
All routes are declared in src/router/index.tsx using React Router v7. Protected routes are wrapped in <RequireAuth> to ensure that unauthenticated users are seamlessly redirected to the /login page.
| Route Path | View Component | Access Level | Description |
|---|---|---|---|
/login |
Login.tsx |
Public | User login screen with credentials validation |
/register |
Register.tsx |
Public | User account registration |
/ |
Home.tsx |
Authenticated | Main articles feed, search, filters & quick post |
/articles |
Home.tsx |
Authenticated | Feed alias |
/create-article |
CreateArticle.tsx |
Authenticated | Dedicated article authoring suite |
/home |
Home.tsx |
Role-Protected (ADMIN) |
Admin overview portal |
The application features seamless session handling with dual tokens:
sequenceDiagram
autonumber
actor User as User
participant App as React App
participant Storage as LocalStorage
participant Axios as Axios Interceptor
participant Backend as Backend API
User->>App: Submits Login (email, password)
App->>Backend: POST /api/v1/auth/login
Backend-->>App: { access_token, refresh_token }
App->>Storage: Store ACCESS_TOKEN & REFRESH_TOKEN
App-->>User: Redirect to Feed (/)
Note over App,Backend: Subsequent Authenticated Requests
App->>Axios: Fetch Articles /api/v1/article/
Axios->>Axios: Attach "Authorization: Bearer <ACCESS_TOKEN>"
Axios->>Backend: GET /api/v1/article/
alt Token is valid
Backend-->>Axios: 200 OK (Articles Data)
Axios-->>App: Render Feed
else Token Expired (401 Unauthorized)
Backend-->>Axios: 401 Unauthorized
Axios->>Backend: POST /api/v1/auth/refresh (with REFRESH_TOKEN)
alt Refresh successful
Backend-->>Axios: { accessToken: new_access_token }
Axios->>Storage: Update ACCESS_TOKEN
Axios->>Backend: Retry original request with new token
Backend-->>Axios: 200 OK (Articles Data)
Axios-->>App: Render Feed
else Refresh token invalid / expired
Backend-->>Axios: 403 Forbidden
Axios->>Storage: Purge ACCESS_TOKEN & REFRESH_TOKEN
Axios-->>User: Redirect to /login
end
end
Ensure you have the following installed on your machine:
- Node.js:
v18.0.0or higher (Node.js 20+ recommended) - npm:
v9.0.0or higher (orpnpm/yarn) - Git
-
Clone the repository:
git clone https://github.com/chathunga2007/ITS2020-RAD-Article-Frontend.git cd ITS2020-RAD-Article-Frontend -
Install dependencies:
npm install
The application points by default to the deployed Vercel production backend:
- Production Backend:
https://rad-article-be.vercel.app/api/v1/ - Local Development Backend:
http://localhost:3000/api/v1/
To switch between local and production backends, configure src/service/api.ts:
const api = axios.create({
// baseURL: "http://localhost:3000/api/v1/" // Local backend
baseURL: "https://rad-article-be.vercel.app/api/v1/" // Production backend
})Run the Vite development server with Hot Module Replacement (HMR):
npm run devThe application will be accessible at:
http://localhost:5173
Compile TypeScript and generate the optimized production bundle:
npm run buildPreview the production build locally:
npm run previewRun code quality linting:
npm run lintThe frontend connects with the following endpoints exposed by the RAD Article Backend:
| Method | Endpoint | Description | Headers |
|---|---|---|---|
POST |
/auth/register |
Register new user account | Public |
POST |
/auth/login |
Login and receive access/refresh tokens | Public |
POST |
/auth/refresh |
Request refreshed access token | Public |
GET |
/auth/me |
Fetch authenticated user profile | Bearer <token> |
| Method | Endpoint | Description | Content-Type |
|---|---|---|---|
GET |
/article/?page=:page&limit=:limit |
Fetch paginated article feed | application/json |
POST |
/article/create |
Publish new article with image attachment | multipart/form-data |
- Glassmorphism & Gradients: Subtle background blur and translucent surfaces create depth and visual hierarchy.
- Micro-Animations: Hover state elevation, smooth scale transformations on cards, and animated loading spinners.
- Immediate Feedback: Instant visual image upload preview and proactive client-side validation.
- Empty & Loading States: Clean fallback screens during data hydration and network fetches.
Contributions are welcome! Please follow these steps:
- Fork the Repository
- Create a Feature Branch:
git checkout -b feature/AmazingFeature
- Commit your Changes:
git commit -m "Add AmazingFeature" - Push to the Branch:
git push origin feature/AmazingFeature
- Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for more details.
Developed with ❤️ for the ITS2020 RAD Module