-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.js
More file actions
106 lines (99 loc) · 4.21 KB
/
App.js
File metadata and controls
106 lines (99 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React, { useState, useEffect } from 'react';
import { SafeAreaView, ScrollView, StyleSheet } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import { Provider as PaperProvider, TextInput, Button, Title, Snackbar } from 'react-native-paper';
export default function App() {
const [artist, setArtist] = useState('');
const [song, setSong] = useState('');
const [lyrics, setLyrics] = useState('');
const [message, setMessage] = useState('');
const [visible, setVisible] = useState(false);
const [adminURL, setAdminURL] = useState('');
const [adminToken, setAdminToken] = useState('');
const [configured, setConfigured] = useState(false);
const resetConfig = async () => {
await SecureStore.deleteItemAsync('ADMIN_URL');
await SecureStore.deleteItemAsync('ADMIN_SECRET');
setAdminURL('');
setAdminToken('');
setConfigured(false);
showSnackbar('Configuration cleared. Enter new admin details.');
};
useEffect(() => {
const loadConfig = async () => {
const url = await SecureStore.getItemAsync('ADMIN_URL');
const token = await SecureStore.getItemAsync('ADMIN_SECRET');
if (url && token) {
setAdminURL(url);
setAdminToken(token);
setConfigured(true);
}
};
loadConfig();
}, []);
const showSnackbar = (text) => {
setMessage(text);
setVisible(true);
};
const saveConfig = async () => {
if (!adminURL || !adminToken) {
showSnackbar('Please fill both fields');
return;
}
await SecureStore.setItemAsync('ADMIN_URL', adminURL);
await SecureStore.setItemAsync('ADMIN_SECRET', adminToken);
setConfigured(true);
showSnackbar('Configuration saved securely ✅');
};
const sendRequest = async (actionType) => {
try {
const res = await fetch(adminURL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-admin-secret': adminToken },
body: JSON.stringify({ action: actionType, artist, song, lyrics: lyrics.split('\n') })
});
const data = await res.json();
if (data.success) showSnackbar(`✅ ${actionType} successful!`);
else showSnackbar(`❌ ${data.error || 'Failed'}`);
} catch (e) {
showSnackbar(`❌ ${e.message}`);
}
};
if (!configured) {
return (
<PaperProvider>
<SafeAreaView style={styles.container}>
<ScrollView>
<Title style={styles.title}>Lyrix Admin Setup</Title>
<TextInput label="Admin URL" value={adminURL} onChangeText={setAdminURL} mode="outlined" style={styles.input} />
<TextInput label="Admin Secret" value={adminToken} onChangeText={setAdminToken} mode="outlined" secureTextEntry style={styles.input} />
<Button mode="contained" onPress={saveConfig} style={styles.button}>Save</Button>
<Snackbar visible={visible} onDismiss={() => setVisible(false)} duration={3000}>{message}</Snackbar>
</ScrollView>
</SafeAreaView>
</PaperProvider>
);
}
return (
<PaperProvider>
<SafeAreaView style={styles.container}>
<ScrollView>
<Title style={styles.title}>Lyrix Admin</Title>
<TextInput label="Artist" value={artist} onChangeText={setArtist} mode="outlined" style={styles.input} />
<TextInput label="Song" value={song} onChangeText={setSong} mode="outlined" style={styles.input} />
<TextInput label="Lyrics (one line per timestamp)" value={lyrics} onChangeText={setLyrics} mode="outlined" multiline numberOfLines={10} style={styles.input} />
<Button mode="contained" onPress={() => sendRequest('add')} style={styles.button}>Add / Update</Button>
<Button mode="outlined" onPress={() => sendRequest('delete')} style={styles.button}>Delete</Button>
<Button mode="outlined" onPress={resetConfig} style={styles.button} color="#d32f2f">Logout</Button>
<Snackbar visible={visible} onDismiss={() => setVisible(false)} duration={3000}>{message}</Snackbar>
</ScrollView>
</SafeAreaView>
</PaperProvider>
);
}
const styles = StyleSheet.create({
container: { flex:1, padding:16, backgroundColor:'#fff' },
title: { marginBottom:16, textAlign:'center' },
input: { marginBottom:12 },
button: { marginVertical:6 }
});