diff --git a/amnet-native/app/ServerAddModal.tsx b/amnet-native/app/ServerAddModal.tsx
new file mode 100644
index 0000000..dd720ef
--- /dev/null
+++ b/amnet-native/app/ServerAddModal.tsx
@@ -0,0 +1,84 @@
+import {useCallback, useEffect, useState} from "react";
+import {Card, Paragraph, useTheme} from "react-native-paper";
+import {TextInput, TouchableOpacity, View} from "react-native";
+import {useModalStyles} from "../utils/ModalStyles";
+
+import RealmContext from "../models/RealmContext";
+import {AMServer} from "../models/AMServer";
+
+const {useRealm} = RealmContext;
+
+export default function ServerAddModal({navigation}) {
+ const realm = useRealm();
+ const theme = useTheme();
+ const modalStyles = useModalStyles();
+
+ const [serverAddress, setServerAddress] = useState('');
+
+ useEffect(() => {
+ navigation.setOptions({
+ headerLeft: () => navigation.goBack()}>
+ Cancel
+ ,
+ });
+ }, [navigation, modalStyles]);
+
+ useEffect(() => {
+ let urlValid = false;
+
+ try {
+ new URL(serverAddress);
+ urlValid = true;
+ } catch {
+ // do nothing
+ }
+
+ const themeOptions = urlValid ? modalStyles.headerText : {color: theme.colors.outline};
+
+ navigation.setOptions({
+ headerRight: () => saveServer()}>
+ Save
+
+ })
+ }, [navigation, modalStyles, serverAddress]);
+
+ const saveServer = useCallback(() => {
+ let serverObject = realm.objects("server").find(x => x.serverAddress == serverAddress);
+ if (!serverObject) {
+ realm.write(() => {
+ serverObject = realm.create("server", AMServer.generate(serverAddress));
+ });
+ }
+
+ navigation.goBack();
+ setTimeout(() => navigation.navigate('server-card-in', {
+ serverId: serverObject._id.toHexString()
+ }), 500);
+ }, [serverAddress, realm]);
+
+ return (
+
+
+
+
+ Address
+
+
+
+
+
+
+
+ If you're using HTTPS, ensure a trusted certificate has been configured via HTTP.SYS
+
+ )
+}
diff --git a/amnet-native/app/ServerCardIn.tsx b/amnet-native/app/ServerCardIn.tsx
new file mode 100644
index 0000000..d9bcacd
--- /dev/null
+++ b/amnet-native/app/ServerCardIn.tsx
@@ -0,0 +1,9 @@
+import {ScrollView} from "react-native";
+
+export default function ServerCardIn({navigation}) {
+ return (
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/amnet-native/app/ServerManager.tsx b/amnet-native/app/ServerManager.tsx
index e0cdc39..656f79b 100644
--- a/amnet-native/app/ServerManager.tsx
+++ b/amnet-native/app/ServerManager.tsx
@@ -1,9 +1,61 @@
-import {Text, View} from "react-native";
+import {Paragraph} from "react-native-paper";
+import React, {useCallback, useMemo} from "react";
+import {FlatList, Text, View} from "react-native";
+import {Globe, History, ServerOff} from "lucide-react-native";
+import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder";
+import {AMUICard, AMUICardDetail} from "../components/AMUICard";
+import TimeAgo from "../components/TimeAgo";
+
+import RealmContext from "../models/RealmContext";
+import {AMServer} from "../models/AMServer";
+
+const {useQuery} = RealmContext;
+
+function ServerCard(props: { server: AMServer, navigation: any }) {
+ const pageCallback = useCallback(() => {
+ props.navigation.navigate('server-card-in', {
+ serverId: props.server._id.toHexString()
+ });
+ }, [props.navigation, props.server]);
-export default function ServerManager() {
return (
-
- Server Manager
-
- );
+
+
+
+
+ {props.server.serverAddress}
+
+
+
+
+ {props.server.lastUsed
+ ? ()
+ : (never)}
+
+
+ )
+}
+
+export default function ServerManager({navigation}) {
+ const query = useQuery(AMServer);
+ const servers = useMemo(() => query.sorted("lastUsed"), [query]);
+
+ if (!servers.length) {
+ return (
+
+ }/>
+
+ );
+ }
+
+
+ return (
+ i._id.toString()}
+ contentContainerStyle={{paddingBottom: 40}}
+ ItemSeparatorComponent={() => }
+ renderItem={i => }/>
+ )
}
\ No newline at end of file
diff --git a/amnet-native/app/ServerManagerStack.tsx b/amnet-native/app/ServerManagerStack.tsx
new file mode 100644
index 0000000..037bd44
--- /dev/null
+++ b/amnet-native/app/ServerManagerStack.tsx
@@ -0,0 +1,42 @@
+import {Plus} from "lucide-react-native";
+import {TouchableOpacity} from "react-native";
+import {useTheme} from "@react-navigation/native";
+import {createNativeStackNavigator} from "@react-navigation/native-stack";
+
+import ServerCardIn from "./ServerCardIn";
+import ServerManager from "./ServerManager";
+import ServerAddModal from "./ServerAddModal";
+
+const Stack = createNativeStackNavigator();
+
+export default function ServerManagerStack({navigation}) {
+ const theme = useTheme();
+
+ return (
+
+
+ navigation.navigate('add-server')}>
+
+
+ }}/>
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file