This commit is contained in:
Erik 2022-11-24 00:02:01 +02:00
parent 583e2eb8af
commit cab064a143
Signed by untrusted user: Navy.gif
GPG Key ID: 811EC0CD80E7E5FB
8 changed files with 85 additions and 69 deletions

View File

@ -7,10 +7,10 @@ export const TableListEntry = ({onClick, item, itemKeys}) => {
</tr>; </tr>;
}; };
export const Table = ({headerItems, children, items, itemKeys, maxWidth = '30em'}) => { export const Table = ({headerItems, children, items, itemKeys}) => {
let i = 0; let i = 0;
return <table className="striped hover" style={{ maxWidth, marginBottom: '10px' }}> return <table className="striped hover" >
<thead> <thead>
<tr> <tr>
{headerItems.map(item => <th key={item}>{item}</th>)} {headerItems.map(item => <th key={item}>{item}</th>)}

View File

@ -68,7 +68,7 @@ body{
} }
.pageTitle{ .pageTitle{
margin: 0.7em 0 0.7em; margin: 0;
} }
.flex { .flex {

View File

@ -2,7 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom/client'; import ReactDOM from 'react-dom/client';
import './css/index.css'; import './css/index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; // import reportWebVitals from './reportWebVitals';
import { UserContext } from './structures/UserContext'; import { UserContext } from './structures/UserContext';
const root = ReactDOM.createRoot(document.getElementById('root')); const root = ReactDOM.createRoot(document.getElementById('root'));
@ -11,6 +11,9 @@ root.render(<React.StrictMode>
<App /> <App />
</UserContext> </UserContext>
</React.StrictMode>); </React.StrictMode>);
// root.render(<UserContext>
// <App />
// </UserContext>);
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log)) // to log results (for example: reportWebVitals(console.log))

View File

@ -4,7 +4,7 @@ import '../css/pages/Admin.css';
const Admin = () => { const Admin = () => {
return <div className="user-page"> return <div className="user-page">
<h4 className="pageTitle">Admin</h4> <h2 className="pageTitle">Admin</h2>
<div className='card'> <div className='card'>
</div> </div>
</div>; </div>;

View File

@ -4,7 +4,7 @@ import '../css/pages/Empty.css';
const Empty = () => { const Empty = () => {
return <div className="user-page"> return <div className="user-page">
<h4 className="pageTitle">Empty</h4> <h2 className="pageTitle">Empty</h2>
<div className='card'> <div className='card'>
</div> </div>
</div>; </div>;

View File

@ -1,11 +1,17 @@
import React from "react"; import React from "react";
import '../css/pages/Home.css'; import '../css/pages/Home.css';
import { get } from "../util/Util";
const Home = () => { const Home = () => {
return <div className="user-page"> return <div className="user-page">
<h4 className="pageTitle">Home</h4> <h2 className="pageTitle">Home</h2>
<div className='card'> <div className='card'>
<button onClick={async () => {
console.log(await get('/api/test'));
}}>
Test
</button>
</div> </div>
</div>; </div>;
}; };

View File

@ -80,9 +80,18 @@ const ApplicationList = ({ apps }) => {
const Application = ({ app }) => { const Application = ({ app }) => {
const descProps = {defaultValue: app.description, placeholder: 'Describe your application'};
return <div>
<h4>{app.name} ({app.id})</h4>
<b>Description</b>
<textarea {...descProps} >
</textarea>
</div>;
}; };
// TODO: Groups, description, notes
const User = ({ user }) => { const User = ({ user }) => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -90,14 +99,14 @@ const User = ({ user }) => {
useEffect(() => { useEffect(() => {
(async () => { (async () => {
const response = await get(`/api/users/${user._id}/applications`); const response = await get(`/api/users/${user.id}/applications`);
if(response.status === 200) updateApps(response.data); if(response.status === 200) updateApps(response.data);
})(); })();
}, []); }, []);
const ApplicationWrapper = () => { const ApplicationWrapper = () => {
const { appid } = useParams(); const { appid } = useParams();
const app = apps.find(a => a._id === appid); const app = apps.find(a => a.id === appid);
if (!app) return null; if (!app) return null;
return <Application app={app} />; return <Application app={app} />;
}; };
@ -110,25 +119,32 @@ const User = ({ user }) => {
<button className="button primary" onClick={() => { <button className="button primary" onClick={() => {
navigate(-1); navigate(-1);
}}>Back</button> }}>Back</button>
<h3>User {user._id}</h3> <h2>User {user.id}</h2>
</div> </div>
{user.disabled ? <button>Enable</button> : <button>Disable</button>}
<button>Delete</button>
<p><b>Created: </b>{new Date(user.createdTimestamp).toDateString()}</p>
<p><b>2FA: </b>{user.twoFactor.toString()}</p>
<p><b>Disabled: </b>{user.disabled.toString()}</p>
<label htmlFor='username'>Username:</label> <label htmlFor='username'>Username:</label>
<input id='username' defaultValue={user.username} /> <input autoComplete='off' id='username' defaultValue={user.username} />
<label htmlFor='displayName'>Display Name:</label> <label htmlFor='displayName'>Display Name:</label>
<input id='displayName' placeholder='Name to display instead of username' defaultValue={user.displayName} /> <input autoComplete='off' id='displayName' placeholder='Name to display instead of username' defaultValue={user.displayName} />
<select> <select>
<option>User</option> <option>User</option>
<option>Bob</option> <option>Bob</option>
</select> </select>
<h4>Applications</h4> <h3>Applications</h3>
<Routes> <Routes>
<Route path='/' element={<ApplicationList apps={apps} />} /> <Route path='/' element={<ApplicationList apps={apps} />} />
<Route path='/applications/:appid' element={<ApplicationWrapper />} /> <Route path='/applications/:appid' element={<ApplicationWrapper />} />
</Routes> </Routes>
{/* {apps.map(app => <Application key={app._id} app={app} />)} */}
</div> </div>
@ -144,37 +160,21 @@ const User = ({ user }) => {
</div>; </div>;
}; };
// const UserListEntry = ({ user }) => { const CreateUserField = () => {
// const navigate = useNavigate();
// const onClick = () => { const [link, setLink] = useState(null);
// navigate(`/users/${user._id}`); const getSignupCode = async () => {
// }; const response = await get('/api/signup/code');
if(response.status === 200) setLink(response.data);
// return <tr onClick={onClick} style={{cursor: 'pointer'}}> };
// <td>{user.username}</td>
// <td>{user._id}</td>
// </tr>;
// }; return <div className="">
{link ? link : <button onClick={getSignupCode} className="is-center">Create sign-up link</button>}
// // TODO: Make table list generic component {/* TODO: Create form */}
// const UserList = ({ users }) => { </div>;
// return <table className="striped" style={{maxWidth: '30em', marginBottom: '10px'}}>
// <thead>
// <tr>
// <th>Username</th>
// <th>ID</th>
// </tr>
// </thead>
// <tbody>
// {users.map(user => <UserListEntry key={user._id} user={user} />)}
// </tbody>
// </table>;
// }; };
const Users = () => { const Users = () => {
@ -194,47 +194,55 @@ const Users = () => {
const UserWrapper = () => { const UserWrapper = () => {
const { id } = useParams(); const { id } = useParams();
const user = users.find(u => u._id === id); const user = users.find(u => u.id === id);
if (!user) return null; if (!user) return null;
return <User user={user} />; return <User user={user} />;
}; };
const navigate = useNavigate(); const navigate = useNavigate();
const UserListWrapper = () => { const UserListWrapper = () => {
return <div className="user-list-wrapper"> return <div className="user-list-wrapper row">
<div className="col-6">
<Table headerItems={['Username', 'ID']}> <Table headerItems={['Username', 'ID']}>
{users.map(user => <TableListEntry {users.map(user => <TableListEntry
onClick={() => { onClick={() => {
navigate(`/users/${user._id}`); navigate(`/users/${user.id}`);
}} }}
key={user._id} key={user.id}
item={user} item={user}
itemKeys={['username', '_id']} />)} itemKeys={['username', 'id']} />)}
</Table> </Table>
<div className='flex is-vertical-align page-controls'> <div className='flex is-vertical-align is-center page-controls'>
<button className="button dark" onClick={() => setPage(page - 1 || 1)}>Previous</button> <button className="button dark" onClick={() => setPage(page - 1 || 1)}>Previous</button>
<p>Page: {page}</p> <p>Page: {page}</p>
<button className="button dark" onClick={() => { <button className="button dark" onClick={() => {
if (users.length === 10) setPage(page + 1); if (users.length === 10) setPage(page + 1);
}}>Next</button> }}>Next</button>
</div>
</div> </div>
<div className="col-6">
<CreateUserField />
</div>
</div>; </div>;
}; };
return <div className="user-page"> return <div className="user-page">
<h4 className="pageTitle">Users</h4> <h2 className="pageTitle">Users</h2>
{error && <p>{error}</p>} {error && <p>{error}</p>}
<div className='user-list card'> <div className='card'>
<ErrorBoundary> <div className="user-list">
<Routes> <ErrorBoundary>
<Route path='/:id/*' element={<UserWrapper />} /> <Routes>
<Route path='/' element={<UserListWrapper />} /> <Route path='/:id/*' element={<UserWrapper />} />
</Routes> <Route path='/' element={<UserListWrapper />} />
</ErrorBoundary> </Routes>
</ErrorBoundary>
</div>
</div> </div>
</div>; </div>;

View File

@ -57,7 +57,6 @@ export const post = async (url, body) => {
}, },
body: JSON.stringify(body) body: JSON.stringify(body)
}); });
console.log(response);
return parseResponse(response); return parseResponse(response);
}; };