About PoemSite

PoemSite is a modern, full-stack poetry platform for reading, sharing, and discussing poems — with an elegant user interface, robust admin dashboard, and secure backend.

Table of Contents

Tech Stack

  • Frontend: Next.js 15, React, Tailwind CSS, HTML5, CSS3
  • Backend: Firebase Firestore, Firebase Auth, Node.js Express (mail server)
  • Admin Panel: Next.js (separate app), Tailwind CSS
  • Mail Server: Node.js, Express, Nodemailer, Firebase Admin SDK
  • Deployment: Vercel (main), Firebase Hosting (admin), Render (mail server)
  • Other: GitHub Actions (CI/CD), ESLint/Prettier, dotenv
  • APIs: Custom API for mailing, Firebase Functions (optional)
  • Open Source: GitHub

Pages & Navigation

Main User Site

  • Home: Highlights, featured poems, CTAs.
  • /poem: Browse/search all poems, filters, pagination.
  • /poem/[slug]: Poem detail with comments, replies, admin replies, sharing.
  • /about: About the admin and main poet of Poemsite community.
  • /login, /register: Auth pages.
  • /profile: User info.

Admin Dashboard

  • Dashboard Home: Stats, activity, analytics.
  • Poems: Add, edit, delete, approve poems.
  • Users: List, search, manage roles, ban/delete users.
  • Comments: Moderate, delete, admin reply.
  • Mailing List: Export, send announcements.
  • Poem Requests: View/respond to user requests.
Visit Admin Dashboard ↗

Main Features & UX

  • Read, search, and share poems with beautiful, responsive UI
  • Nested comments & replies, admin replies highlighted
  • Animated "Show Replies", "Share", and interactive buttons
  • Role-based actions, only admins can manage poems/users
  • Mailing list join, email notifications (custom API)
  • Poem request & approval workflow
  • Admin dashboard for moderation, analytics, management
  • Live statistics, user tracking, audit logs (admin)
  • Fast, secure authentication (Firebase Auth)
  • All data is real-time via Firestore
  • Animated page transitions and smooth modals
  • Public, mobile-friendly, accessible

Key Code Explanations

Fetching a Poem

const poemQuery = query(
  collection(db, 'poems'),
  where('slug', '==', decodedSlug)
);
const snapshot = await getDocs(poemQuery);
if (snapshot.empty) return notFound();
const poemData = snapshot.docs[0].data();
setPoem(poemData);

Posting a Comment

await addDoc(collection(db, 'comments'), {
  poemSlug: decodedSlug,
  content: newComment.trim(),
  author: authorName,
  timestamp: Timestamp.now(),
  userId: user.uid,
  parentId: null
});

On-demand Replies

const repliesQuery = query(
  collection(db, 'comments'),
  where('poemSlug', '==', decodedSlug),
  where('parentId', '==', parentId),
  orderBy('timestamp', 'asc')
);
const repliesSnapshot = await getDocs(repliesQuery);
const replyData = repliesSnapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() }));

Role-based Actions Example

{user?.uid === comment.userId && (
  <button onClick={() => handleDeleteComment(comment.id)}>
    Delete
  </button>
)}

Security & Authentication

Strict Firestore rules and authentication for both user and admin flows:

match /comments/{commentId} {
  allow read: if true;
  allow create: if request.auth != null;
  allow update: if request.auth.uid == resource.data.userId
    && !(request.resource.data.keys().hasAny(['adminReply']));
  allow update: if request.auth != null
    && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin'
    && request.resource.data.diff(resource.data).changedKeys().hasOnly(['adminReply']);
  allow delete: if request.auth.uid == resource.data.userId;
  allow delete: if request.auth != null
    && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
  • All reads public for poems/comments; writes are restricted.
  • Only authenticated users can comment/reply.
  • Only comment owners/admins can delete/edit.
  • Only admins can manage poems and users.
  • Roles are securely managed in users collection.

Collections & Data Models

poems

  • title: String
  • author: String
  • content: String
  • slug: String (unique, URL-friendly)
  • datePosted: Timestamp

comments

  • poemSlug: String
  • content: String
  • author: String
  • timestamp: Timestamp
  • userId: String
  • parentId: String/null
  • adminReply: String (admin-only, optional)

users

  • uid: String
  • name: String
  • role: "user" | "admin"
  • email: String

poemRequests

  • requestedBy: uid
  • poemTitle: String
  • reason: String
  • timestamp: Timestamp

mailingList

  • uid: String
  • email: String
  • subscribedOn: Timestamp

Admin Dashboard (separate app)

The admin dashboard is a dedicated Next.js app built for moderators and admins, deployed at admin.poems.toshankanwar.website

  • Poem CRUD: Add, approve, edit, delete, feature poems
  • User Management: List, search, ban, change roles
  • Comment Moderation: Delete, reply as admin, audit logs
  • Mailing List management: export, emails, stats
  • Poem Requests: View/respond, one-click publish
  • Analytics dashboard: charts, stats, live activity
  • Authentication: admin role required (checked via Firestore + UI)
  • Seamless connection to main Firestore DB
  • Responsive, animated, professional UI (Tailwind, modals)
  • Open source: GitHub Repo

Mail Server & API

A dedicated backend service (Node.js + Express + Nodemailer) powers:

  • Sending welcome emails, admin approval/announcement notifications
  • Mailing list subscription, opt-in/out, bulk notifications
  • Fully integrated with Firestore and Firebase Admin SDK
  • Endpoints: /api/send-welcome-email, /api/send-aproval-email, /api/send-poem-announcement, /api/unsubscribe
  • Hosted at mail-server-poetry-website.onrender.com
  • Open source: Mail Server GitHub
app.post('/api/send-welcome-email', ... );
app.post('/api/send-aproval-email', ... );
app.post('/api/send-poem-announcement', ... );
app.post('/api/unsubscribe', ... );

Deployment & Hosting

  • Main Site: Deployed on Vercel with auto CI/CD from GitHub.
  • Admin Dashboard: Hosted as a separate app at admin.poems.toshankanwar.website (Firebase Hosting or Vercel).
  • Mail Server: Hosted on Render for scalable mail API.
  • Firestore: Central data store, rules-enforced, real-time.
  • GitHub: All code open source. See main repo and admin repo.
All sensitive keys are securely stored in environment files. Never commit secrets to source!
© 2025 PoemSite Project — Built with Next.js, Firebase, Node.js, and 💜 by Toshan Kanwar.