Logoblog.tiara
  • Home
  • Posts

© 2025. Tiara S. Dewi. All rights reserved.

Content Request Dashboard with Next.js

Content Request Dashboard with Next.js

November 8th, 2025

By trsrdw

Nowadays, maintaining dynamic website content across multiple pages usually requires coordination between content editors and administrators. Rather than making constant requests via chat or email, I wanted to build a structured system that lets editors submit content change requests and lets admins manage and approve those changes.

So I built a Content Request Dashboard with the following features:

  • ✏️ Editors can submit content update requests per page and section
  • 🔐 Authentication system with role-based access (EDITOR and ADMIN)
  • 🔄 Unsaved change detection before navigating away
  • 📋 Request overview with filterable statuses (Admin & Editor view)
  • 🛠️ Admin-only request detail view with ability to update status
  • 🗃️ MySQL database + raw queries (no ORM)
  • 🌟 Built in Next.js App Router with NextAuth

Let me walk you through the process.

The Tech Stack

Before writing any code, I settled on these technologies:

  • Next.js (Frontend + Backend)
  • NextAuth (Authentication)
  • MySQL (Storing users and requests)
  • SCSS modules (Component-based styling)

Rather than using Prisma or another ORM, I chose raw MySQL queries with mysql2/promise—cleaner and easier for a small schema.

Designing the Database

This app only needs two tables:

CREATE TABLE users (
id VARCHAR(64) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
role ENUM('ADMIN', 'EDITOR') NOT NULL DEFAULT 'EDITOR',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE requests (
id VARCHAR(24) PRIMARY KEY,
form_key VARCHAR(64) NOT NULL,
section_key VARCHAR(64) NOT NULL,
title VARCHAR(255) NOT NULL,
fields JSON NOT NULL,
payload JSON NOT NULL,
status ENUM('REQUESTED', 'IN_PROGRESS', 'DONE') NOT NULL DEFAULT 'REQUESTED',
requester_email VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

The UI Structure

The Dashboard UI has two main areas:

1. Sidebar – Navigation

  • Overview
  • Form Pages (Home, About, Program, etc.)
  • Admin (only if logged in as Admin)

2. Main content – Either:

  • A request form (editor requests changes by section)
  • A request list or detail view (admin reviews and updates status)
Screenshot 2025-11-08 at 19-42-47 Content Request - Greeneration Foundation.png

Submitting Requests with Section-Based Forms

Each page (e.g. "About") is broken into sections, and editors can submit updates per section. If they don't fill a section, no request is created for it.

Screenshot 2025-11-08 at 19-41-54 Content Request - Greeneration Foundation.png
Screenshot 2025-11-08 at 19-42-33 Content Request - Greeneration Foundation.png

Handling Unsaved Changes

One UX gem of this project is the unsaved change detector. If the user tries to switch sections without saving, a modal (or simple confirm) appears:

"You have unsaved changes. Are you sure you want to leave?"

This is implemented with a simple React Context:

const { isDirty, setDirty } = useUnsavedChanges();

All form changes trigger setDirty(true).

Admin Request Management

Screenshot 2025-11-08 at 19-42-47 Content Request - Greeneration Foundation.png

Admins have access to a dedicated panel under /dashboard/admin, which allows them to:

  • ✅ View all content requests logged by editors
  • 🔄 Filter by status (REQUESTED, IN_PROGRESS, or DONE)
  • 🔍 Open a detailed view of each request (including fields and payload submitted)
  • 🔁 Update status of a request (mark as IN_PROGRESS or DONE)

These features make it easy for admins to prioritize updates, collaborate with editors, and track progress.

🚧 Future Enhancements (In Development)

I'm building even more tools to help admins manage the system efficiently:

👥 User Management

View and manage all registered users (add, delete, or update roles such as EDITOR or ADMIN).

🧹 Clean History

Delete DONE requests within a selected date range (e.g., older than X days). Helps keep the system tidy.

Wrapping Up

This project has evolved into a practical and scalable content request tool, built with clarity and collaboration in mind. It empowers editors with a simple form-based UI to request website updates and gives admins a centralized dashboard to track and manage those requests.

From handling user authentication with role-based access, to translating dynamic form submissions into structured database entries, this project demonstrates a real-world full-stack workflow using Next.js, MySQL, and NextAuth.

While the core functionality is in place, there's still more to come:

  • 🔜 Admin utilities like request pruning and user management
  • 💡 UI improvements for better UX and accessibility

Whether you're looking to build a project like this for a client or learning how to structure scalable dashboards with serverless APIs, I hope this walkthrough inspires your next build.

Categories:

ProjectsTech

Recent Posts

Mini Project: QRIS Payments for GB Toolkit

Mini Project: QRIS Payments for GB Toolkit

How I implemented QRIS payments, Midtrans integration, and automated file delive …

Read More
Bibi Turns One 🎂

Bibi Turns One 🎂

When I moved into my new place in Bandung, I didn’t expect to gain a companion — …

Read More