v1.0.0

Power of One News Admin Panel

A comprehensive content management system for managing news articles, categories, shorts, magazines, users, notifications, and site configuration.

Next.js 15 React 19 TypeScript OTP Authentication 9 Languages
๐Ÿ 

Overview

Power of One News Admin Panel is a web-based CMS for the Power of One News platform. Administrators manage news articles, categories, short-form stories, magazines, advertisements, user-generated content, push notifications, and site configuration from a single dashboard.

The application is a Next.js 15 frontend that communicates with the backend API. Media assets are stored on AWS S3.

PropertyValue
Project namepowerofone-news-admin
FrameworkNext.js 15 (App Router)
LanguageTypeScript
Node.js>= 18.18.0
Default APIhttps://backend.powerofonenews.com/api
Production port9999 (PM2)
๐Ÿš€

Getting Started

Prerequisites

  • Node.js >= 18.18.0
  • npm (or yarn / pnpm)
  • Access to the Power of One News backend API
  • Google Cloud Translation API key (for translation features)

Installation

bash
# Clone the repository
git clone <repository-url>
cd POON_Admin

# Install dependencies
npm install

# Create .env.local with required keys (see Environment Variables)

# Start development server
npm run dev

Open http://localhost:3000 and log in with an authorized admin mobile number.

Available Scripts

CommandDescription
npm run devStart development server (port 3000)
npm run buildProduction build
npm run startStart production server
npm run lintRun ESLint
โš™๏ธ

Environment Variables

Create a .env.local file in the project root:

.env.local
# Backend API base URL (optional โ€” defaults to production API)
NEXT_PUBLIC_API_BASE_URL=https://backend.powerofonenews.com/api

# AES encryption key for auth payloads (optional โ€” has built-in fallback)
NEXT_PUBLIC_ENTK_VALUE=your-encryption-key

# Google Cloud Translation API key (required for auto-translation)
NEXT_PUBLIC_GOOGLE_TRANSLATE_API_KEY=your-google-translate-api-key

# LibreTranslate API URL (optional fallback for translation)
NEXT_PUBLIC_LIBRETRANSLATE_API_URL=https://libretranslate.de/translate
โš ๏ธ Security note: Never commit .env.local or expose API keys in version control.
โœจ

Features

Core Content Management

๐Ÿ“Š

Dashboard

Overview with article stats, recent articles, category breakdown, and quick actions.

๐Ÿ“ฐ

Posts

Full article lifecycle โ€” list, filter, create, edit, delete including translation groups.

๐Ÿท๏ธ

Categories

Hierarchical categories with multi-language translations and image upload.

๐Ÿ“‹

News Items

Editorial tags: features, trending, popular, latest, editor-pick, breaking.

๐ŸŽฌ

Shorts

Short-form story content โ€” create, edit, and publish.

๐Ÿ“š

Magazine

Digital magazine uploads (PDF/image) with metadata.

๐Ÿ–ผ๏ธ

Gallery

Image and video gallery with filtering and thumbnails.

โœ๏ธ

Blog Posts

Blog content management (routes exist; nav item currently commented out).

Engagement & Users

ModuleDescription
CommentsModerate comments on news, blog, and story content
UsersView registered app users, profiles, preferences, and block status
ContactManage contact form submissions โ€” view, mark as read, delete
NotificationsSend push notifications (broadcast or to selected users)

Platform Capabilities

OTP-based login AES encryption Bearer token auth Auto translation (8 languages) Rich text editor Light / dark theme Responsive drawer Multi-language stats
๐Ÿ› ๏ธ

Technology Stack

Frontend

TechnologyPurpose
Next.js 15React framework with App Router
React 19UI library
TypeScriptType-safe development
Bootstrap 5Base styling
AxiosHTTP client with interceptors
React Hook Form + YupForm validation
Crypto-JSAES encryption for API payloads
Custom RichTextEditorContent editor with media upload

External Services

ServicePurpose
Power of One News Backend APIAll CRUD operations
AWS S3Image, video, and file storage
Google Cloud Translation APIMulti-language article translation
PM2Process manager in production
๐Ÿ—๏ธ

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Admin Browser (Client)                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚ Login / OTP โ”‚  โ”‚  Dashboard   โ”‚  โ”‚  Module Components  โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                          โ–ผ                                   โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                       โ”‚
โ”‚              โ”‚   apiService (api.ts) โ”‚                       โ”‚
โ”‚              โ”‚   axiosClient         โ”‚                       โ”‚
โ”‚              โ”‚   AES Encryption      โ”‚                       โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚ HTTPS (Bearer Token)
                           โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚  Backend API           โ”‚
              โ”‚  backend.powerofone-   โ”‚
              โ”‚  news.com/api          โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                          โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚  AWS S3 (media)        โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Request Flow

  1. Admin enters mobile number โ†’ OTP sent via encrypted payload to /admin/auth/otp/send
  2. Admin verifies OTP โ†’ JWT token returned from /admin/auth/otp/verify
  3. Token stored in localStorage as authToken
  4. All subsequent requests include Authorization: Bearer <token> via Axios interceptor
  5. On 401 response, session is cleared and user is redirected to login

Routing Model

RouteDescription
/Login page (OTP flow)
/dashboardMain dashboard (tab switching via ?tab=)
/dashboard/articles/createCreate article
/dashboard/articles/edit/[id]Edit article
/dashboard/news-items/createCreate news item tag
/dashboard/shorts/createCreate short story
/dashboard/gallery/createCreate gallery entry
/dashboard/blog-posts/createCreate blog post
๐Ÿ“

Project Structure

directory tree
POON_Admin/
โ”œโ”€โ”€ .github/workflows/main.yml    # CI/CD โ€” deploy on push to main
โ”œโ”€โ”€ docs/                         # HTML documentation (this site)
โ”œโ”€โ”€ public/assets/                # Static CSS, fonts, icons
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ app/
โ”‚   โ”‚   โ”œโ”€โ”€ layout.tsx            # Root layout
โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx              # Login / OTP entry
โ”‚   โ”‚   โ””โ”€โ”€ dashboard/
โ”‚   โ”‚       โ”œโ”€โ”€ page.tsx          # Main dashboard shell
โ”‚   โ”‚       โ”œโ”€โ”€ articles/         # Article create & edit
โ”‚   โ”‚       โ”œโ”€โ”€ news-items/       # News item create & edit
โ”‚   โ”‚       โ”œโ”€โ”€ shorts/           # Short story create & edit
โ”‚   โ”‚       โ”œโ”€โ”€ gallery/          # Gallery create & edit
โ”‚   โ”‚       โ””โ”€โ”€ blog-posts/       # Blog create & edit
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ auth/                 # LoginForm, OtpVerification
โ”‚   โ”‚   โ””โ”€โ”€ dashboard/            # All management modules
โ”‚   โ”œโ”€โ”€ layouts/                  # Wrapper.tsx
โ”‚   โ”œโ”€โ”€ modals/                   # ImagePopup, VideoPopup
โ”‚   โ”œโ”€โ”€ styles/                   # index.css, auth.css
โ”‚   โ””โ”€โ”€ utils/
โ”‚       โ”œโ”€โ”€ api.ts                # API service & endpoints
โ”‚       โ”œโ”€โ”€ apiConfig.ts          # Base URL & token helper
โ”‚       โ”œโ”€โ”€ axiosClient.ts        # Axios instance & interceptors
โ”‚       โ”œโ”€โ”€ translation.ts        # Multi-language translation
โ”‚       โ””โ”€โ”€ utils.ts              # Helpers (slug generation)
โ”œโ”€โ”€ next.config.js
โ”œโ”€โ”€ package.json
โ””โ”€โ”€ .env.local                    # Environment variables (not committed)
๐Ÿ”

Authentication

Login Flow

  1. Mobile Number โ€” Admin enters a 10-digit Indian mobile number
  2. OTP Send โ€” apiService.sendOtp(mobile) encrypts { mobile } with AES and posts to /admin/auth/otp/send
  3. OTP Verify โ€” Admin enters OTP; encrypted payload posted to /admin/auth/otp/verify
  4. Session โ€” On success, authToken, isAuthenticated, and mobile are stored in localStorage

Session Protection

  • Dashboard checks isAuthenticated on mount; redirects to / if missing
  • Axios interceptor attaches Bearer token to every request
  • 401 responses clear session and surface "Session expired" errors
  • Logout clears all auth keys and redirects to login
Sensitive auth payloads use AES encryption (Crypto-JS). The key is configured via NEXT_PUBLIC_ENTK_VALUE or falls back to the built-in default in api.ts.
๐ŸŒ

Multi-Language Support

Supported Languages

CodeLanguage
enEnglish
hiHindi
mrMarathi
teTelugu
taTamil
knKannada
guGujarati
bnBengali
paPunjabi

Article Translation

When creating or editing articles, admins can enable automatic translation via translation.ts:

  • Translates title, subtitle, description, and content
  • Uses Google Cloud Translation API when API key is set
  • Fallback providers: LibreTranslate, MyMemory
  • Groups translations via translationGroupId on the backend
โ˜๏ธ

Deployment

CI/CD (GitHub Actions)

Pushing to the main branch triggers automatic deployment:

  1. Code synced via rsync to server at 52.221.144.52
  2. Deploy path: /var/www/html/powerofone-news-admin/
  3. npm install and npm run build run on the server
  4. PM2 starts the app as powerkaadmin on port 9999

Manual Deployment

bash
npm install
npm run build
npm run start -- -p 9999

# Or with PM2:
pm2 start npm --name "powerkaadmin" -- run start -- -p 9999
๐Ÿ”Œ

API Integration

Base URL: NEXT_PUBLIC_API_BASE_URL or https://backend.powerofonenews.com/api

Client: src/utils/axiosClient.ts ยท Service: src/utils/api.ts

CategoryEndpoints
AuthPOST /admin/auth/otp/send, POST /admin/auth/otp/verify
DashboardGET /admin/dashboard
CategoriesPOST /admin/category/create|update|delete, GET /admin/category/list
NewsPOST /admin/news/create|update|delete, GET /admin/news/list
News ItemsPOST /admin/newsItems/create|update, GET /admin/newsItems/list
StoriesPOST /admin/story/create|update|delete, GET /admin/story/list
GalleryPOST /admin/gallery/create|update, GET /admin/gallery/list
MagazinePOST /admin/magazine/create|update|delete, GET /admin/magazine/list
AdvertisementsPOST /admin/advertise/create|update|delete, GET /admin/advertise/list
CommentsGET /admin/comment/list|list-by-type, update, delete
ContactGET /admin/contact/list, mark-as-read, update, delete
UsersGET /admin/user-list
NotificationsPOST /admin/notification/send|broadcast, GET /admin/notification/users-list
UploadPOST /admin/upload-image, POST /admin/upload-contentImage
SitemapPOST /admin/generate-sitemap, GET /admin/sitemap

All endpoint constants are defined in API_ENDPOINTS inside src/utils/api.ts.

๐Ÿ“ฆ

Module Reference

๐Ÿ“Š

Dashboard

Article stats, language-filtered counts, recent articles table with status filters, category overview, and quick actions.

๐Ÿ“ฐ

Posts (Articles)

Paginated list, category filter, bulk delete, rich text editor, image upload, news item tags, and auto-translation.

๐Ÿท๏ธ

Categories

Parent-child hierarchy, 9-language translations, image upload, display order, enable/disable.

๐Ÿ“‹

News Items

Editorial tags: features, trending, popular, latest, editor-pick, breaking. Toggle active status.

๐ŸŽฌ

Shorts

Short-form stories with title, content, author, category, image, and publish date.

๐Ÿ“š

Magazine

Upload PDF/image magazines with title, author, description, publish date, and active status.

๐Ÿ–ผ๏ธ

Gallery

Image and video entries with thumbnails, search/filter, and active/inactive status.

๐Ÿ’ฌ

Comments

Filter by news/blog/story. Approve, deactivate, or delete. Paginated list with article titles.

๐Ÿ‘ฅ

Users

View profiles, preferences, liked/bookmarked content. Block/unblock users.

๐Ÿ“ง

Contact

List submissions, view messages, mark as read, delete.

๐Ÿ””

Notifications

Broadcast or targeted push notifications with title, body, image, and linked article.

๐Ÿ“ข

Advertisements

Banner ads with image upload, link URL, display order, and active status.

โš™๏ธ

Settings

Social media links, sitemap generation/download, general and security sections.

๐ŸŽจ

UI & UX

FeatureDetails
NavigationCollapsible side drawer, active tab highlighting, mobile overlay, desktop persistent sidebar
ThemeLight/dark mode via tg-theme attribute, persisted in localStorage
Toastsreact-toastify โ€” success, error, info, warning (top-center)
FormsReact Hook Form + Yup validation, loading states on submit
Rich Text EditorBold, italic, headings, lists, links, inline image/video upload to S3, media resize panel
๐Ÿ–ผ๏ธ

Media Storage

Uploaded images and files are stored on AWS S3. The API returns relative paths; the frontend constructs full URLs:

URL pattern
https://stagingpowerofnews.s3.ap-southeast-1.amazonaws.com/<path>
  • POST /admin/upload-image โ€” Featured images, category images
  • POST /admin/upload-contentImage โ€” Inline content images in the rich text editor
๐Ÿ”ง

Troubleshooting

IssueSolution
"Session expired" on API callsLog out and log in again; check that authToken is valid
Translation failsVerify NEXT_PUBLIC_GOOGLE_TRANSLATE_API_KEY is set and billing is enabled
Images not loadingConfirm S3 path is correct and the bucket/object is publicly accessible
Build fails on lintESLint errors are ignored during builds (eslint.ignoreDuringBuilds: true)
OTP not receivedConfirm mobile number is registered as admin on the backend