Add responsive design

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 15:26:37 +00:00
parent bdb8b2d7e2
commit 6b1e9a25af
7 changed files with 646 additions and 47 deletions

View File

@@ -0,0 +1,103 @@
/**
* Middleware for handling responsive API requests
* Ensures backend responds appropriately to different device types
*/
export interface DeviceInfo {
type: 'mobile' | 'tablet' | 'desktop';
userAgent: string;
screenWidth?: number;
screenHeight?: number;
}
/**
* Detect device type from User-Agent and viewport
*/
export function detectDevice(userAgent: string, width?: number): DeviceInfo['type'] {
const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
const tabletRegex = /iPad|Android(?!.*Mobile)/i;
if (width) {
if (width < 768) return 'mobile';
if (width < 1024) return 'tablet';
return 'desktop';
}
if (tabletRegex.test(userAgent)) return 'tablet';
if (mobileRegex.test(userAgent)) return 'mobile';
return 'desktop';
}
/**
* Optimize response payload based on device type
* Reduces data transfer for mobile devices
*/
export function optimizePayload<T extends Record<string, any>>(
data: T,
deviceType: DeviceInfo['type']
): T {
if (deviceType === 'mobile') {
// Remove heavy fields for mobile
const optimized = { ...data } as any;
// Remove high-res images, use thumbnails instead
if ('images' in data && Array.isArray(data.images)) {
optimized.images = (data.images as any[]).map((img: any) => ({
...img,
url: img.thumbnail || img.url,
highRes: undefined,
}));
}
// Limit array sizes for mobile
if ('items' in data && Array.isArray(data.items)) {
optimized.items = (data.items as any[]).slice(0, 10);
}
return optimized;
}
return data;
}
/**
* Add device info to API request headers
*/
export function addDeviceHeaders(headers: HeadersInit = {}): HeadersInit {
const width = typeof window !== 'undefined' ? window.innerWidth : undefined;
const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : '';
const deviceType = detectDevice(userAgent, width);
return {
...headers,
'X-Device-Type': deviceType,
'X-Screen-Width': width?.toString() || '',
'X-User-Agent': userAgent,
};
}
/**
* Adaptive pagination based on device
*/
export function getAdaptivePagination(deviceType: DeviceInfo['type']) {
const limits = {
mobile: 10,
tablet: 20,
desktop: 50,
};
return {
limit: limits[deviceType],
offset: 0,
};
}
/**
* Image quality based on device and connection
*/
export function getImageQuality(deviceType: DeviceInfo['type'], connectionType?: string): number {
if (connectionType === 'slow-2g' || connectionType === '2g') return 30;
if (deviceType === 'mobile') return 60;
if (deviceType === 'tablet') return 80;
return 90;
}