Trashware is a real-time smart bin monitoring dashboard for campus or facility operations. It helps staff monitor trash bin fill levels, track full bins, manage device records, review activity history, and handle alerts from one web app.
This project is built with:
- Next.js (Pages Router)
- React
- TypeScript
- Tailwind CSS
- Firebase Firestore
- NextAuth
The application reads bin data from Firestore in real time and turns it into several operational views:
Dashboard: summary cards and bins that need attentionMonitoring: full live list of bins with search and status filtersManage Bin: create, edit, and delete bin recordsNotifications: alerts derived from full binsHistory / Analytics: trends and activity summaries from historical bin dataAuthentication: email/password and Google sign-in
- Real-time bin monitoring using Firestore
onSnapshot - Fill-level classification such as empty, nearly full, full, and offline
- Search by building, floor, room, and bin ID
- Full-bin notifications with read/unread state
- Bin CRUD management for operators
- Hourly history synchronization for analytics
- Credentials login and Google login with role stored in Firestore
- Framework: Next.js
16 - UI: React
19, Tailwind CSS4 - Auth:
next-auth - Database: Firebase Firestore
- Utilities:
date-fns,bcryptjs,react-icons
src/
components/
dashboard/
history/
layout/
manage/
notifications/
context/
SearchContext.tsx
lib/
firebase.ts
services/
deriveNotificationService.ts
historyAnalyticsService.ts
historyService.ts
notificationReadService.ts
pages/
api/
auth/[...nextauth].ts
register.ts
auth/
login/
register/
analytics/
history/
manage/
monitoring/
notifications/
index.tsx
styles/
types/
views/
- Users can register through
POST /api/register - Credentials login checks the
userscollection and compares hashed passwords - Google login creates a Firestore user record automatically if it does not exist
- User role is stored in the NextAuth JWT/session payload
- The app subscribes to the
binscollection in Firestore - Each bin record drives dashboard cards, monitoring cards, and management tables
- Bin health is derived mainly from:
status:onorofflevel: fill percentage
- Notifications are derived from live bin data instead of being persisted as full notification documents
- A notification exists when a bin is full (
level >= 90) - Read state is stored separately in the
notificationReadcollection - If a bin is no longer full, its read marker is cleaned up
- The app syncs bin snapshots into
bin_historyon an hourly basis - Analytics pages compute trends, peak times, and frequently full locations from that historical data
/- Public Interactive Landing Page (features, tech stack, live ESP32 simulator, and system telemetry console)/auth/login- User Sign-in Page (Credentials login + Google Google login)/auth/register- User Registration Page
/dashboard- Summary cards, attention list, and pickup priority leaderboard/monitoring- Live monitoring sheet of all bins with status/building filters/monitoring/[id]- bin detail / action page/manage- bin management/notifications- derived alerts/history- analytics and historical trends/analytics- analytics page entry present in the repo
/api/register/api/auth/[...nextauth]
The codebase currently implies these collections:
Primary live device/bin data.
Expected fields commonly used in the UI:
id: stringgedung: stringlantai: stringruang: stringcapacity: string | numberlevel: numberstatus: 'on' | 'off'lastUpdatelocationin some history flows
Application users for credentials and Google sign-in.
Common fields:
emailfullNamepassword(nullable for Google accounts)rolecreatedAt
Stores read/unread state for derived notifications.
Common fields:
notificationIdreadAt
Hourly snapshot data for analytics.
Common fields:
binIdlocationcapacitytimestampsource
Create a local environment file:
cp .env.example .env.localRequired variables:
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
NEXTAUTH_SECRET=
NEXTAUTH_URL=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=Install dependencies:
npm installRun the development server:
npm run devOpen http://localhost:3000.
Two details are worth knowing before extending the app:
- Some features use
capacityas literal bin capacity, while history code appears to use it as an analytics value. Verify the intended meaning before changing analytics logic. - Some screens build location from
gedung,lantai, andruang, while history sync also references alocationfield directly. Keeping those formats consistent will make the app easier to maintain.
- Middleware currently only matches
/admin/:path* - Most page-level auth protection is handled inside pages with
useSession - There is commented-out role logic in middleware, so role-based access control looks planned but not fully enforced globally yet
README.mdwas previously still the default Next.js template- Some notification code exists in commented legacy form and is no longer the active path
notificationReadService.subscribeToReadNotificationsis not a full real-time subscription yet- The repo contains a
.env.local; secrets should stay out of version control
- Add Firestore security rules documentation
- Document the exact bin schema used by the device side
- Clarify user roles and access policy
- Add deployment steps for Vercel or your chosen host
- Add architecture diagrams for device-to-database data flow