From 51f8b3229c5a655b97ff43c45ed82743ae729ee2 Mon Sep 17 00:00:00 2001 From: fcarraUniSa Date: Fri, 27 Feb 2026 20:59:45 +0100 Subject: [PATCH] url fix --- App.tsx | 335 ++++++++++++++++++++++++++++++++++++++++++++-- app.json | 14 +- eas.json | 21 +++ package-lock.json | 187 +++++++++++++++++++++++++- package.json | 9 +- 5 files changed, 551 insertions(+), 15 deletions(-) create mode 100644 eas.json diff --git a/App.tsx b/App.tsx index 0329d0c..478205d 100644 --- a/App.tsx +++ b/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 ( + + + + + + ); + } + + // WebView screen + if (showWebView) { + return ( + + + + + โ† Indietro + + + CondoPay + + + + ( + + + Caricamento... + + )} + /> + + ); + } + + // Configuration screen return ( - - Open up App.tsx to start working on your app! - - + + + + + ๐Ÿ  + CondoMob + Connetti al tuo CondoPay + + + + URL Istanza CondoPay + + + Inserisci l'URL della tua istanza CondoPay + + + + + {isValidating ? ( + + ) : ( + Connetti + )} + + + + Esempio: + {DEFAULT_URL} + + + ); } 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', + }, }); diff --git a/app.json b/app.json index 33d76bb..e5df081 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,6 @@ { "expo": { - "name": "condomob", + "name": "Condopay Mobile", "slug": "condomob", "version": "1.0.0", "orientation": "portrait", @@ -13,7 +13,8 @@ "backgroundColor": "#ffffff" }, "ios": { - "supportsTablet": true + "supportsTablet": true, + "bundleIdentifier": "com.okcomputer.condopay" }, "android": { "adaptiveIcon": { @@ -21,10 +22,17 @@ "backgroundColor": "#ffffff" }, "edgeToEdgeEnabled": true, - "predictiveBackGestureEnabled": false + "predictiveBackGestureEnabled": false, + "permissions": ["INTERNET"], + "package": "com.okcomputer.condopay" }, "web": { "favicon": "./assets/favicon.png" + }, + "extra": { + "eas": { + "projectId": "1af9def8-ac59-42a0-b40e-76cf8a58bd23" + } } } } diff --git a/eas.json b/eas.json new file mode 100644 index 0000000..6e5c62e --- /dev/null +++ b/eas.json @@ -0,0 +1,21 @@ +{ + "cli": { + "version": ">= 18.0.3", + "appVersionSource": "remote" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal" + }, + "production": { + "autoIncrement": true + } + }, + "submit": { + "production": {} + } +} diff --git a/package-lock.json b/package-lock.json index d686396..8fe0771 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,13 @@ "name": "condomob", "version": "1.0.0", "dependencies": { + "@react-native-async-storage/async-storage": "^2.2.0", "expo": "~54.0.33", + "expo-dev-client": "~6.0.20", "expo-status-bar": "~3.0.9", "react": "19.1.0", - "react-native": "0.81.5" + "react-native": "0.81.5", + "react-native-webview": "^13.16.0" }, "devDependencies": { "@types/react": "~19.1.0", @@ -2661,6 +2664,18 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@react-native-async-storage/async-storage": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.2.0.tgz", + "integrity": "sha512-gvRvjR5JAaUZF8tv2Kcq/Gbt3JHwbKFYfmb445rhOj6NUMx3qPLixmDx5pZAyb9at1bYvJ4/eTUipU5aki45xw==", + "license": "MIT", + "dependencies": { + "merge-options": "^3.0.4" + }, + "peerDependencies": { + "react-native": "^0.0.0-0 || >=0.65 <1.0" + } + }, "node_modules/@react-native/assets-registry": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz", @@ -3137,6 +3152,22 @@ "node": ">= 14" } }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/anser": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz", @@ -4292,6 +4323,76 @@ } } }, + "node_modules/expo-dev-client": { + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-6.0.20.tgz", + "integrity": "sha512-5XjoVlj1OxakNxy55j/AUaGPrDOlQlB6XdHLLWAw61w5ffSpUDHDnuZzKzs9xY1eIaogOqTOQaAzZ2ddBkdXLA==", + "license": "MIT", + "dependencies": { + "expo-dev-launcher": "6.0.20", + "expo-dev-menu": "7.0.18", + "expo-dev-menu-interface": "2.0.0", + "expo-manifests": "~1.0.10", + "expo-updates-interface": "~2.0.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-launcher": { + "version": "6.0.20", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-6.0.20.tgz", + "integrity": "sha512-a04zHEeT9sB0L5EB38fz7sNnUKJ2Ar1pXpcyl60Ki8bXPNCs9rjY7NuYrDkP/irM8+1DklMBqHpyHiLyJ/R+EA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.11.0", + "expo-dev-menu": "7.0.18", + "expo-manifests": "~1.0.10" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-menu": { + "version": "7.0.18", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-7.0.18.tgz", + "integrity": "sha512-4kTdlHrnZCAWCT6tZRQHSSjZ7vECFisL4T+nsG/GJDo/jcHNaOVGV5qPV9wzlTxyMk3YOPggRw4+g7Ownrg5eA==", + "license": "MIT", + "dependencies": { + "expo-dev-menu-interface": "2.0.0" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-menu-interface": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-2.0.0.tgz", + "integrity": "sha512-BvAMPt6x+vyXpThsyjjOYyjwfjREV4OOpQkZ0tNl+nGpsPfcY9mc6DRACoWnH9KpLzyIt3BOgh3cuy/h/OxQjw==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-json-utils": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-0.15.0.tgz", + "integrity": "sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==", + "license": "MIT" + }, + "node_modules/expo-manifests": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-1.0.10.tgz", + "integrity": "sha512-oxDUnURPcL4ZsOBY6X1DGWGuoZgVAFzp6PISWV7lPP2J0r8u1/ucuChBgpK7u1eLGFp6sDIPwXyEUCkI386XSQ==", + "license": "MIT", + "dependencies": { + "@expo/config": "~12.0.11", + "expo-json-utils": "~0.15.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-modules-autolinking": { "version": "3.0.24", "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-3.0.24.tgz", @@ -4413,6 +4514,15 @@ "react-native": "*" } }, + "node_modules/expo-updates-interface": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-2.0.0.tgz", + "integrity": "sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo/node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -4828,12 +4938,34 @@ "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "license": "Apache-2.0" }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -5296,6 +5428,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -5797,6 +5938,12 @@ "node": ">=6" } }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -6194,6 +6341,18 @@ "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", "license": "MIT" }, + "node_modules/merge-options": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz", + "integrity": "sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==", + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7311,6 +7470,32 @@ "react-native": "*" } }, + "node_modules/react-native-webview": { + "version": "13.16.0", + "resolved": "https://registry.npmjs.org/react-native-webview/-/react-native-webview-13.16.0.tgz", + "integrity": "sha512-Nh13xKZWW35C0dbOskD7OX01nQQavOzHbCw9XoZmar4eXCo7AvrYJ0jlUfRVVIJzqINxHlpECYLdmAdFsl9xDA==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "invariant": "2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, + "node_modules/react-native-webview/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react-native/node_modules/@react-native/virtualized-lists": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.81.5.tgz", diff --git a/package.json b/package.json index 59deb28..adf6a20 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,18 @@ "main": "index.ts", "scripts": { "start": "expo start", - "android": "expo start --android", - "ios": "expo start --ios", + "android": "expo run:android", + "ios": "expo run:ios", "web": "expo start --web" }, "dependencies": { + "@react-native-async-storage/async-storage": "^2.2.0", "expo": "~54.0.33", + "expo-dev-client": "~6.0.20", "expo-status-bar": "~3.0.9", "react": "19.1.0", - "react-native": "0.81.5" + "react-native": "0.81.5", + "react-native-webview": "^13.16.0" }, "devDependencies": { "@types/react": "~19.1.0",