feat: SAPIENS Mobile App - Initial commit

React Native mobile application for SAPIENS news platform.
Consolidated all previous history into single commit.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
jungwoo choi
2025-10-23 14:30:25 +09:00
commit 919afe56f2
1516 changed files with 64072 additions and 0 deletions

View File

@ -0,0 +1,135 @@
import { View, Text, Modal, TouchableOpacity, StyleSheet } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
interface LanguageModalProps {
visible: boolean;
onClose: () => void;
currentLanguage: string;
onSelectLanguage: (language: string) => void;
}
const languages = [
{ code: 'ko', name: '한국어', flag: '🇰🇷' },
{ code: 'en', name: 'English', flag: '🇺🇸' },
{ code: 'ja', name: '日本語', flag: '🇯🇵' },
{ code: 'zh-cn', name: '简体中文', flag: '🇨🇳' },
{ code: 'zh-tw', name: '繁體中文', flag: '🇹🇼' },
{ code: 'fr', name: 'Français', flag: '🇫🇷' },
{ code: 'de', name: 'Deutsch', flag: '🇩🇪' },
{ code: 'es', name: 'Español', flag: '🇪🇸' },
{ code: 'it', name: 'Italiano', flag: '🇮🇹' },
];
export default function LanguageModal({ visible, onClose, currentLanguage, onSelectLanguage }: LanguageModalProps) {
return (
<Modal
visible={visible}
transparent
animationType="fade"
onRequestClose={onClose}
>
<TouchableOpacity
style={styles.overlay}
activeOpacity={1}
onPress={onClose}
>
<View style={styles.modalContainer}>
<View style={styles.header}>
<Text style={styles.title}>Select Language</Text>
<TouchableOpacity onPress={onClose}>
<Ionicons name="close" size={24} color="#333" />
</TouchableOpacity>
</View>
<View style={styles.languageList}>
{languages.map((lang) => (
<TouchableOpacity
key={lang.code}
style={[
styles.languageItem,
currentLanguage === lang.code && styles.languageItemActive,
]}
onPress={() => {
onSelectLanguage(lang.code);
onClose();
}}
>
<View style={styles.languageInfo}>
<Text style={styles.flag}>{lang.flag}</Text>
<Text style={[
styles.languageName,
currentLanguage === lang.code && styles.languageNameActive,
]}>
{lang.name}
</Text>
</View>
{currentLanguage === lang.code && (
<Ionicons name="checkmark" size={20} color="#007AFF" />
)}
</TouchableOpacity>
))}
</View>
</View>
</TouchableOpacity>
</Modal>
);
}
const styles = StyleSheet.create({
overlay: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
modalContainer: {
backgroundColor: '#fff',
borderRadius: 12,
width: '85%',
maxWidth: 400,
maxHeight: '70%',
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
title: {
fontSize: 18,
fontWeight: '600',
color: '#000',
},
languageList: {
padding: 8,
},
languageItem: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
padding: 12,
borderRadius: 8,
marginBottom: 4,
},
languageItemActive: {
backgroundColor: '#f0f0f0',
},
languageInfo: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
flag: {
fontSize: 24,
},
languageName: {
fontSize: 16,
color: '#333',
},
languageNameActive: {
fontWeight: '600',
color: '#007AFF',
},
});