Implemented basic user management

Smaller refactorings
This commit is contained in:
grimsi
2024-09-15 13:47:36 +02:00
parent 110eb3dd5a
commit 791fd71795
10 changed files with 217 additions and 124 deletions
@@ -1,8 +1,8 @@
import Section from "Frontend/components/general/Section";
import Input from "Frontend/components/general/Input";
import {Avatar, Button, Input as NextUiInput, Tooltip} from "@nextui-org/react";
import {Form, Formik} from "formik";
import {Avatar, Button} from "@nextui-org/react";
import {Check, Info} from "@phosphor-icons/react";
import {Check, Info, Trash} from "@phosphor-icons/react";
import React, {useEffect, useState} from "react";
import {useAuth} from "Frontend/util/auth";
import * as Yup from "yup";
@@ -10,11 +10,12 @@ import UserUpdateDto from "Frontend/generated/de/grimsi/gameyfin/users/dto/UserU
import {UserEndpoint} from "Frontend/generated/endpoints";
import {SmallInfoField} from "Frontend/components/general/SmallInfoField";
import {toast} from "sonner";
import AvatarUpload from "Frontend/components/general/AvatarUpload";
import {removeAvatar, uploadAvatar} from "Frontend/endpoints/AvatarEndpoint";
export default function ProfileManagement() {
const [configSaved, setConfigSaved] = useState(false);
const auth = useAuth();
const [avatar, setAvatar] = useState<any>();
useEffect(() => {
if (configSaved) {
@@ -22,6 +23,11 @@ export default function ProfileManagement() {
}
}, [configSaved])
function onFileSelected(event: any) {
setAvatar(event.target.files[0]);
}
async function handleSubmit(values: any) {
const userUpdate: UserUpdateDto = {
username: values.username,
@@ -91,11 +97,21 @@ export default function ProfileManagement() {
</div>
<div className="flex flex-row flex-1 justify-between gap-16">
<div className="flex flex-col basis-1/4 mt-8 items-center">
<Avatar showFallback
src={`/images/avatar?username=${auth.state.user?.username}`}
className="size-40 m-4"></Avatar>
<AvatarUpload upload="/avatar/upload" remove="/avatar/delete" accept="image/*"/>
<div className="flex flex-col basis-1/4 mt-8 gap-4">
<div className="flex flex-row justify-center">
<Avatar showFallback
src={`/images/avatar?username=${auth.state.user?.username}`}
className="size-40 m-4 flex flex-row">
</Avatar>
</div>
<div className="flex flex-row gap-2">
<NextUiInput type="file" accept="image/*" onChange={onFileSelected}/>
<Button onClick={() => uploadAvatar(avatar)} isDisabled={avatar == null}
color="success">Upload</Button>
<Tooltip content="Remove your current avatar">
<Button onClick={removeAvatar} isIconOnly color="danger"><Trash/></Button>
</Tooltip>
</div>
</div>
<div className="flex flex-col flex-grow">
@@ -2,10 +2,9 @@ import React, {useEffect, useState} from "react";
import ConfigFormField from "Frontend/components/administration/ConfigFormField";
import withConfigPage from "Frontend/components/administration/withConfigPage";
import Section from "Frontend/components/general/Section";
import * as Yup from "yup";
import {UserEndpoint} from "Frontend/generated/endpoints";
import UserInfoDto from "Frontend/generated/de/grimsi/gameyfin/users/dto/UserInfoDto";
import {UserCard} from "Frontend/components/general/UserCard";
import {UserManagementCard} from "Frontend/components/general/UserManagementCard";
function UserManagementLayout({getConfig, formik}: any) {
const [users, setUsers] = useState<UserInfoDto[]>([]);
@@ -28,23 +27,11 @@ function UserManagementLayout({getConfig, formik}: any) {
<Section title="Users"/>
<div className="grid grid-cols-300px gap-4">
{users.map((user) => <UserCard user={user} key={user.username}/>)}
{users.map((user) => <UserManagementCard user={user} key={user.username}/>)}
</div>
</div>
)
;
}
const validationSchema = Yup.object({
library: Yup.object({
metadata: Yup.object({
update: Yup.object({
// @ts-ignore
schedule: Yup.string().cron()
})
})
})
});
export const UserManagement = withConfigPage(UserManagementLayout, "User Management", "users", validationSchema);
export const UserManagement = withConfigPage(UserManagementLayout, "User Management", "users");