Files
shokuninmarche/server.js
airewit-developer c48464ac97 feat: Event Creation & Management — Organizer Dashboard (42327b58)
Backend:
- POST /api/events — create event, validates title/date/venue required,
  rejects past dates (Asia/Jerusalem aware), returns compliance_checklist flag
  when max_guests >= 100
- GET /api/events — list organizer events (scoped by JWT), paginated (limit 20),
  enriched with rsvp_confirmed/pending/total + vendors_confirmed counts,
  sorted by event_date ASC
- GET /api/events/:id — single event with RSVP + vendor counts
- PUT /api/events/:id — COALESCE update, validated status transitions
  (draft→published/cancelled, published→cancelled/completed),
  ownership enforced; returns compliance_checklist flag when crossing 100 guests
- DELETE /api/events/:id — soft delete (deleted_at + status=cancelled), 204

Frontend:
- DashboardPage — real event list, EventCard grid, pagination, prominent
  empty state with "צור אירוע ראשון" CTA
- EventCard — title, date, venue, RSVP confirmed/total/vendors stats,
  progress bar (orange at 90%), days-until countdown, publish/edit/cancel actions
- CreateEventPage — full form: title, date+time picker (min=today),
  venue, kashrut, budget, guest count; compliance checklist appears when
  max_guests >= 100, dismissible; Hebrew validation errors
- EventDetailPage — full event detail with stat cards, days-until,
  read-only compliance checklist for 100+ events, quick-action links
- ComplianceChecklist — reusable: interactive (create/edit) or read-only
  (detail page); 4 Israeli compliance items, dismissible banner
- Button component: added asChild support via @radix-ui/react-slot
- App.tsx: routes for /events/new, /events/:id, /events/:id/edit

Build: 0 TS errors, 68 modules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-21 18:41:42 +00:00

50 lines
1.4 KiB
JavaScript

require('dotenv').config();
const express = require('express');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const path = require('path');
const authRoutes = require('./routes/auth');
const eventRoutes = require('./routes/events');
const guestRoutes = require('./routes/guests');
const rsvpRoutes = require('./routes/rsvp');
const { authMiddleware } = require('./middleware/auth');
const { startReminderCron } = require('./jobs/reminderCron');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(cors({
origin: process.env.CLIENT_ORIGIN || true,
credentials: true,
}));
app.use(express.json());
app.use(cookieParser());
// Health check — no auth required
app.get('/health', (req, res) => res.json({ status: 'ok' }));
// Auth routes — no middleware (register/login are public)
app.use('/api/auth', authRoutes);
// Public RSVP routes — no auth required
app.use('/api/rsvp', rsvpRoutes);
// All routes below require valid JWT
app.use('/api', authMiddleware);
// Event + Guest management routes (auth enforced above)
app.use('/api/events', eventRoutes);
app.use('/api', guestRoutes);
// Serve React frontend in production
app.use(express.static(path.join(__dirname, 'client', 'dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'));
});
app.listen(PORT, () => {
console.log(`אירועית server running on port ${PORT}`);
startReminderCron();
});