Connecting campus surplus food with students and local organizations — fast, safe, and with a little help from AI.
Mammoth ReServe is a React + TypeScript application that helps a university dining hall efficiently route surplus food to students, student groups, and local food banks. The app streamlines donation logging, highlights availability in real time, and uses Gemini to generate concise pickup alerts and image-based estimates of servings/weight to reduce waste and improve safety.
- Reduce campus food waste by making excess meals visible and reservable.
- Lower coordination friction between dining staff and community partners.
- Provide quick, consistent summaries (and estimates) for donated items.
- Encourage safe use via clear safety/allergen context and simple confirmations.
- Role-based entry points:
- Student: browse available items, reserve servings, and track pickups.
- Dining Hall Staff: log donations with photos, approve/revoke organizations, and manage pickup confirmations.
- Student Groups / Food Banks: sign in to receive and coordinate donations.
- AI assistance via Gemini:
- Image Analysis: estimates servings and weight; summarizes observations to help set expectations.
- Alert Generation: creates a concise, friendly message for quick broadcasts.
- Clean, mobile-friendly UI with clear flows for donation, reservation, and confirmation.
- Donation logging with optional photo upload and safety/allergen details.
- AI-generated summary and estimates for faster, consistent posting.
- Reservation workflow with pickup time and partial/all servings.
- Dining staff dashboards for user approvals and pickup confirmations.
- Role-based navigation and sign-in/register flows for organizations.
- Frontend (Vite/React/TS):
- SPA served by Vite during development on
http://localhost:3000. - Proxies API calls from
/api/*to the local server.
- SPA served by Vite during development on
- Backend (Express proxy):
- Runs on
http://localhost:5174by default. - Calls Gemini through
@google/genaistrictly on the server (API key never sent to the browser). - Endpoints:
POST /api/genai/analyze→{ base64Image }→{ foodName, summary, observations[], estimatedServings, estimatedWeightLbs }POST /api/genai/alert→{ foodItem, servings }→{ alertMessage }GET /api/health→{ ok: true }
- Runs on
- Frontend: React 19, TypeScript 5.8, Vite 6, Tailwind CSS (CDN), Recharts.
- Backend: Node.js (ESM), Express 4,
@google/genai(Gemini),cors,body-parser,dotenv. - Dev tooling:
concurrently(optional dual-run), Vite proxy for/api.
Prerequisites: Node.js 18+ and a Gemini API key
- Install dependencies
npm install- Configure your API key (server-side only)
- Option A: create
.env(or.env.local) and setGEMINI_API_KEY=your_key - Option B: copy the example and edit it
copy .env.example .env
# then open .env and set GEMINI_API_KEY- Start the Gemini proxy server (Terminal 1)
npm run start:server- Start the Vite dev server (Terminal 2)
npm run devApp: http://localhost:3000 (Vite proxies /api/* to the server on port 5174)
Optional: start both together (may not work in some shells)
npm run dev:all- Role Selection: Choose Student, Dining Hall Staff, or Organization.
- Dining Hall Staff:
- Add donations with optional photos and safety/allergen details.
- Review and approve/revoke organizations.
- Confirm pickups as completed.
- Students / Organizations:
- Browse available items; reserve servings and specify pickup time.
- Track reservations and pickups.
- API key stays on the server; never expose
GEMINI_API_KEYto the client. - Use
.envlocally and a proper secrets manager in production. - Consider adding rate limiting and authentication before internet exposure.
- AuthN/AuthZ for proxy endpoints and role management.
- Historical analytics on surplus patterns and pickup rates.
- Automated notification integrations (email/SMS/Slack).
- Accessibility and localization improvements.
- Built with React, Vite, and the Google Gemini SDK.