From 40d5d9da4a1eb889e7bcfc0d9a0f4ca4d512e8f1 Mon Sep 17 00:00:00 2001 From: "Navy.gif" Date: Fri, 9 Dec 2022 18:11:49 +0200 Subject: [PATCH] bunch of bullshit --- src/App.js | 104 +++++++++--------- src/components/FileSelector.js | 36 +++++++ src/components/Table.js | 1 + src/css/index.css | 4 + src/pages/Admin.js | 29 ++++- src/pages/Home.js | 185 +------------------------------- src/pages/Users.js | 4 +- src/pages/home/Applications.js | 102 ++++++++++++++++++ src/pages/home/Profile.js | 187 +++++++++++++++++++++++++++++++++ src/util/Util.js | 20 ++++ 10 files changed, 438 insertions(+), 234 deletions(-) create mode 100644 src/components/FileSelector.js create mode 100644 src/pages/home/Applications.js create mode 100644 src/pages/home/Profile.js diff --git a/src/App.js b/src/App.js index 494539e..72a2d5e 100644 --- a/src/App.js +++ b/src/App.js @@ -39,7 +39,12 @@ function App() { }, []); const menuItems = [ - { to: '/home', label: 'Home', items: [{ to: '/profile', label: 'Profile', relative: true }] }, + { + to: '/home', label: 'Home', items: [ + { to: '/profile', label: 'Profile', relative: true }, + { to: '/applications', label: 'Applications', relative: true } + ] + }, { to: '/users', label: 'Users' }, { to: '/admin', label: 'Admin' } ]; @@ -51,55 +56,58 @@ function App() {
- {user ? -
-
- -
- - - -
- : null} - -
- - - - - - - - } /> - - - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - } /> - - - - -
-

Made with ❤️ by Navy.gif  |  CSS by D3vision

-
+ {user ? +
+
+ +
+ + +
+ : null} +
+ + + + + + + + + + } /> + + + + + + } /> + + + + + + } /> + + + + } /> + + + + } /> + + } /> + + + + +
+

Made with ❤️ by Navy.gif  |  CSS by D3vision

+
+
diff --git a/src/components/FileSelector.js b/src/components/FileSelector.js new file mode 100644 index 0000000..6b692ec --- /dev/null +++ b/src/components/FileSelector.js @@ -0,0 +1,36 @@ +import React, { useState } from "react"; + +const FileSelector = ({cb}) => { + + if (!cb) throw new Error('Missing callback'); + const [file, setFile] = useState(null); + + const onDragOver = (event) => { + event.stopPropagation(); + event.preventDefault(); + }; + + const onDrop = (event) => { + event.preventDefault(); + const { dataTransfer } = event; + if (!dataTransfer.files.length) return; + + const [file] = dataTransfer.files; + setFile(file); + cb(file); + }; + + return ; +}; + +export default FileSelector; \ No newline at end of file diff --git a/src/components/Table.js b/src/components/Table.js index dd9ceea..2fbe722 100644 --- a/src/components/Table.js +++ b/src/components/Table.js @@ -9,6 +9,7 @@ export const TableListEntry = ({onClick, item, itemKeys}) => { export const Table = ({headerItems, children, items, itemKeys}) => { + if (!headerItems) throw new Error(`Missing table headers`); let i = 0; return diff --git a/src/css/index.css b/src/css/index.css index 5230c24..f7523f0 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -18,6 +18,10 @@ --font-family-mono: monaco, "Consolas", "Lucida Console", monospace; } +textarea { + resize: none; +} + .w-100{ width: 100% !important; } diff --git a/src/pages/Admin.js b/src/pages/Admin.js index 1dae121..483e806 100644 --- a/src/pages/Admin.js +++ b/src/pages/Admin.js @@ -1,12 +1,33 @@ -import React from "react"; +import React, { useRef, useState } from "react"; +import FileSelector from "../components/FileSelector"; import '../css/pages/Admin.css'; const Admin = () => { - return
-

Admin

-
+ const [file, setFile] = useState(null); + + const submit = (event) => { + event.preventDefault(); + console.log(file); + }; + + return
+ +
+

Thematic customisation

+
+ + + + +
+ +
+

Dingus

+ +
+
; }; diff --git a/src/pages/Home.js b/src/pages/Home.js index 1fe1182..7cda0bf 100644 --- a/src/pages/Home.js +++ b/src/pages/Home.js @@ -1,190 +1,14 @@ -import React, { useRef, useState } from "react"; +import React from "react"; import { Route, Routes } from "react-router"; import '../css/pages/Home.css'; -import { useLoginContext } from "../structures/UserContext"; import ErrorBoundary from "../util/ErrorBoundary"; -import { capitalise, get, post } from "../util/Util"; - -const TwoFactorControls = ({ user }) => { - - const [twoFactorError, set2FAError] = useState(null); - const [displayInput, setDisplayInput] = useState(false); - - const [qr, setQr] = useState(null); - const displayQr = async () => { - const response = await get('/api/user/2fa'); - if (response.status !== 200) return set2FAError(response.message); - setQr(response.message); - }; - - const codeRef = useRef(); - const disable2FA = async (event) => { - event.preventDefault(); - const code = codeRef.current.value; - if (!code) return; - const response = await post('/api/user/2fa/disable', { code }); - if (response.status !== 200) return set2FAError(response.message); - }; - - const submitCode = async (event) => { - event.preventDefault(); - const code = codeRef.current.value; - if (!code) return; - const response = await post('/api/user/2fa/verify', { code }); - if (response.status !== 200) return set2FAError(response.message); - }; - - let inner =
- {qr ? -
- -
- - - -
: - } -
; - - - if (user.twoFactor) inner =
- {displayInput ? -
- - - - : } -
; - - return
- {twoFactorError &&

{twoFactorError}

} - {inner} -
; - -}; - -const ExternalProfile = ({ profile }) => { - return
- {capitalise(profile.provider)} -

Username: {profile.username}

-

ID: {profile.id}

-
; -}; - -const ThirdPartyConnections = ({user}) => { - - const {externalProfiles} = user; - - return
- {externalProfiles.map(profile => )} -
; - -}; - -const Profile = () => { - - const [user] = useLoginContext(); - const [file, setFile] = useState(null); - const fileSelector = useRef(); - const [fileName, setFileName] = useState(null); - const [error, setError] = useState(null); - - // For some reason this has to be done for onDrop to work - const onDragOver = (event) => { - event.stopPropagation(); - event.preventDefault(); - }; - - const onDrop = (event) => { - event.preventDefault(); - const { dataTransfer } = event; - if (!dataTransfer.files.length) return; - - const [file] = dataTransfer.files; - console.log(file.name); - setFileName(`Selected: ${file.name}`); - setFile(file); - }; - - const fileGarbage = (event) => { - setFile(event.target.files[0]); - setFileName(`Selected: ${event.target.files[0].name}`); - }; - - const submit = async ({target: button}) => { - button.disabled = true; - if (!file) return; - - const body = new FormData(); - body.set('file', file, file.name); - // body.set('name', file.name); - - const response = await post('/api/user/avatar', body, { headers: null }); - if (!response.success) setError(response.message); - else fileSelector.current.value = null; - button.disabled = false; - }; - - return
- -
-

Profile

-
-
-

Profile Picture

- -
-
-

Change Profile Picture

-
- - - -
-
-

Third party connections

- - -
- -
-

Settings

- -

ID: {user.id}

- -
- - - - - - - - - - - - - - -

Two Factor: {user.twoFactor ? 'enabled' : 'disabled'}

- - -
-
; -}; +import Applications from "./home/Applications"; +import Profile from "./home/Profile"; const Main = () => { return
- + What to put here? hmmm
; }; @@ -194,6 +18,7 @@ const Home = () => { } /> } /> + } /> ; }; diff --git a/src/pages/Users.js b/src/pages/Users.js index 29b350b..cd0c8d0 100644 --- a/src/pages/Users.js +++ b/src/pages/Users.js @@ -68,7 +68,7 @@ const ApplicationList = ({ apps }) => { return
{apps.map(app => { - navigate(`${window.location.pathname}/applications/${app.id}`); + navigate(`applications/${app.id}`); }} key={app.id} item={app} @@ -219,7 +219,7 @@ const Users = () => { const UserWrapper = () => { const { id } = useParams(); const user = users.find(u => u.id === id); - if (!user) return null; + if (!user) return

Unknown user

; return ; }; diff --git a/src/pages/home/Applications.js b/src/pages/home/Applications.js new file mode 100644 index 0000000..b55ae76 --- /dev/null +++ b/src/pages/home/Applications.js @@ -0,0 +1,102 @@ +import React, { useEffect, useRef, useState } from "react"; +import { Route, Routes, useNavigate, useParams } from "react-router"; +import { Table, TableListEntry } from "../../components/Table"; +import ErrorBoundary from "../../util/ErrorBoundary"; +import { post, get, del } from "../../util/Util"; + +const Application = ({ app }) => { + + const navigate = useNavigate(); + + const deleteApp = async () => { + const response = await del(`/api/user/applications/${app.id}`); + }; + + return
+ +

{app.name}

+

{app.description}

+

{app.token}

+ +
; + +}; + +const Applications = () => { + + const [applications, setApplications] = useState([]); + const [loading, setLoading] = useState(true); + const navigate = useNavigate(); + + useEffect(() => { + (async () => { + const response = await get('/api/user/applications'); + if (response.status === 200) setApplications(response.data); + setLoading(false); + })(); + }, []); + + const descField = useRef(); + const nameField = useRef(); + const [error, setError] = useState(null); + + const createApp = async (event) => { + event.preventDefault(); + const button = event.target; + + const name = nameField.current.value; + if(!name) return setError('Missing name'); + const description = descField.current.value; + nameField.current.value = ''; + descField.current.value = ''; + button.disabled = true; + const response = await post('/api/user/applications', { name, description }); + if (response.status !== 200) setError(response.message); + else setApplications((apps) => [...apps, response.data]); + + button.disabled = false; + }; + + const Main = () => { + return
+ +
+

Applications

+
+ {applications.map(application => navigate(application.id)} + item={application} + itemKeys={['name', 'id']} + />)} +
+
+ +
+

Create Application

+ {error &&

{error}

} +
+ +