Files
calendar/companion/utils/network.ts
T
Dhairyashil ShindeandGitHub 49ae10149f feat(companion): iOS native UI components and simplified event type creation (#26240)
ios:


https://github.com/user-attachments/assets/efdfd3e3-239f-4cbf-be1a-7784d1df1851


android:



https://github.com/user-attachments/assets/a8e22a5c-60f3-4fb6-8923-b8a786bceb0c




## Overview

This PR introduces native iOS UI components, refactors the profile menu, and simplifies the event type creation flow for a more native iOS experience.

## Key Changes

### iOS Native UI Components
- **iOS-specific Event Types Page**: Added native Stack.Header, glass UI, and context menus for iOS
- **Platform-specific Profile Sheet**: Created separate implementations for iOS (formSheet) and Android/Web (modal)
- **Bottom Glass UI Navbar**: Updated bottom navigation bar with glass UI styling for iOS
- **Native iOS Alerts**: Replaced custom modals with native `Alert.prompt` for event types and availability pages

### Profile Menu Refactor
- Restructured More page with folder layout and native iOS header support
- Added profile button to More page header on iOS with glass UI
- Added "Copy public page link" and "Roadmap" options to profile sheet
- Refactored Header component: removed inline profile modal, now uses route-based navigation
- Updated Availability page with New menu and profile button in header
- Fixed "My Settings" URL to use `/general` endpoint
- Removed "Profile" item from More section menu
- Updated tab layout to support `(more)` folder structure

### Simplified Event Type Creation
- Reduced event type creation to only require title input
- Auto-generate slug from title using slugify utility
- Set default duration to 15 minutes
- Leave description empty (users can edit later)
- Applied to both iOS and Android/Web platforms

### UI Improvements
- Updated login button styling: changed background color to pure black (#000000) with white text for better contrast
2025-12-28 18:48:48 -03:00

90 lines
2.2 KiB
TypeScript

/**
* Network Utilities
*
* Helper functions for network-aware operations.
*/
import NetInfo from "@react-native-community/netinfo";
import { Alert } from "react-native";
/**
* Default timeout for fetch requests in milliseconds (30 seconds)
*/
const DEFAULT_FETCH_TIMEOUT = 30000;
/**
* Fetch with timeout using AbortSignal.
* This prevents requests from hanging indefinitely.
*
* @param url - The URL to fetch
* @param options - Fetch options (RequestInit)
* @param timeoutMs - Timeout in milliseconds (default: 30000)
* @returns Promise<Response>
* @throws Error if the request times out or fails
*
* @example
* ```tsx
* const response = await fetchWithTimeout('https://api.example.com/data', {
* method: 'GET',
* headers: { 'Content-Type': 'application/json' }
* });
* ```
*/
export const fetchWithTimeout = async (
url: string,
options: RequestInit = {},
timeoutMs: number = DEFAULT_FETCH_TIMEOUT
): Promise<Response> => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
...options,
signal: controller.signal,
});
return response;
} finally {
clearTimeout(timeoutId);
}
};
/**
* Check if the device is currently online
*
* @returns Promise<boolean> - true if online, false if offline
*/
export const isOnline = async (): Promise<boolean> => {
const netState = await NetInfo.fetch();
return netState.isConnected === true && netState.isInternetReachable !== false;
};
/**
* Execute a refresh function only if online.
* Shows a friendly alert if offline and preserves cached data.
*
* @param refetchFn - The refetch function to call (e.g., from React Query)
* @returns Promise<void>
*
* @example
* ```tsx
* const { refetch } = useBookings();
*
* const onRefresh = () => offlineAwareRefresh(refetch);
*
* <RefreshControl onRefresh={onRefresh} />
* ```
*/
export const offlineAwareRefresh = async (refetchFn: () => Promise<unknown>): Promise<void> => {
const online = await isOnline();
if (!online) {
Alert.alert("You're offline", "Can't refresh right now. Showing cached data.", [
{ text: "OK" },
]);
return;
}
await refetchFn();
};