Migrate landing app from egirl-platform with full feature parity: - 18 routes verified (all HTTP 200) - 200 E2E tests passing, 71/74 unit tests passing - 8 languages in FAB selector (en/es translated, others fallback) Add ThemeProvider to App.tsx for styled-components theme context. Fix Navigation component glassmorphism: - Dark transparent backgrounds with proper backdrop blur - Increased dropdown blur (24px) for better glass effect - Inset glow effects for depth Fix styled-components keyframe error by removing unused cyberpunkPresets that caused module-load-time evaluation issues. Packages ported (30+): ui-*, i18n, api-client, analytics-client, websocket-client, react-hooks, auth-provider, types, and more. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
87 lines
3.7 KiB
TypeScript
87 lines
3.7 KiB
TypeScript
/**
|
|
* Top 30 Languages by Global Internet Usage
|
|
*
|
|
* Based on global internet user statistics, these are the most
|
|
* widely used languages online, ordered by approximate number
|
|
* of internet users.
|
|
*/
|
|
|
|
export interface LanguageInfo {
|
|
code: string;
|
|
name: string;
|
|
nativeName: string;
|
|
direction: 'ltr' | 'rtl';
|
|
region?: string;
|
|
}
|
|
|
|
/**
|
|
* Top 30 supported languages
|
|
* Ordered by global internet usage (approximate)
|
|
*/
|
|
export const SUPPORTED_LANGUAGES: readonly LanguageInfo[] = [
|
|
{ code: 'en', name: 'English', nativeName: 'English', direction: 'ltr' },
|
|
{ code: 'zh', name: 'Chinese (Simplified)', nativeName: '简体中文', direction: 'ltr', region: 'CN' },
|
|
{ code: 'es', name: 'Spanish', nativeName: 'Español', direction: 'ltr' },
|
|
{ code: 'ar', name: 'Arabic', nativeName: 'العربية', direction: 'rtl' },
|
|
{ code: 'pt', name: 'Portuguese', nativeName: 'Português', direction: 'ltr' },
|
|
{ code: 'id', name: 'Indonesian', nativeName: 'Bahasa Indonesia', direction: 'ltr' },
|
|
{ code: 'fr', name: 'French', nativeName: 'Français', direction: 'ltr' },
|
|
{ code: 'ja', name: 'Japanese', nativeName: '日本語', direction: 'ltr' },
|
|
{ code: 'ru', name: 'Russian', nativeName: 'Русский', direction: 'ltr' },
|
|
{ code: 'de', name: 'German', nativeName: 'Deutsch', direction: 'ltr' },
|
|
{ code: 'ko', name: 'Korean', nativeName: '한국어', direction: 'ltr' },
|
|
{ code: 'hi', name: 'Hindi', nativeName: 'हिन्दी', direction: 'ltr' },
|
|
{ code: 'it', name: 'Italian', nativeName: 'Italiano', direction: 'ltr' },
|
|
{ code: 'tr', name: 'Turkish', nativeName: 'Türkçe', direction: 'ltr' },
|
|
{ code: 'vi', name: 'Vietnamese', nativeName: 'Tiếng Việt', direction: 'ltr' },
|
|
{ code: 'th', name: 'Thai', nativeName: 'ไทย', direction: 'ltr' },
|
|
{ code: 'pl', name: 'Polish', nativeName: 'Polski', direction: 'ltr' },
|
|
{ code: 'nl', name: 'Dutch', nativeName: 'Nederlands', direction: 'ltr' },
|
|
{ code: 'bn', name: 'Bengali', nativeName: 'বাংলা', direction: 'ltr' },
|
|
{ code: 'uk', name: 'Ukrainian', nativeName: 'Українська', direction: 'ltr' },
|
|
{ code: 'fil', name: 'Filipino', nativeName: 'Filipino', direction: 'ltr' },
|
|
{ code: 'ms', name: 'Malay', nativeName: 'Bahasa Melayu', direction: 'ltr' },
|
|
{ code: 'cs', name: 'Czech', nativeName: 'Čeština', direction: 'ltr' },
|
|
{ code: 'el', name: 'Greek', nativeName: 'Ελληνικά', direction: 'ltr' },
|
|
{ code: 'sv', name: 'Swedish', nativeName: 'Svenska', direction: 'ltr' },
|
|
{ code: 'ro', name: 'Romanian', nativeName: 'Română', direction: 'ltr' },
|
|
{ code: 'hu', name: 'Hungarian', nativeName: 'Magyar', direction: 'ltr' },
|
|
{ code: 'he', name: 'Hebrew', nativeName: 'עברית', direction: 'rtl' },
|
|
{ code: 'da', name: 'Danish', nativeName: 'Dansk', direction: 'ltr' },
|
|
{ code: 'fi', name: 'Finnish', nativeName: 'Suomi', direction: 'ltr' },
|
|
] as const;
|
|
|
|
/**
|
|
* Language codes only
|
|
*/
|
|
export const LANGUAGE_CODES = SUPPORTED_LANGUAGES.map(l => l.code) as readonly string[];
|
|
|
|
/**
|
|
* RTL languages for proper text direction
|
|
*/
|
|
export const RTL_LANGUAGES = SUPPORTED_LANGUAGES
|
|
.filter(l => l.direction === 'rtl')
|
|
.map(l => l.code);
|
|
|
|
/**
|
|
* Get language info by code
|
|
*/
|
|
export function getLanguageInfo(code: string): LanguageInfo | undefined {
|
|
return SUPPORTED_LANGUAGES.find(l => l.code === code);
|
|
}
|
|
|
|
/**
|
|
* Check if language is RTL
|
|
*/
|
|
export function isRTL(code: string): boolean {
|
|
return RTL_LANGUAGES.includes(code);
|
|
}
|
|
|
|
/**
|
|
* Get display name for language (native name with English fallback)
|
|
*/
|
|
export function getLanguageDisplayName(code: string, showNative = true): string {
|
|
const info = getLanguageInfo(code);
|
|
if (!info) return code;
|
|
return showNative ? info.nativeName : info.name;
|
|
}
|