# Easy Reserveren - Restaurant Reserveringssysteem > Modern, betaalbaar reserveringssysteem voor restaurants met embeddable widget > €69 per jaar | Onbeperkte reserveringen | Real-time beschikbaarheid ## Project Overzicht Easy Reserveren is een volledig functioneel restaurant reserveringssysteem dat bestaat uit: - **Admin Panel**: Beheer van tafels, tijdslots, reserveringen, evenementen en klanten - **Reserveringswidget**: Embeddable widget voor websites waarmee gasten direct kunnen reserveren - **Analytics Dashboard**: Inzicht in bezettingsgraden, piekuren en gastvoorkeuren - **Multi-tenant**: Meerdere restaurants beheren vanuit één account ## Technologie Stack ### Frontend - React 18.3.1 met TypeScript - Vite 5.4.2 als build tool - Tailwind CSS voor styling - Lucide React voor iconografie ### Backend & Database - Supabase (PostgreSQL) met Row Level Security - @supabase/supabase-js 2.57.4 - Real-time synchronisatie voor beschikbaarheid ### Extra Functionaliteiten - jsPDF + jsPDF-AutoTable voor PDF export van reserveringen - Google Maps API integratie (@googlemaps/js-api-loader) - Stripe integratie voor betalingen (Edge Functions) ## Project Structuur ``` /tmp/cc-agent/59988886/project/ ├── src/ │ ├── components/ # React componenten │ │ ├── AdminPanel.tsx # Hoofdbeheer interface │ │ ├── AnalyticsPanel.tsx # Analytics en statistieken │ │ ├── EmbedCodeGenerator.tsx # Widget embed code │ │ ├── LandingPage.tsx # Marketing homepage │ │ ├── LoginPage.tsx # Authenticatie login │ │ ├── ReservationWidget.tsx # Embeddable widget │ │ ├── RestaurantOnboarding.tsx # Setup wizard │ │ ├── SignupPage.tsx # Registratie │ │ └── TimelineView.tsx # Tijdlijn reserveringen │ ├── contexts/ │ │ └── AuthContext.tsx # Auth state management │ ├── lib/ │ │ └── supabase.ts # Supabase client setup │ ├── App.tsx # Main app component │ └── main.tsx # Entry point ├── public/ │ ├── widget.js # Standalone widget script │ ├── test.html # Widget test page │ ├── robots.txt # SEO crawler rules │ ├── sitemap.xml # SEO sitemap │ └── llms.txt # AI indexering (dit bestand) ├── supabase/ │ ├── migrations/ # Database schema migrations │ └── functions/ # Edge Functions │ ├── stripe-checkout/ # Stripe checkout sessie │ └── stripe-webhook/ # Stripe webhook handler └── package.json # Dependencies ``` ## Database Schema ### Core Tables **restaurants** - Restaurant informatie - id (uuid, primary key) - name (text) - address (text) - phone (text) - email (text) - company_name, kvk_number, btw_number (bedrijfsinfo) - subscription_status, subscription_end_date, trial_end_date - stripe_customer_id, stripe_subscription_id - created_at, updated_at **tables** - Tafels - id (uuid, primary key) - restaurant_id (uuid, foreign key) - table_number (text) - capacity (integer) - is_active (boolean) **time_slots** - Openingstijden - id (uuid, primary key) - restaurant_id (uuid, foreign key) - day_of_week (integer, 0-6) - start_time (time) - end_time (time) - slot_duration (integer, minuten) - is_active (boolean) **reservations** - Reserveringen - id (uuid, primary key) - restaurant_id (uuid, foreign key) - table_id (uuid, foreign key) - event_id (uuid, nullable) - customer_name (text) - customer_email (text) - customer_phone (text) - party_size (integer) - reservation_date (date) - reservation_time (time) - status (text: 'pending', 'confirmed', 'seated', 'completed', 'cancelled') - notes (text) - created_at (timestamptz) **events** - Speciale evenementen - id (uuid, primary key) - restaurant_id (uuid, foreign key) - name (text) - description (text) - event_start_date, event_end_date (date) - daily_start_time, daily_end_time (time) - reservation_start_date, reservation_end_date (date) - max_reservation_days_ahead (integer) - color (text, hex) **blocked_dates** - Gesloten datums - id (uuid, primary key) - restaurant_id (uuid, foreign key) - blocked_date (date) - reason (text) **widget_settings** - Widget aanpassing - id (uuid, primary key) - restaurant_id (uuid, foreign key) - primary_color (text, hex) - secondary_color (text, hex) - text_color (text, hex) **user_restaurants** - Multi-tenant relaties - id (uuid, primary key) - user_id (uuid, foreign key naar auth.users) - restaurant_id (uuid, foreign key) - role (text: 'owner', 'admin', 'staff') ### Beveiliging (RLS Policies) Alle tabellen hebben Row Level Security enabled met policies voor: - Authenticated users: volledige CRUD voor eigen restaurants - Anonymous users: alleen SELECT voor widget (restaurants, tables, time_slots, events, blocked_dates) - Multi-tenant isolation via user_restaurants tabel ## API Endpoints ### Supabase Client Queries **Reserveringen ophalen** ```typescript const { data, error } = await supabase .from('reservations') .select('*, tables(*)') .eq('restaurant_id', restaurantId) .order('reservation_date', { ascending: true }); ``` **Beschikbare tijden checken** ```typescript const { data, error } = await supabase .from('time_slots') .select('*') .eq('restaurant_id', restaurantId) .eq('day_of_week', dayOfWeek) .eq('is_active', true); ``` **Nieuwe reservering maken** ```typescript const { data, error } = await supabase .from('reservations') .insert({ restaurant_id, table_id, customer_name, customer_email, customer_phone, party_size, reservation_date, reservation_time, status: 'pending' }); ``` ### Edge Functions **stripe-checkout** - URL: `/functions/v1/stripe-checkout` - Method: POST - Body: `{ priceId: string, restaurantId: string }` - Returns: Stripe checkout session URL **stripe-webhook** - URL: `/functions/v1/stripe-webhook` - Method: POST - Handles: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted - Updates: subscription_status in restaurants table ## Belangrijke Features ### 1. Admin Panel Functionaliteiten - **Tafelbeheer**: CRUD operaties voor tafels met capaciteit - **Tijdslot Planning**: Flexibele openingstijden per weekdag - **Reserveringsbeheer**: Lijst en tijdlijn views, status tracking - **Evenementenbeheer**: Speciale openingstijden voor events - **Geblokkeerde Datums**: Sluitingsdagen beheren - **Klantenbeheer**: Historie en contactinfo - **Widget Instellingen**: Kleurcustomization - **Analytics**: Bezettingsgraden, piekuren, omzet tracking - **PDF Export**: Reserveringsrapporten downloaden ### 2. Reserveringswidget - Stapsgewijze flow: personen → datum → tijd → gegevens → bevestiging - Real-time beschikbaarheid checking - Automatische tafel-toewijzing op basis van party_size - Respect voor events en blocked_dates - Responsive design (mobiel/desktop) - Aanpasbare kleuren via widget_settings - Embeddable via script tag ### 3. Multi-tenant Systeem - Supabase auth.users voor authenticatie - user_restaurants junction tabel voor toegang - Rol-gebaseerde toegang (owner, admin, staff) - Meerdere restaurants per gebruiker - Isolatie via RLS policies ### 4. Subscription Management - 28 dagen gratis trial - Stripe integratie voor betalingen - Automatische status updates via webhooks - Trial tracking met trial_end_date ## SEO & Discoverability ### Meta Tags (index.html) ```html