feat: Android

This commit is contained in:
2026-06-21 14:28:07 +02:00
parent edb1d5fe82
commit af06bc2b5c
13 changed files with 879 additions and 1258 deletions
+101 -20
View File
@@ -1,28 +1,109 @@
import { Button, SafeAreaView, ScrollView, Text, View } from 'react-native';
import { useState } from 'react';
import { StyleSheet, Text, View, TextInput, Button, ScrollView, ActivityIndicator } from 'react-native';
import JecnaapiReactNative from 'jecnaapi-react-native';
export default function App() {
return (
<SafeAreaView style={styles.container}>
<ScrollView style={styles.container}>
<Text style={styles.header}>Module API Example</Text>
</ScrollView>
</SafeAreaView>
);
}
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [result, setResult] = useState<string>('No data yet. Please login.');
const handleTestLoginAndFetch = async () => {
if (!username || !password) {
setResult('Error: Enter username and password');
return;
}
setLoading(true);
setResult('Logging in...');
try {
// 1. Call the raw native Kotlin bridge
const loginSuccess = await JecnaapiReactNative.login(username, password);
if (loginSuccess) {
setResult('Login Successful! Fetching profile...');
// 2. Fetch the raw JSON string
const rawProfileString = await JecnaapiReactNative.getStudentProfile();
// 3. Manually parse it (since you kept the default export)
const profile = JSON.parse(rawProfileString);
// Display it nicely on screen
setResult(JSON.stringify(profile, null, 2));
} else {
setResult('Login failed. Check credentials.');
}
} catch (error: any) {
setResult(`Bridge Error: ${error.message}`);
} finally {
setLoading(false);
}
};
function Group(props: { name: string; children: React.ReactNode }) {
return (
<View style={styles.group}>
<Text style={styles.groupHeader}>{props.name}</Text>
{props.children}
<View style={styles.container}>
<Text style={styles.header}>JecnaAPI Native Tester</Text>
<TextInput
style={styles.input}
placeholder="Username"
value={username}
onChangeText={setUsername}
autoCapitalize="none"
/>
<TextInput
style={styles.input}
placeholder="Password"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button title="Test Login & Fetch Profile" onPress={handleTestLoginAndFetch} disabled={loading} />
{loading && <ActivityIndicator style={{ marginTop: 20 }} size="large" color="#0000ff" />}
<ScrollView style={styles.resultBox}>
<Text style={styles.resultText}>{result}</Text>
</ScrollView>
</View>
);
}
const styles = {
header: { fontSize: 30, margin: 20 },
groupHeader: { fontSize: 20, marginBottom: 20 },
group: { margin: 20, backgroundColor: '#fff', borderRadius: 10, padding: 20 },
container: { flex: 1, backgroundColor: '#eee' },
view: { flex: 1, height: 200 },
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
paddingTop: 80,
backgroundColor: '#F5FCFF',
},
header: {
fontSize: 22,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
input: {
height: 50,
borderColor: '#ccc',
borderWidth: 1,
borderRadius: 8,
marginBottom: 15,
paddingHorizontal: 15,
backgroundColor: '#fff',
},
resultBox: {
marginTop: 20,
flex: 1,
backgroundColor: '#1e1e1e',
borderRadius: 8,
padding: 15,
},
resultText: {
color: '#00FF00',
fontFamily: 'monospace',
fontSize: 12,
},
});
+12 -2
View File
@@ -22,6 +22,16 @@
},
"web": {
"favicon": "./assets/favicon.png"
}
},
"plugins": [
[
"expo-build-properties",
{
"android": {
"minSdkVersion": 26
}
}
]
]
}
}
}
+15
View File
@@ -9,6 +9,7 @@
"version": "1.0.0",
"dependencies": {
"expo": "~56.0.12",
"expo-build-properties": "~56.0.19",
"react": "19.2.3",
"react-native": "0.85.3"
},
@@ -2625,6 +2626,20 @@
}
}
},
"node_modules/expo-build-properties": {
"version": "56.0.19",
"resolved": "https://registry.npmjs.org/expo-build-properties/-/expo-build-properties-56.0.19.tgz",
"integrity": "sha512-InoviXcxWosNp4cC7L3SWoiY99Xr2HdgN+LYHb6mUm/BBVxy1mIMrZR+3PJ2gwDZzW6EJNDz8ioASWGHBTmzpA==",
"license": "MIT",
"dependencies": {
"@expo/schema-utils": "^56.0.0",
"resolve-from": "^5.0.0",
"semver": "^7.6.0"
},
"peerDependencies": {
"expo": "*"
}
},
"node_modules/expo-modules-autolinking": {
"version": "56.0.16",
"resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-56.0.16.tgz",
+2 -1
View File
@@ -4,6 +4,7 @@
"main": "index.ts",
"dependencies": {
"expo": "~56.0.12",
"expo-build-properties": "~56.0.19",
"react": "19.2.3",
"react-native": "0.85.3"
},
@@ -23,4 +24,4 @@
"nativeModulesDir": ".."
}
}
}
}