mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
adding admin screen
This commit is contained in:
parent
87e6760818
commit
80fb1472e4
@ -1,4 +1,44 @@
|
|||||||
|
import { SafeAreaView, Image, View } from 'react-native';
|
||||||
|
import { styles } from './Admin.styled';
|
||||||
|
import { useAdmin } from './useAdmin.hook';
|
||||||
|
import { Prompt } from './prompt/Prompt';
|
||||||
|
import { Dashboard } from './dashboard/Dashboard';
|
||||||
|
import logo from 'images/login.png';
|
||||||
|
|
||||||
export function Admin() {
|
export function Admin() {
|
||||||
return <></>
|
|
||||||
|
const { state, actions } = useAdmin();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.wrapper}>
|
||||||
|
<SafeAreaView>
|
||||||
|
{ state.split === true && (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.paddedPane}>
|
||||||
|
<Image style={styles.splash} source={logo} />
|
||||||
|
</View>
|
||||||
|
<View style={styles.pane}>
|
||||||
|
{ state.token == null && (
|
||||||
|
<Prompt login={actions.login} />
|
||||||
|
)}
|
||||||
|
{ state.token != null && (
|
||||||
|
<Dashboard token={state.token} config={state.config} logout={actions.logout} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
{ state.split === false && (
|
||||||
|
<View style={styles.container}>
|
||||||
|
{ state.token == null && (
|
||||||
|
<Prompt login={actions.login} />
|
||||||
|
)}
|
||||||
|
{ state.token != null && (
|
||||||
|
<Dashboard token={state.token} config={state.config} logout={actions.logout} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</SafeAreaView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
app/mobile/src/admin/Admin.styled.js
Normal file
30
app/mobile/src/admin/Admin.styled.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import { Colors } from 'constants/Colors';
|
||||||
|
|
||||||
|
export const styles = StyleSheet.create({
|
||||||
|
wrapper: {
|
||||||
|
backgroundColor: Colors.background,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
padding: 16,
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
splash: {
|
||||||
|
flex: 1,
|
||||||
|
width: null,
|
||||||
|
height: null,
|
||||||
|
resizeMode: 'contain',
|
||||||
|
},
|
||||||
|
pane: {
|
||||||
|
width: '50%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
paddedPane: {
|
||||||
|
width: '50%',
|
||||||
|
height: '100%',
|
||||||
|
paddingRight: 16,
|
||||||
|
},
|
||||||
|
});
|
3
app/mobile/src/admin/dashboard/Dashboard.jsx
Normal file
3
app/mobile/src/admin/dashboard/Dashboard.jsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export function Dashboard() {
|
||||||
|
return <></>
|
||||||
|
}
|
34
app/mobile/src/admin/prompt/Prompt.jsx
Normal file
34
app/mobile/src/admin/prompt/Prompt.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { ActivityIndicator, Alert, Text, TextInput, View, TouchableOpacity } from 'react-native';
|
||||||
|
import { styles } from './Prompt.styled';
|
||||||
|
import Ionicons from '@expo/vector-icons/AntDesign';
|
||||||
|
import { usePrompt } from './usePrompt.hook';
|
||||||
|
|
||||||
|
export function Prompt({ login }) {
|
||||||
|
|
||||||
|
const { state, actions } = usePrompt();
|
||||||
|
|
||||||
|
const setLogin = async () => {
|
||||||
|
try {
|
||||||
|
let config = await actions.attach();
|
||||||
|
login(state.password, config);
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
Alert.alert(
|
||||||
|
"Access Failed",
|
||||||
|
"Please check your admin token.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.wrapper}>
|
||||||
|
<View style={styles.container}>
|
||||||
|
<View style={styles.control}>
|
||||||
|
<TouchableOpacity onPress={actions.login}>
|
||||||
|
<Ionicons style={styles.config} name="user" size={24} color="#aaaaaa" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
103
app/mobile/src/admin/prompt/Prompt.styled.js
Normal file
103
app/mobile/src/admin/prompt/Prompt.styled.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import { Colors } from 'constants/Colors';
|
||||||
|
|
||||||
|
export const styles = StyleSheet.create({
|
||||||
|
wrapper: {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
paddingTop: 8,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
space: {
|
||||||
|
width: 32,
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
backgroundColor: Colors.formBackground,
|
||||||
|
borderRadius: 4,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
display: 'flex',
|
||||||
|
paddingLeft: 16,
|
||||||
|
paddingRight: 16,
|
||||||
|
},
|
||||||
|
control: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
color: Colors.grey,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
width: '100%',
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 24,
|
||||||
|
color: Colors.grey,
|
||||||
|
},
|
||||||
|
spacemid: {
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
textAlign: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
spacetop: {
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
textAlign: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
fontSize: 32,
|
||||||
|
color: Colors.text,
|
||||||
|
},
|
||||||
|
inputwrapper: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: '100%',
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: Colors.divider,
|
||||||
|
borderWidth: 1,
|
||||||
|
marginBottom: 16,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
inputfield: {
|
||||||
|
flex: 1,
|
||||||
|
textAlign: 'center',
|
||||||
|
padding: 8,
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
marginTop: 16,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: 128,
|
||||||
|
height: 28,
|
||||||
|
backgroundColor: Colors.primary,
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
logintext: {
|
||||||
|
color: Colors.formFocus,
|
||||||
|
},
|
||||||
|
nologin: {
|
||||||
|
marginTop: 16,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: 128,
|
||||||
|
height: 28,
|
||||||
|
borderRadius: 4,
|
||||||
|
borderColor: Colors.divider,
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
nologintext: {
|
||||||
|
color: Colors.disabled,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
25
app/mobile/src/admin/prompt/usePrompt.hook.js
Normal file
25
app/mobile/src/admin/prompt/usePrompt.hook.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
export function usePrompt() {
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
attach: () => {
|
||||||
|
},
|
||||||
|
login: () => {
|
||||||
|
navigate('/login');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return { state, actions };
|
||||||
|
}
|
||||||
|
|
29
app/mobile/src/admin/useAdmin.hook.js
Normal file
29
app/mobile/src/admin/useAdmin.hook.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { useWindowDimensions } from 'react-native';
|
||||||
|
|
||||||
|
export function useAdmin() {
|
||||||
|
|
||||||
|
const [state, setState] = useState({
|
||||||
|
split: null,
|
||||||
|
});
|
||||||
|
const dimensions = useWindowDimensions();
|
||||||
|
|
||||||
|
const updateState = (value) => {
|
||||||
|
setState((s) => ({ ...s, ...value }));
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (dimensions.width > 650) {
|
||||||
|
updateState({ split: true });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateState({ split: false });
|
||||||
|
}
|
||||||
|
}, [dimensions]);
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
};
|
||||||
|
|
||||||
|
return { state, actions };
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function getNodeConfig(token) {
|
export async function getNodeConfig(server, token) {
|
||||||
let config = await fetchWithTimeout(`/admin/config?token=${token}`, { method: 'GET' });
|
let config = await fetchWithTimeout(`https://${server}/admin/config?token=${token}`, { method: 'GET' });
|
||||||
checkResponse(config);
|
checkResponse(config);
|
||||||
return await config.json();
|
return await config.json();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function getNodeStatus() {
|
export async function getNodeStatus(server) {
|
||||||
let status = await fetchWithTimeout(`/admin/status`, { method: 'GET' });
|
let status = await fetchWithTimeout(`http://${server}/admin/status`, { method: 'GET' });
|
||||||
checkResponse(status);
|
checkResponse(status);
|
||||||
return await status.json();
|
return await status.json();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||||
|
|
||||||
export async function setNodeStatus(token) {
|
export async function setNodeStatus(server, token) {
|
||||||
let status = await fetchWithTimeout(`/admin/status?token=${token}`, { method: 'PUT' });
|
let status = await fetchWithTimeout(`http://${server}/admin/status?token=${token}`, { method: 'PUT' });
|
||||||
checkResponse(status);
|
checkResponse(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user