A secure, standalone Next.js application for handling whistleblowing reports. This application operates independently from the main dashboard and communicates only through API endpoints.
- π Secure & Independent: No direct database access, API-only communication
- π¨ Dynamic Theming: Company branding and colors applied dynamically
- π± Responsive Design: Mobile-first design with Tailwind CSS
- ποΈ File Uploads: Support for multiple file types with validation
- π Report Tracking: Public and private tracking options
- π Multi-language Ready: Built with next-intl for internationalization
- βΏ Accessible: WCAG compliant form components
- π Performance Optimized: Lightweight and fast loading
This application follows the separation plan outlined in WHISTLEBLOWING_FORM_SEPARATION_PLAN.md:
- Complete Independence: No shared dependencies with dashboard
- API Communication: All data exchange through HTTP APIs
- Dynamic Configuration: Form settings fetched from dashboard API
- Security First: Rate limiting, input validation, and secure file handling
- Node.js 18 or higher
- npm or yarn
- A running instance of the Zaupy Dashboard (for API endpoints)
-
Clone and navigate to the project:
cd zaupy-form -
Install dependencies:
npm install
-
Set up environment variables:
cp .env.example .env.local
Create
.env.localwith your configuration:# Dashboard API Configuration (required) DASHBOARD_API_URL=http://localhost:3000 # Default subdomain for local development NEXT_PUBLIC_SUBDOMAIN_FALLBACK=devisium # Optional: Custom app URL NEXT_PUBLIC_APP_URL=http://localhost:3001
-
Start the development server:
npm run dev
-
Open your browser:
- Landing page: http://localhost:3001
- Company form: http://localhost:3001/[subdomain]
- Development form: http://localhost:3001/devisium
src/
βββ app/ # Next.js App Router pages
β βββ [subdomain]/ # Company-specific form pages
β β βββ page.tsx # Main form page
β β βββ success/ # Success page after submission
β β βββ track/ # Report tracking pages
β βββ globals.css # Global styles and CSS variables
β βββ layout.tsx # Root layout with security headers
β βββ page.tsx # Landing page
βββ components/ # React components
β βββ form/ # Form-specific components
β β βββ ReportForm.tsx # Main form component
β β βββ FormFields.tsx # Form input fields
β β βββ CategorySelect.tsx # Category selection
β β βββ TrackingOptions.tsx # Tracking mode selection
β β βββ FileUploadSection.tsx # File upload component
β βββ layout/ # Layout components
β β βββ Header.tsx # Dynamic header with branding
β β βββ Footer.tsx # Company footer
β β βββ PageLayout.tsx # Main layout wrapper
β βββ providers/ # React context providers
β β βββ ConfigProvider.tsx # Configuration context
β β βββ ThemeProvider.tsx # Dynamic theming
β βββ ui/ # Reusable UI components
β βββ Button.tsx # Button component
β βββ Input.tsx # Input component
β βββ Textarea.tsx # Textarea component
β βββ Select.tsx # Select component
β βββ Card.tsx # Card component
β βββ Alert.tsx # Alert component
β βββ LoadingSpinner.tsx # Loading component
β βββ FileUpload.tsx # File upload UI
βββ hooks/ # Custom React hooks
β βββ useFormConfig.ts # Configuration fetching hook
β βββ useReportSubmission.ts # Form submission hook
βββ lib/ # Utility libraries
β βββ api.ts # Dashboard API client
β βββ validation.ts # Form validation schemas
β βββ utils.ts # Utility functions
βββ types/ # TypeScript type definitions
βββ index.ts # All type definitions
The application communicates with the dashboard through these endpoints:
GET /api/public/forms/{subdomain}/configFetches company-specific form configuration including:
- Branding (logo, colors, content)
- Categories and validation rules
- File upload restrictions
- Tracking settings
POST /api/public/reports/submitSubmits new reports with:
- Form data validation
- File upload handling
- Tracking ID generation
GET /api/public/reports/track/{trackingId}Retrieves report status and updates.
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run type-check- Run TypeScript type checkingnpm test- Run Jest testsnpm run test:e2e- Run Playwright end-to-end tests
- UI Components: Add to
src/components/ui/ - Form Components: Add to
src/components/form/ - API Endpoints: Extend
src/lib/api.ts - Validation: Update
src/lib/validation.ts - Types: Add to
src/types/index.ts
The application supports dynamic theming through CSS custom properties:
// Colors are applied dynamically from API configuration
const colors = {
primary: '#3B82F6',
accent: '#8B5CF6',
success: '#10B981',
error: '#EF4444'
}-
Build the Docker image:
docker build -t zaupy-form . -
Run the container:
docker run -p 3001:3000 \ -e DASHBOARD_API_URL=https://your-dashboard.com \ zaupy-form
# Required
DASHBOARD_API_URL=https://your-dashboard.com
NEXT_PUBLIC_APP_URL=https://forms.yourcompany.com
# Optional
RATE_LIMIT_REQUESTS_PER_MINUTE=10
MAX_FILE_SIZE_MB=10
MAX_FILES_PER_SUBMISSION=5
LOG_LEVEL=infoConfigure your DNS and reverse proxy to route subdomains to this application:
# Nginx example
server {
server_name *.yourcompany.com;
location / {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}- No Database Access: Form app has no direct database connections
- Input Validation: Comprehensive validation with Zod
- Rate Limiting: Built-in request rate limiting
- File Security: File type and size validation
- CORS Protection: Proper cross-origin headers
- Security Headers: CSP, XSS protection, frame options
- HTTPS Enforcement: Secure communication only
npm testnpm run test:e2e- Form loads with correct branding
- All validation works correctly
- File uploads function properly
- Success page displays tracking ID
- Error states are handled gracefully
- Mobile responsiveness works
- Different company configurations work
- Report tracking functionality works
-
Configuration not loading
- Check
DASHBOARD_API_URLenvironment variable - Verify API endpoint is accessible
- Check CORS configuration on dashboard
- Ensure "devisium" company exists in dashboard for development
- Check
-
Styling issues
- Ensure Tailwind CSS is properly configured
- Check dynamic color application
- Verify CSS custom properties
-
File upload problems
- Check file size and type restrictions
- Verify API endpoint handles multipart/form-data
- Check browser console for upload errors
-
Tracking not working
- Verify tracking API endpoint is configured
- Check tracking ID format and password (if required)
- Ensure report exists in dashboard
Visit /api/health to check application status and API connectivity.
- Follow the existing code style and structure
- Add tests for new features
- Update documentation for changes
- Ensure type safety with TypeScript
- Test across different company configurations
This project is part of the Zaupy platform. See the main project license for details.
For issues and questions:
- Check the troubleshooting section above
- Review the separation plan document
- Contact the development team
Note: This is a standalone application that requires a running Zaupy Dashboard instance to function properly. The application is designed to be completely independent and communicates only through well-defined API endpoints.