Init
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import './styles.css';
|
||||
|
||||
function App() {
|
||||
const [users, setUsers] = useState([]);
|
||||
const [apiKeys, setApiKeys] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUsers();
|
||||
fetchApiKeys();
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
const fetchUsers = async () => {
|
||||
const res = await axios.get('/api/users');
|
||||
setUsers(res.data);
|
||||
};
|
||||
|
||||
const fetchApiKeys = async () => {
|
||||
const res = await axios.get('/api/api-keys');
|
||||
setApiKeys(res.data);
|
||||
};
|
||||
|
||||
if (loading) return <div>Loading...</div>;
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h1>Ollama Proxy Admin</h1>
|
||||
|
||||
<section>
|
||||
<h2>Users</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Username</th>
|
||||
<th>Email</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{users.map(user => (
|
||||
<tr key={user.id}>
|
||||
<td>{user.id}</td>
|
||||
<td>{user.username}</td>
|
||||
<td>{user.email}</td>
|
||||
<td>{user.is_active ? 'Active' : 'Inactive'}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>API Keys</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Key</th>
|
||||
<th>User</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{apiKeys.map(key => (
|
||||
<tr key={key.id}>
|
||||
<td>{key.id}</td>
|
||||
<td>{key.name}</td>
|
||||
<td>{key.key}</td>
|
||||
<td>{key.user_id}</td>
|
||||
<td>{key.is_active ? 'Active' : 'Inactive'}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,55 @@
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
color: #34495e;
|
||||
}
|
||||
|
||||
section {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: 12px 15px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #ecf0f1;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
color: #27ae60;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-inactive {
|
||||
color: #e74c3c;
|
||||
font-weight: 600;
|
||||
}
|
||||
Reference in New Issue
Block a user