UHall Form Handler
Stores interview form submissions from the React SPA and provides an admin page to view, delete, and download them as CSV.
by UHall Dev Team · github.com/maulei41/university_hall.dev · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/maulei41/university_hall.dev/archive/refs/heads/main.zipUniversity Hall HKU — Frontend Website
A production-grade, fully-responsive React + TypeScript website for University Hall, The University of Hong Kong. Built with Vite, Tailwind CSS, and Framer Motion.
Features
- 7 Complete Pages: Homepage, About, Facilities, Events, Contact, People, Apply
- Dark Academia Aesthetic: Heritage-inspired design with gold and emerald accents
- Fully Responsive: Mobile-first design with breakpoints for XS, SM, MD, LG, XL
- Elegant Animations: Framer Motion with
prefers-reduced-motionsupport - Accessibility: WCAG 2.1 AA compliant
- Performance Optimized: Code splitting, lazy-loaded images
- Contact Form Backend: WordPress plugin stores submissions with admin panel
Quick Start
Prerequisites
- Node.js 16+ and npm
Installation
git clone <repo-url>
cd universityhall.dev
npm install
npm run dev
The site opens at http://localhost:3000 with HMR enabled.
Build for Production
npm run build
npm run preview
Build output is in dist/.
Project Structure
src/
├── components/
│ ├── common/ # Base UI components (Button, Card, Badge, etc.)
│ ├── layout/ # Header, Footer, Layout wrappers
│ └── animations/ # Framer Motion animation components
├── pages/ # Page components
├── hooks/ # Custom hooks
├── utils/ # Utility functions
├── types/ # TypeScript type definitions
├── constants/ # Content and configuration
├── App.tsx # Main app with routing
├── main.tsx # Entry point
└── index.css # Global styles with Tailwind
vite.config.ts # Vite configuration
tailwind.config.js # Tailwind CSS configuration
uhall-form-handler.php # WordPress plugin — stores form submissions
uhall-react-app.php # WordPress mu-plugin — serves the React SPA
Deployment
WordPress (Self-hosted WordPress)
The project ships as two separate plugins:
| Plugin | Type | Purpose |
|---|---|---|
uhall-react-app.php |
mu-plugin (Must-Use) | Intercepts front-end requests, serves the React SPA build, and routes all non-WP paths to index.html for client-side routing |
uhall-form-handler.php |
Standard plugin | Registers a REST API endpoint for form submissions, stores data in a custom DB table, and provides an admin panel with CSV export |
Setup
-
Build the frontend:
$env:VITE_BUILD_TARGET="wordpress"; npm run build -
Deploy the built assets to your server at
wp-content/uhall-react-app/:wp-content/uhall-react-app/ ├── assets/ ├── index.html └── ... -
Deploy the mu-plugin — copy
uhall-react-app.phpto your server:wp-content/mu-plugins/uhall-react-app.phpCreate the
mu-pluginsfolder if it doesn't exist. WordPress auto-detects mu-plugins — no activation needed. -
Deploy the form handler plugin — create a folder and copy
uhall-form-handler.php:wp-content/plugins/uhall-form-handler/uhall-form-handler.php -
Activate the form handler — go to WordPress Admin → Plugins and activate UHall Form Handler.
The SPA is now live at your WordPress domain.
WordPress Admin
Once deployed, visit WordPress Admin → Interview Submissions to view, delete, or download form submissions as CSV.
Updating
# Rebuild frontend
npm run build
# Sync dist/ to server
rsync -avz dist/ user@host:/path/to/wp-content/uhall-react-app/
How It Works
uhall-react-app.php(mu-plugin) intercepts all front-end requests and serves the React SPA'sindex.htmlfor client-side routing. Static assets (js,css, images) are served directly from thewp-content/uhall-react-app/directory with correct MIME types and long-lived cache headers. WordPress admin (/wp-admin) and REST API (/wp-json/) requests pass through untouched.uhall-form-handler.php(standard plugin) exposes aPOST /wp-json/uhall/v1/submissionsendpoint. The React contact form posts to this endpoint; submissions are stored in a customwp_uhall_submissionstable. An admin menu page under Interview Submissions lets you view, batch-delete, and download submissions as CSV. Email notifications are sent touhall@connect.hku.hkon each submission.
Design System
Color Palette
- Background: #0B2018 (Deep Forest)
- Surface: #1A4231 (Rich Green)
- Gold: #C9A84C (Warm Accent)
- Gold Light: #E8C96E (Bright Accent)
- Emerald: #52B788 (Fresh Accent)
- Text Primary: #F5F0E8 (Cream)
- Text Muted: #C8C0B0 (Gray)
Typography
- Headings: Playfair Display
- Body: Cormorant Garamond
- Metadata: JetBrains Mono
Components
- Buttons: Primary (gold), Secondary (outline), Ghost (text)
- Cards: Base card with shadow and hover elevation
- Badges: Inline status indicators (gold, emerald, muted)
Pages Overview
Homepage (/)
Hero with parallax, statistics bar, feature cards, 6-milestone timeline, 6-facility gallery, testimonials carousel, events preview, CTA.
About (/about)
Heritage storytelling, 6-point timeline, 4-pillar philosophy, leadership grid, mission statement.
Facilities (/facilities)
Category tab filtering (Dining, Academic, Recreation, Accommodation, Community), detailed facility cards, gallery grid.
Events (/events)
Featured event banner, category filtering, upcoming events with RSVP, past events archive.
Contact (/contact)
Contact form with validation (posts to WordPress form handler REST API), office info, hours, social links, map placeholder.
People (/people)
Leadership grid, role filtering (Warden, Fellows, Staff), person cards with bio.
Apply (/apply)
4-step application process, multi-step form, 6-item FAQ accordion, requirements checklist.
Image Replacement Guide
All images use structured placeholders with data-image-id attributes:
imageId: 'hero_castle' // Hero background
imageId: 'dining_hall' // Dining facility
imageId: 'library' // Library facility
imageId: 'recreation' // Recreation facilities
imageId: 'accommodation' // Residential rooms
imageId: 'common_rooms' // Common areas
imageId: 'community_center' // Community center
imageId: 'person_warden' // People images
Replace ImagePlaceholder with actual <img> tags and update src to your image URLs. Maintain aspect ratios: 16:9 (hero), 4:3 (facility cards), 1:1 (people).
Responsive Breakpoints
XS: < 480px (Mobile)
SM: 480–767px (Small tablet)
MD: 768–1023px (Tablet)
LG: 1024–1279px (Desktop)
XL: ≥ 1280px (Large desktop)
Environment Variables
VITE_API_URL=https://example.com/wp-json/uhall/v1
VITE_FORM_ENDPOINT=/submissions
For WordPress mu-plugin deployment, set VITE_API_URL to your WordPress site's REST API base URL (e.g., https://yoursite.com/wp-json/uhall/v1).
Testing & Quality
npx tsc --noEmit # Type checking
npm run build # Build check
Content Management
All static content is in src/constants/content.ts:
- Timeline events, Facilities data, Events list, People/team members
- Testimonials, FAQ items, Social links, Office information
Contributors
Maulei 💻 🐛 📖 👀 🚧 ⚠️ 🎨 |
devggupta 🎨 |
License
© 1956 - 2026 University Hall, The University of Hong Kong. All rights reserved.