url fix
This commit is contained in:
335
App.tsx
335
App.tsx
@@ -1,20 +1,339 @@
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { StyleSheet, Text, View } from 'react-native';
|
||||
import { useState, useEffect } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
Alert,
|
||||
ActivityIndicator,
|
||||
SafeAreaView,
|
||||
StatusBar
|
||||
} from 'react-native';
|
||||
import { WebView } from 'react-native-webview';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
const STORAGE_KEY = '@condomob_url';
|
||||
const DEFAULT_URL = 'https://condopay.fcarra.mywire.org';
|
||||
|
||||
export default function App() {
|
||||
const [url, setUrl] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isValidating, setIsValidating] = useState(false);
|
||||
const [showWebView, setShowWebView] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
loadSavedUrl();
|
||||
}, []);
|
||||
|
||||
const loadSavedUrl = async () => {
|
||||
try {
|
||||
const savedUrl = await AsyncStorage.getItem(STORAGE_KEY);
|
||||
if (savedUrl) {
|
||||
setUrl(savedUrl);
|
||||
setShowWebView(true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading saved URL:', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const validateUrl = (urlString: string): boolean => {
|
||||
try {
|
||||
const parsedUrl = new URL(urlString);
|
||||
return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const isCondoPayUrl = (urlString: string): boolean => {
|
||||
// Check if URL contains 'condopay' in the hostname
|
||||
const lowerUrl = urlString.toLowerCase();
|
||||
return lowerUrl.includes('condopay');
|
||||
};
|
||||
|
||||
const handleConnect = async () => {
|
||||
if (!url.trim()) {
|
||||
Alert.alert('Errore', 'Inserisci un URL valido');
|
||||
return;
|
||||
}
|
||||
|
||||
// Add https:// if no protocol is provided
|
||||
let finalUrl = url.trim();
|
||||
if (!finalUrl.startsWith('http://') && !finalUrl.startsWith('https://')) {
|
||||
finalUrl = 'https://' + finalUrl;
|
||||
}
|
||||
|
||||
// Validate URL format
|
||||
if (!validateUrl(finalUrl)) {
|
||||
Alert.alert('Errore', 'L\'URL inserito non è valido');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a CondoPay URL
|
||||
if (!isCondoPayUrl(finalUrl)) {
|
||||
Alert.alert(
|
||||
'URL non valido',
|
||||
'L\'URL deve puntare a un\'istanza di CondoPay (deve contenere "condopay" nel dominio)'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsValidating(true);
|
||||
|
||||
// Try to validate by checking if the URL is reachable
|
||||
try {
|
||||
const response = await fetch(finalUrl, {
|
||||
method: 'HEAD',
|
||||
signal: AbortSignal.timeout(10000)
|
||||
});
|
||||
|
||||
if (response.ok || response.status === 200 || response.status === 301 || response.status === 302) {
|
||||
// Save URL and show WebView
|
||||
await AsyncStorage.setItem(STORAGE_KEY, finalUrl);
|
||||
setUrl(finalUrl);
|
||||
setShowWebView(true);
|
||||
} else {
|
||||
Alert.alert('Errore', 'Impossibile connettersi all\'istanza di CondoPay');
|
||||
}
|
||||
} catch (error) {
|
||||
// If fetch fails, still try to show the WebView - it might work
|
||||
console.log('Validation fetch failed, trying WebView anyway:', error);
|
||||
try {
|
||||
await AsyncStorage.setItem(STORAGE_KEY, finalUrl);
|
||||
setUrl(finalUrl);
|
||||
setShowWebView(true);
|
||||
} catch (storageError) {
|
||||
Alert.alert('Errore', 'Impossibile salvare l\'URL');
|
||||
}
|
||||
} finally {
|
||||
setIsValidating(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setShowWebView(false);
|
||||
};
|
||||
|
||||
// Loading screen while checking for saved URL
|
||||
if (isLoading) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.content}>
|
||||
<ActivityIndicator size="large" color="#007AFF" />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
// WebView screen
|
||||
if (showWebView) {
|
||||
return (
|
||||
<SafeAreaView style={styles.webViewContainer}>
|
||||
<StatusBar barStyle="dark-content" />
|
||||
<View style={styles.webViewHeader}>
|
||||
<TouchableOpacity onPress={handleBack} style={styles.backButton}>
|
||||
<Text style={styles.backButtonText}>← Indietro</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle} numberOfLines={1}>
|
||||
CondoPay
|
||||
</Text>
|
||||
<View style={styles.placeholder} />
|
||||
</View>
|
||||
<WebView
|
||||
source={{ uri: url }}
|
||||
style={styles.webView}
|
||||
startInLoadingState={true}
|
||||
renderLoading={() => (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color="#007AFF" />
|
||||
<Text style={styles.loadingText}>Caricamento...</Text>
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
// Configuration screen
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Open up App.tsx to start working on your app!</Text>
|
||||
<StatusBar style="auto" />
|
||||
</View>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar barStyle="dark-content" />
|
||||
<View style={styles.content}>
|
||||
<View style={styles.logoContainer}>
|
||||
<Text style={styles.logoText}>🏠</Text>
|
||||
<Text style={styles.title}>CondoMob</Text>
|
||||
<Text style={styles.subtitle}>Connetti al tuo CondoPay</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.label}>URL Istanza CondoPay</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
value={url}
|
||||
onChangeText={setUrl}
|
||||
placeholder="https://condopay.example.com"
|
||||
placeholderTextColor="#999"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
keyboardType="url"
|
||||
/>
|
||||
<Text style={styles.hint}>
|
||||
Inserisci l'URL della tua istanza CondoPay
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.button, isValidating && styles.buttonDisabled]}
|
||||
onPress={handleConnect}
|
||||
disabled={isValidating}
|
||||
>
|
||||
{isValidating ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.buttonText}>Connetti</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.exampleContainer}>
|
||||
<Text style={styles.exampleTitle}>Esempio:</Text>
|
||||
<Text style={styles.exampleUrl}>{DEFAULT_URL}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#f5f5f5',
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
padding: 24,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
logoContainer: {
|
||||
alignItems: 'center',
|
||||
marginBottom: 40,
|
||||
},
|
||||
logoText: {
|
||||
fontSize: 64,
|
||||
marginBottom: 16,
|
||||
},
|
||||
title: {
|
||||
fontSize: 32,
|
||||
fontWeight: 'bold',
|
||||
color: '#333',
|
||||
marginBottom: 8,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
},
|
||||
inputContainer: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
label: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
marginBottom: 8,
|
||||
},
|
||||
input: {
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
fontSize: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: '#ddd',
|
||||
},
|
||||
hint: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginTop: 8,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: '#007AFF',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: 'center',
|
||||
marginBottom: 24,
|
||||
},
|
||||
buttonDisabled: {
|
||||
backgroundColor: '#99c2ff',
|
||||
},
|
||||
buttonText: {
|
||||
color: '#fff',
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
},
|
||||
exampleContainer: {
|
||||
alignItems: 'center',
|
||||
marginTop: 20,
|
||||
},
|
||||
exampleTitle: {
|
||||
fontSize: 14,
|
||||
color: '#999',
|
||||
marginBottom: 8,
|
||||
},
|
||||
exampleUrl: {
|
||||
fontSize: 14,
|
||||
color: '#007AFF',
|
||||
fontFamily: 'monospace',
|
||||
},
|
||||
// WebView styles
|
||||
webViewContainer: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
webViewHeader: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
backgroundColor: '#fff',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#ddd',
|
||||
},
|
||||
backButton: {
|
||||
padding: 8,
|
||||
},
|
||||
backButtonText: {
|
||||
fontSize: 16,
|
||||
color: '#007AFF',
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
},
|
||||
placeholder: {
|
||||
width: 60,
|
||||
},
|
||||
webView: {
|
||||
flex: 1,
|
||||
},
|
||||
loadingContainer: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
loadingText: {
|
||||
marginTop: 12,
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user