Add TranslatorModal and PhrasebookModal to ServicesScreen; update localization for new phrases
This commit is contained in:
@@ -7,12 +7,15 @@ import React, { useState } from 'react';
|
|||||||
import CurrencyConverterModal from '@/components/CurrencyConverterModal';
|
import CurrencyConverterModal from '@/components/CurrencyConverterModal';
|
||||||
import HotelBusinessCardModal from '@/components/HotelBusinessCardModal';
|
import HotelBusinessCardModal from '@/components/HotelBusinessCardModal';
|
||||||
import LostKeyModal from '@/components/LostKeyModal';
|
import LostKeyModal from '@/components/LostKeyModal';
|
||||||
|
import TranslatorModal from '@/components/TranslatorModal';
|
||||||
|
import PhrasebookModal from '@/components/PhrasebookModal';
|
||||||
|
|
||||||
export default function ServicesScreen() {
|
export default function ServicesScreen() {
|
||||||
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
|
const [currencyModalVisible, setCurrencyModalVisible] = useState(false);
|
||||||
const [hotelModalVisible, setHotelModalVisible] = useState(false);
|
const [hotelModalVisible, setHotelModalVisible] = useState(false);
|
||||||
const [lostKeyModalVisible, setLostKeyModalVisible] = useState(false);
|
const [lostKeyModalVisible, setLostKeyModalVisible] = useState(false);
|
||||||
const [translatorModalVisible, setTranslatorModalVisible] = useState(false);
|
const [translatorModalVisible, setTranslatorModalVisible] = useState(false);
|
||||||
|
const [phrasebookModalVisible, setPhrasebookModalVisible] = useState(false);
|
||||||
|
|
||||||
const services = [
|
const services = [
|
||||||
{
|
{
|
||||||
@@ -39,6 +42,12 @@ export default function ServicesScreen() {
|
|||||||
icon: <FontAwesome5 name="language" size={24} color="#D4AF37" />,
|
icon: <FontAwesome5 name="language" size={24} color="#D4AF37" />,
|
||||||
onPress: () => setTranslatorModalVisible(true),
|
onPress: () => setTranslatorModalVisible(true),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('Phrasebook'),
|
||||||
|
name: 'phrasebook',
|
||||||
|
icon: <FontAwesome5 name="book" size={24} color="#D4AF37" />,
|
||||||
|
onPress: () => setPhrasebookModalVisible(true),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -64,6 +73,14 @@ export default function ServicesScreen() {
|
|||||||
visible={lostKeyModalVisible}
|
visible={lostKeyModalVisible}
|
||||||
onClose={() => setLostKeyModalVisible(false)}
|
onClose={() => setLostKeyModalVisible(false)}
|
||||||
/>
|
/>
|
||||||
|
<TranslatorModal
|
||||||
|
visible={translatorModalVisible}
|
||||||
|
onClose={() => setTranslatorModalVisible(false)}
|
||||||
|
/>
|
||||||
|
<PhrasebookModal
|
||||||
|
visible={phrasebookModalVisible}
|
||||||
|
onClose={() => setPhrasebookModalVisible(false)}
|
||||||
|
/>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
122
components/PhrasebookModal.tsx
Normal file
122
components/PhrasebookModal.tsx
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Modal, View, Text, StyleSheet, TouchableOpacity, FlatList, SafeAreaView } from 'react-native';
|
||||||
|
import { View as ThemedView } from './Themed';
|
||||||
|
import { FontAwesome } from '@expo/vector-icons';
|
||||||
|
import i18n from '@/i18n';
|
||||||
|
|
||||||
|
type PhrasebookModalProps = {
|
||||||
|
visible: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const PHRASES = [
|
||||||
|
{ tk: 'Salam', ar: 'مرحبا (Marhaban)' },
|
||||||
|
{ tk: 'Hawa', ar: 'نعم (Na\'am)' },
|
||||||
|
{ tk: 'Ýok', ar: 'لا (La)' },
|
||||||
|
{ tk: 'Sag boluň', ar: 'شكرا (Shukran)' },
|
||||||
|
{ tk: 'Minnetdar', ar: 'شكرا جزيلا (Shukran Gazilan)' },
|
||||||
|
{ tk: 'Haýyş edýärin', ar: 'من فضلك (Min fadlik)' },
|
||||||
|
{ tk: 'Bagyşlaň', ar: 'آسف (Asif)' },
|
||||||
|
{ tk: 'Men size nähili kömek edip bilerin?', ar: 'كيف يمكنني مساعدتك؟ (Kayfa yumkinuni musa\'adatuk?)' },
|
||||||
|
{ tk: 'Bu näçe?', ar: 'بكم هذا؟ (Bikam hadha?)' },
|
||||||
|
{ tk: 'Hajathana nirede?', ar: 'أين الحمام؟ (Ayna al-hammam?)' },
|
||||||
|
{ tk: 'Men ýolumy ýitirdim', ar: 'لقد ضللت طريقي (Laqad dalalt tariqi)' },
|
||||||
|
{ tk: 'Lukman çagyryň', ar: 'اتصل بطبيب (Ittasil bi-tabib)' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const PhrasebookModal = ({ visible, onClose }: PhrasebookModalProps) => {
|
||||||
|
const renderItem = ({ item }: { item: { tk: string; ar: string } }) => (
|
||||||
|
<View style={styles.phraseItem}>
|
||||||
|
<Text style={styles.turkmenText}>{item.tk}</Text>
|
||||||
|
<Text style={styles.arabicText}>{item.ar}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
animationType="slide"
|
||||||
|
transparent={true}
|
||||||
|
visible={visible}
|
||||||
|
onRequestClose={onClose}
|
||||||
|
>
|
||||||
|
<ThemedView style={styles.centeredView}>
|
||||||
|
<View style={styles.modalView}>
|
||||||
|
<TouchableOpacity style={styles.closeButton} onPress={onClose}>
|
||||||
|
<FontAwesome name="close" size={24} color="black" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>{i18n.t('Phrasebook')}</Text>
|
||||||
|
<SafeAreaView style={styles.listContainer}>
|
||||||
|
<FlatList
|
||||||
|
data={PHRASES}
|
||||||
|
renderItem={renderItem}
|
||||||
|
keyExtractor={(item, index) => index.toString()}
|
||||||
|
ItemSeparatorComponent={() => <View style={styles.separator} />}
|
||||||
|
/>
|
||||||
|
</SafeAreaView>
|
||||||
|
</View>
|
||||||
|
</ThemedView>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
centeredView: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
},
|
||||||
|
modalView: {
|
||||||
|
margin: 20,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
borderRadius: 20,
|
||||||
|
padding: 20,
|
||||||
|
paddingTop: 40,
|
||||||
|
alignItems: 'center',
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: {
|
||||||
|
width: 0,
|
||||||
|
height: 2,
|
||||||
|
},
|
||||||
|
shadowOpacity: 0.25,
|
||||||
|
shadowRadius: 4,
|
||||||
|
elevation: 5,
|
||||||
|
width: '90%',
|
||||||
|
height: '80%',
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 15,
|
||||||
|
right: 15,
|
||||||
|
zIndex: 1,
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 15,
|
||||||
|
},
|
||||||
|
listContainer: {
|
||||||
|
width: '100%',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
phraseItem: {
|
||||||
|
paddingVertical: 15,
|
||||||
|
paddingHorizontal: 10,
|
||||||
|
},
|
||||||
|
turkmenText: {
|
||||||
|
fontSize: 16,
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
arabicText: {
|
||||||
|
fontSize: 18,
|
||||||
|
textAlign: 'right',
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#eee',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PhrasebookModal;
|
||||||
175
components/TranslatorModal.tsx
Normal file
175
components/TranslatorModal.tsx
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Modal, View, Text, TextInput, Button, StyleSheet, TouchableOpacity, KeyboardAvoidingView, Platform, ScrollView } from 'react-native';
|
||||||
|
import { View as ThemedView } from './Themed';
|
||||||
|
import { FontAwesome } from '@expo/vector-icons';
|
||||||
|
import i18n from '@/i18n';
|
||||||
|
|
||||||
|
type TranslatorModalProps = {
|
||||||
|
visible: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TranslatorModal = ({ visible, onClose }: TranslatorModalProps) => {
|
||||||
|
const [turkmenText, setTurkmenText] = useState('');
|
||||||
|
const [arabicText, setArabicText] = useState('');
|
||||||
|
|
||||||
|
const handleTranslate = async () => {
|
||||||
|
if (turkmenText.trim() === '') {
|
||||||
|
setArabicText('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Placeholder for Translation API call ---
|
||||||
|
// You would replace this with your actual translation logic.
|
||||||
|
// For example, calling a function that makes an API request to a translation service.
|
||||||
|
try {
|
||||||
|
// const translated = await translateText(turkmenText, 'tk', 'ar');
|
||||||
|
// setArabicText(translated);
|
||||||
|
setArabicText(`(Translation for: ${turkmenText})`); // Mock response
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Translation error:", error);
|
||||||
|
setArabicText("Error: Could not translate.");
|
||||||
|
}
|
||||||
|
// -----------------------------------------
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
animationType="slide"
|
||||||
|
transparent={true}
|
||||||
|
visible={visible}
|
||||||
|
onRequestClose={onClose}
|
||||||
|
>
|
||||||
|
<KeyboardAvoidingView
|
||||||
|
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||||
|
style={styles.keyboardAvoidingContainer}
|
||||||
|
>
|
||||||
|
<ThemedView style={styles.centeredView}>
|
||||||
|
<ScrollView contentContainerStyle={styles.scrollViewContent}>
|
||||||
|
<View style={styles.modalView}>
|
||||||
|
<TouchableOpacity style={styles.closeButton} onPress={onClose}>
|
||||||
|
<FontAwesome name="close" size={24} color="black" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={styles.modalTitle}>{i18n.t('Translator')}</Text>
|
||||||
|
|
||||||
|
<View style={styles.inputContainer}>
|
||||||
|
<Text style={styles.label}>Türkmençe</Text>
|
||||||
|
<TextInput
|
||||||
|
style={[styles.textInput, styles.turkmenInput]}
|
||||||
|
placeholder="Hat yaz"
|
||||||
|
placeholderTextColor="#888" // slightly grey
|
||||||
|
onChangeText={setTurkmenText}
|
||||||
|
value={turkmenText}
|
||||||
|
multiline
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={styles.inputContainer}>
|
||||||
|
<Text style={styles.label}>Arapça</Text>
|
||||||
|
<View style={styles.arabicOutputContainer}>
|
||||||
|
<Text style={styles.arabicText}>{arabicText}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<TouchableOpacity onPress={handleTranslate} style={styles.translateButton}>
|
||||||
|
<Text style={styles.translateButtonText}>{i18n.t('Translate')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</ThemedView>
|
||||||
|
</KeyboardAvoidingView>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
keyboardAvoidingContainer: {
|
||||||
|
flex: 1,
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
centeredView: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
scrollViewContent: {
|
||||||
|
flexGrow: 1,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
modalView: {
|
||||||
|
margin: 20,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
borderRadius: 20,
|
||||||
|
padding: 35,
|
||||||
|
alignItems: 'center',
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: {
|
||||||
|
width: 0,
|
||||||
|
height: 2,
|
||||||
|
},
|
||||||
|
shadowOpacity: 0.25,
|
||||||
|
shadowRadius: 4,
|
||||||
|
elevation: 5,
|
||||||
|
width: '100%',
|
||||||
|
minWidth: '90%',
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 10,
|
||||||
|
right: 10,
|
||||||
|
},
|
||||||
|
modalTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
inputContainer: {
|
||||||
|
marginBottom: 15,
|
||||||
|
minWidth: '90%',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
fontSize: 16,
|
||||||
|
marginBottom: 5,
|
||||||
|
color: '#333',
|
||||||
|
},
|
||||||
|
textInput: {
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#ddd',
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 10,
|
||||||
|
fontSize: 16,
|
||||||
|
minWidth: '90%',
|
||||||
|
},
|
||||||
|
turkmenInput: {
|
||||||
|
height: 100,
|
||||||
|
textAlignVertical: 'top',
|
||||||
|
},
|
||||||
|
arabicOutputContainer: {
|
||||||
|
height: 100,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: '#ddd',
|
||||||
|
borderRadius: 10,
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: '#f9f9f9',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
arabicText: {
|
||||||
|
fontSize: 18,
|
||||||
|
textAlign: 'right', // For RTL text
|
||||||
|
},
|
||||||
|
translateButton: {
|
||||||
|
marginTop: 15,
|
||||||
|
},
|
||||||
|
translateButtonText: {
|
||||||
|
color: '#D4AF37',
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default TranslatorModal;
|
||||||
@@ -42,5 +42,8 @@
|
|||||||
"Money": "Pul",
|
"Money": "Pul",
|
||||||
"Hotel": "Otel",
|
"Hotel": "Otel",
|
||||||
"Lost room key": "Açar otagyň içinde galdy",
|
"Lost room key": "Açar otagyň içinde galdy",
|
||||||
"Translator": "Perewod"
|
"Translator": "Perewod",
|
||||||
|
"Phrasebook": "Sözlük",
|
||||||
|
"Enter text in Turkmen": "Türkmençe sözleri gir",
|
||||||
|
"Translate": "Terjime et"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user