Internal dashboard for Tax Center Gunadarma. This repository is used for admin and operational workflows, including authentication, content management, activity data, volunteer data, research data, service-related data, and role-based dashboard pages.
This dashboard is built with Next.js App Router and is intended to support internal team workflows. Access to private areas is handled in proxy.ts, while frontend requests are routed through /api rewrites so pages do not need to hardcode the API domain everywhere.
Some important context for this app:
- the landing page is available at
/ - the main internal areas are
/dashboardand/dashboard-tax-volunteers - authentication pages live under
/auth/* - full metadata is only applied to the landing page
- the root app metadata is intentionally set to
noindexbecause this is primarily an internal-facing application
- Next.js 16
- React 19
- TypeScript
- Tailwind CSS 4
- TanStack Query
- Axios
- Tiptap
- React Hook Form + Zod
app/
auth/
dashboard/
dashboard-tax-volunteers/
components/
constant/
hooks/
lib/
providers/
public/
routes/
proxy.ts
Current structure guidelines:
app/**contains routes and layoutscomponents/**contains feature and UI componentslib/**contains helpers, axios setup, auth cookie helpers, and SEO helpersconstant/**contains shared constants such asAPI_BASE_URL,PROXY, and cookie keysproxy.tshandles redirects and role-based access control
Install dependencies:
npm installStart the development server:
npm run devRun a production build locally:
npm run build
npm run startThe dashboard currently uses:
NEXT_PUBLIC_SITE_URL=https://dashboard.taxcenterug.comThis value is used for landing page metadata, especially:
- canonical URL
- Open Graph URL
- Twitter card URL
metadataBase
If the dashboard domain or subdomain changes, update this value and redeploy.
The dashboard still points to staging services.
The main places to check are:
constant/constant.tsnext.config.ts
Current behavior:
API_BASE_URL = "https://stag.api.taxcenterug.com"/api/:path*is rewritten tohttps://stag.api.taxcenterug.com/api/:path*
So even if the dashboard itself is deployed to a production VPS, the data flow is still tied to the staging API until production endpoints are introduced.
Metadata helpers live in lib/seo.ts.
The landing page / has full metadata:
- title
- description
- canonical URL
- Open Graph
- Twitter card
The dashboard uses:
public/og_image.jpg
Internal dashboard pages are not intended for search indexing.
This repository is set up for VPS deployment on Hostinger using Docker and GitHub Actions.
Deployment files:
Dockerfiledocker-compose.prod.yml.github/workflows/docker-deploy.yml
On the server, the dashboard runs separately from the public website:
- deploy directory:
/opt/dashboard-taxcenter-web - host port:
127.0.0.1:3001
This allows it to live alongside taxcenter-web, which uses port 3000.
This repo expects:
VPS_HOSTVPS_PORTVPS_USERVPS_SSH_KEYGHCR_USERNAMEGHCR_TOKENNEXT_PUBLIC_SITE_URL
Run this once on the server:
sudo mkdir -p /opt/dashboard-taxcenter-web
sudo chown -R <deploy-user>:<deploy-user> /opt/dashboard-taxcenter-webAlso make sure:
- the deploy user can log in over SSH
- the deploy user is allowed to run Docker
- internal host port
3001is available
On the VPS:
cd /opt/dashboard-taxcenter-web
docker compose -f docker-compose.prod.yml ps
docker logs dashboard-taxcenter-web --tail 100
curl http://127.0.0.1:3001If you want to test it locally before wiring a domain, use an SSH tunnel:
ssh -L 3001:127.0.0.1:3001 -p 3190 <deploy-user>@<server-ip>Then open:
http://localhost:3001
Once the dashboard subdomain points to the VPS, Nginx should proxy requests to:
http://127.0.0.1:3001
SSL can be added afterward.
- this dashboard still makes the most sense as an internal/staging-oriented app
- when the dashboard domain changes, update
NEXT_PUBLIC_SITE_URL - if the backend moves from staging to production, review both
next.config.tsandconstant/constant.ts - if the landing page changes significantly, its metadata should be reviewed as well