This document describes the implementation of two new React components for the Gatherraa platform.
- Issue #302: Event Registration Guard Component
- Issue #306: Lazy Image Component with Optimization
A wrapper component that controls access to registration based on configurable conditions and rules.
✅ Wallet Connection Validation - Checks if user's wallet is connected
✅ Event Capacity Checking - Prevents registration when event is full
✅ Registration Deadline Enforcement - Blocks registration after deadline
✅ Custom Rule Support - Allows custom validation logic
✅ Contextual Messages - Displays appropriate error messages
✅ Reusable Design - Works across different event pages
✅ Customizable UI - Supports custom fallback components
import {
RegistrationGuard,
createWalletRule,
createCapacityRule,
createExpirationRule
} from '@/components/ui/molecules/RegistrationGuard';
const rules = [
createWalletRule(isWalletConnected),
createCapacityRule(currentRegistrations, maxCapacity),
createExpirationRule(registrationDeadline),
];
<RegistrationGuard rules={rules}>
<Button>Register Now</Button>
</RegistrationGuard>rules: RegistrationRule[]- Array of validation ruleschildren: React.ReactNode- Content to render when all rules passfallback?: React.ReactNode- Custom fallback for failed validationshowRuleDetails?: boolean- Show individual rule statusclassName?: string- Additional CSS classes
createWalletRule(isConnected: boolean)- Wallet connection rulecreateCapacityRule(current: number, max: number)- Capacity rulecreateExpirationRule(deadline: Date)- Expiration rulecreateCustomRule(check: Function, message: string)- Custom rule
An advanced image component with lazy loading, placeholder effects, and performance optimizations.
✅ Lazy Loading - Uses Intersection Observer for efficient loading
✅ Blur-up Effect - Smooth placeholder to image transition
✅ Skeleton Loading - Shows skeleton while loading
✅ Fallback Support - Displays fallback image on error
✅ Layout Shift Prevention - Maintains aspect ratios
✅ Responsive Design - Multiple object-fit options
✅ Error Handling - Graceful degradation on load failures
import { OptimizedImage } from '@/components/ui/atoms/OptimizedImage';
<OptimizedImage
src="https://example.com/image.jpg"
alt="Description"
aspectRatio="16/9"
lazy={true}
blurUp={true}
placeholder="data:image/svg+xml;base64,..."
fallbackSrc="/fallback.jpg"
className="rounded-lg"
/>src: string- Image source URLalt: string- Alternative textfallbackSrc?: string- Fallback image URLplaceholder?: string- Low-quality placeholder (LQIP)showSkeleton?: boolean- Show loading skeletonlazy?: boolean- Enable lazy loadingrootMargin?: string- Intersection Observer root marginthreshold?: number- Intersection Observer thresholdaspectRatio?: string- Aspect ratio (e.g., "16/9", "1/1")objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'blurUp?: boolean- Enable blur-up effectonLoad?: (event) => void- Load success callbackonError?: (event) => void- Load error callback
app/frontend/components/
├── ui/
│ ├── atoms/
│ │ ├── OptimizedImage/
│ │ │ ├── OptimizedImage.tsx
│ │ │ ├── OptimizedImage.stories.tsx
│ │ │ └── index.ts
│ │ └── index.ts (updated)
│ └── molecules/
│ ├── RegistrationGuard/
│ │ ├── RegistrationGuard.tsx
│ │ ├── RegistrationGuard.stories.tsx
│ │ └── index.ts
│ └── index.ts (updated)
└── Demo/
└── RegistrationDemo.tsx
Both components follow the existing design system patterns:
- Consistent Styling - Uses existing CSS variables and Tailwind classes
- Component Architecture - Follows atomic design principles
- TypeScript Support - Full type safety and IntelliSense
- Accessibility - Proper ARIA labels and semantic HTML
- Responsive Design - Mobile-first approach
- Dark Mode - Supports light/dark themes
Comprehensive Storybook stories are included for both components:
- All rules valid
- Wallet not connected
- Event full
- Registration expired
- Multiple issues
- Custom fallback
- Hide rule details
- Default image
- Aspect ratios
- Placeholder with blur-up
- Fallback image
- Lazy loading
- Object fit variants
- Custom skeleton
- Error handling
The components are designed with testability in mind:
- Pure Functions - Helper functions are easily testable
- Mockable Dependencies - External dependencies can be mocked
- Event Callbacks - Load/error events for testing
- State Management - Predictable state transitions
- Accessibility - Screen reader friendly markup
- Minimal re-renders with stable rule references
- Efficient rule evaluation
- Conditional rendering for optimal performance
- Intersection Observer for efficient lazy loading
- Image preloading with proper error handling
- Blur-up effect with CSS transitions
- Layout stability with aspect ratios
- Memory efficient with proper cleanup
- Modern Browsers - Chrome 88+, Firefox 85+, Safari 14+
- Intersection Observer - Supported in all modern browsers
- CSS Features - Uses widely supported CSS properties
- TypeScript - Full type support for better development experience
Replace manual validation checks with RegistrationGuard:
// Before
{isWalletConnected && !isEventFull && !isExpired ? (
<RegisterButton />
) : (
<ErrorMessage />
)}
// After
<RegistrationGuard rules={rules}>
<RegisterButton />
</RegistrationGuard>Replace basic img tags with OptimizedImage:
// Before
<img src={src} alt={alt} className="w-full h-full" />
// After
<OptimizedImage
src={src}
alt={alt}
aspectRatio="16/9"
lazy={true}
className="w-full"
/>- Integration with real wallet providers
- Advanced rule composition (AND/OR logic)
- Analytics tracking for registration attempts
- A/B testing support for different messages
- WebP/AVIF format support with fallbacks
- Progressive image loading
- Image optimization service integration
- Zoom/lightbox functionality
When contributing to these components:
- Follow existing code patterns and naming conventions
- Add comprehensive TypeScript types
- Include Storybook stories for new features
- Test accessibility with screen readers
- Verify performance impact with React DevTools
- Update documentation for API changes
Implementation Date: March 28, 2026
Issues Closed: #302, #306
Pull Request: feature/registration-guard-and-optimized-image