Rental Agreement Generator - Feature Summary
Overview
Built a complete Rental Agreement Generator feature that allows landlords to create rental agreements by adding tenant details, defining agreement terms, and generating a previewable PDF document.
Files Created
1. Schema & Validation (src/lib/schemas/agreement.ts)
- Purpose: Type-safe form validation using Zod
- Exports:
tenantDetailsSchema: Validates Step 1 (property selection, tenant details)agreementDetailsSchema: Validates Step 2 (financial terms, conditions)agreementFormSchema: Combined schema with cross-field validation- TypeScript types:
TenantDetailsFormData,AgreementDetailsFormData,AgreementFormData Propertyinterface for mock data
2. Agreement Form Component (src/app/(protected)/agreements/_components/agreement-form.tsx)
- Purpose: Multi-step form with React Hook Form + Zod validation
- Features:
- Step 1: Property selection dropdown with mock properties
- Step 1: Tenant details (first name, last name, mobile with Aadhaar note)
- Step 2: Financial terms (rent, deposit, tenure, lock-in period)
- Step 2: Additional charges and conditions (textarea)
- Navigation: “Next”, “Back”, “Generate Preview”, “Create & Send Invite” buttons
- Real-time validation across all fields
3. PDF Template Component (src/app/(protected)/agreements/_components/draft-agreement.tsx)
- Purpose: Professional PDF document using @react-pdf/renderer
- Features:
- Professional layout with header, sections, and footer
- Custom Inter font from Google Fonts
- Sections: Parties, Property Details, Financial Terms, T&Cs
- Standard rental clauses (rent payment, deposit, lock-in, maintenance, notice)
- Dynamic content from form data
- Signature blocks for landlord and tenant
- LandlordX branding footer
4. Agreement Viewer Component (src/app/(protected)/agreements/_components/review-agreement-details.tsx)
- Purpose: Display PDF preview in the UI
- Features:
- PDFViewer with toolbar for zoom/navigation
- 600px height with proper styling
- Memoized for performance
- Accepts form data and property/landlord details
5. Invite Dialog Component (src/components/features/invite-dialog.tsx)
- Purpose: Display shareable link after agreement creation
- Features:
- Modal dialog with success message
- Read-only input showing mock invite link
- Copy button with visual feedback (checkmark on success)
- “Done” button to close dialog
- Note about WhatsApp notification
5. Main Page (src/app/(protected)/agreements/create/page.tsx)
- Purpose: Orchestrates the entire user journey
- Features:
- Two-column layout (form left, preview right)
- Back button to dashboard
- Preview updates on “Generate Preview” click
- Placeholder shown when no preview generated
- Mock invite link generation (format:
https://landlordx.app/invite/{id}) - Invite dialog opens after “Create & Send Invite” submission
- Uses mock data for properties and landlord information
7. Mock Data (src/lib/mock/properties.ts)
- Purpose: Centralized mock data for development
- Exports:
MOCK_PROPERTIES: Array of 3 sample propertiesMOCK_LANDLORD: Landlord profile datagetPropertyById(): Helper to find property by IDgetPropertyDetails(): Helper to extract name/address for agreements
User Journey
- Navigate to
/agreements/create - Step 1 - Add Tenant:
- Select property from dropdown
- Enter tenant’s first name, last name, mobile number
- Click “Next” (validates before proceeding)
- Step 2 - Agreement Details:
- Enter monthly rent, security deposit
- Set agreement tenure and lock-in period
- Add optional charges and conditions
- Click “Generate Preview” to see PDF (right column)
- Review Preview:
- PDF renders with all entered data
- Structured document with professional styling
- Create Agreement:
- Click “Create & Send Invite”
- Dialog appears with mock shareable link
- Copy link button for easy sharing
- Click “Done” to close
Technical Implementation
Form State Management
- React Hook Form with Zod resolver
- Multi-step navigation with field-level validation
- Real-time error messages
- Number inputs properly parsed (rent, deposit, tenure)
PDF Generation
- @react-pdf/renderer for client-side PDF
- Responsive layout with professional styling
- Custom fonts for better typography
- Conditional rendering (e.g., optional charges/conditions)
Component Architecture
- Clear separation of concerns
- Reusable components with proper TypeScript types
- Proper import ordering following ESLint rules
- shadcn/ui components for consistent UI
- Centralized mock data in
src/lib/mock/for easy maintenance
Mock Data Organization
All mock data is now organized in src/lib/mock/:
properties.ts: Property listings, landlord information, helper functionsindex.ts: Central export point for all mock data
Benefits:
- Easy to locate and update mock data
- Type-safe with proper TypeScript definitions
- Helper functions for common operations
- Clear TODO comments for production API replacement
- Consistent with project conventions
Next Steps (Production Readiness)
-
API Integration:
- Fetch real properties from backend
- POST agreement data to
/api/agreements - POST tenant data to
/api/tenants - Generate actual shareable link with backend
-
Property Selection:
- Replace mock data with API call using TanStack Query
- Show property images/thumbnails
- Add property search/filter
-
Tenant Verification:
- Aadhaar verification flow
- DigiLocker integration for KYC
-
Agreement Storage:
- Save PDF to cloud storage (S3/Supabase Storage)
- Store agreement metadata in database
- Link agreement to property and tenant
-
Notifications:
- Send WhatsApp message with invite link
- Email notification to tenant
- SMS fallback
-
Invite Link Flow:
- Create
/invite/[id]page for tenant acceptance - E-signature capture
- Agreement status tracking (pending, signed, active)
- Create
-
Error Handling:
- Add toast notifications for API errors
- Loading states during submission
- Retry mechanisms
Dependencies Added
@react-pdf/renderer: Client-side PDF generationlucide-react: Icons (already installed, using ArrowLeftIcon, CopyIcon, CheckIcon)- shadcn/ui components:
dialog,textarea(added via CLI)
Testing Checklist
- Navigate to
/agreements/create - Fill Step 1 with valid data
- Try “Next” with invalid data (should show errors)
- Fill Step 2 with valid financial terms
- Click “Generate Preview” (PDF should render)
- Try invalid lock-in period > tenure (should show error)
- Click “Create & Send Invite” (dialog should open)
- Copy invite link (should show checkmark)
- Verify link format:
https://landlordx.app/invite/{7-char-id} - Click “Done” (dialog should close)
File Structure
apps/frontend/
├── docs/
│ └── RENTAL_AGREEMENT_FEATURE.md # This document
├── src/
│ ├── app/
│ │ └── (protected)/
│ │ └── agreements/
│ │ ├── _components/
│ │ │ ├── agreement-form.tsx # Multi-step form
│ │ │ ├── draft-agreement.tsx # PDF preview wrapper
│ │ │ └── review-agreement-details.tsx # PDF template
│ │ └── create/
│ │ └── page.tsx # Main orchestration page
│ └── lib/
│ ├── mock/
│ │ ├── index.ts # Mock data exports
│ │ └── properties.ts # Property & landlord mock data
│ └── schemas/
│ └── agreement.ts # Zod schemas & typesNotes
- All code follows LandlordX frontend conventions
- Proper TypeScript typing throughout
- ESLint rules satisfied
- Mobile-first responsive design
- Dark mode support via Tailwind CSS variables
- No compile or lint errors