mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Fix #635
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
import {Card, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, useDisclosure} from "@heroui/react";
|
import {Card, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, useDisclosure} from "@heroui/react";
|
||||||
import {DotsThreeVertical} from "@phosphor-icons/react";
|
import {DotsThreeVertical} from "@phosphor-icons/react";
|
||||||
import {useAuth} from "Frontend/util/auth";
|
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {MessageEndpoint, PasswordResetEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
|
import {MessageEndpoint, PasswordResetEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
|
||||||
import {AvatarEndpoint} from "Frontend/endpoints/endpoints";
|
import {AvatarEndpoint} from "Frontend/endpoints/endpoints";
|
||||||
@@ -20,7 +19,6 @@ export function UserManagementCard({user}: { user: UserInfoDto }) {
|
|||||||
const [disabledKeys, setDisabledKeys] = useState<string[]>([]);
|
const [disabledKeys, setDisabledKeys] = useState<string[]>([]);
|
||||||
const [dropdownItems, setDropdownItems] = useState<any[]>([]);
|
const [dropdownItems, setDropdownItems] = useState<any[]>([]);
|
||||||
const [passwordResetToken, setPasswordResetToken] = useState<TokenDto>();
|
const [passwordResetToken, setPasswordResetToken] = useState<TokenDto>();
|
||||||
const auth = useAuth();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setUserEnabled(user.enabled);
|
setUserEnabled(user.enabled);
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React, {useEffect, useState} from "react";
|
||||||
import {addToast, Button, Input, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
|
import {addToast, Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader, Snippet} from "@heroui/react";
|
||||||
import {RegistrationEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
|
import {MessageEndpoint, RegistrationEndpoint, UserEndpoint} from "Frontend/generated/endpoints";
|
||||||
|
import TokenDto from "Frontend/generated/org/gameyfin/app/shared/token/TokenDto";
|
||||||
|
import {Form, Formik, FormikErrors} from "formik";
|
||||||
|
import Input from "Frontend/components/general/input/Input";
|
||||||
|
import * as Yup from "yup";
|
||||||
|
|
||||||
interface InviteUserModalProps {
|
interface InviteUserModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -8,23 +12,30 @@ interface InviteUserModalProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function InviteUserModal({isOpen, onOpenChange}: InviteUserModalProps) {
|
export default function InviteUserModal({isOpen, onOpenChange}: InviteUserModalProps) {
|
||||||
const [email, setEmail] = useState<string | null>();
|
const [token, setToken] = useState<TokenDto | null>(null);
|
||||||
const [error, setError] = useState<string | null>();
|
const [isMessageServiceEnabled, setIsMessageServiceEnabled] = useState<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setEmail(null);
|
setToken(null);
|
||||||
setError(null);
|
MessageEndpoint.isEnabled().then(enabled => {
|
||||||
}, []);
|
setIsMessageServiceEnabled(enabled);
|
||||||
|
});
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
async function inviteUser(onClose: () => void) {
|
async function inviteUser(email: string, setErrors: (errors: FormikErrors<any>) => void, onClose: () => void) {
|
||||||
if (!email) return;
|
if (!email) return;
|
||||||
|
|
||||||
if (await UserEndpoint.existsByMail(email)) {
|
if (await UserEndpoint.existsByMail(email)) {
|
||||||
setError("User with this email already exists");
|
setErrors({email: "User with this email already exists"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMessageServiceEnabled) {
|
||||||
|
let token = await RegistrationEndpoint.createInvitation(email);
|
||||||
|
setToken(token);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
await RegistrationEndpoint.createInvitation(email);
|
await RegistrationEndpoint.createInvitation(email);
|
||||||
addToast({
|
addToast({
|
||||||
title: "Invitation sent",
|
title: "Invitation sent",
|
||||||
@@ -32,32 +43,57 @@ export default function InviteUserModal({isOpen, onOpenChange}: InviteUserModalP
|
|||||||
color: "success"
|
color: "success"
|
||||||
});
|
});
|
||||||
onClose();
|
onClose();
|
||||||
} catch (e) {
|
|
||||||
setError("Failed to create invitation");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange} backdrop="opaque" size="lg">
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange} backdrop="opaque" size="4xl">
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
{(onClose) => (
|
{(onClose) => (
|
||||||
<>
|
<Formik
|
||||||
|
initialValues={{email: ""}}
|
||||||
|
isInitialValid={false}
|
||||||
|
validationSchema={Yup.object({
|
||||||
|
email: Yup.string()
|
||||||
|
.email("Invalid email address")
|
||||||
|
.required("Email is required")
|
||||||
|
})}
|
||||||
|
onSubmit={async (values: any, {setErrors}) => {
|
||||||
|
await inviteUser(values.email, setErrors, onClose);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(formik) => (
|
||||||
|
<Form>
|
||||||
<ModalHeader className="flex flex-col gap-1">Invite a new user</ModalHeader>
|
<ModalHeader className="flex flex-col gap-1">Invite a new user</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<p>Enter the email address of the user you want to invite:</p>
|
<p>Enter the email address of the user you want to invite:</p>
|
||||||
<Input errorMessage={error} onChange={(e) => setEmail(e.target.value)} type="email"/>
|
<Input label="E-Mail" name="email" type="email"/>
|
||||||
{error && <small className="text-danger">{error}</small>}
|
|
||||||
|
{token && (
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<p>The user can accept the invitation using the following link:</p>
|
||||||
|
<Snippet symbol="">
|
||||||
|
{`${document.baseURI}accept-invitation?token=${token.secret}`}
|
||||||
|
</Snippet>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
<Button variant="light" onPress={onClose}>
|
<Button variant="light" onPress={onClose}>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button color="success" onPress={() => inviteUser(onClose)}
|
<Button color="success"
|
||||||
isDisabled={email === null || email === undefined || email.length < 1}>
|
type="submit"
|
||||||
Send invitation
|
isLoading={formik.isSubmitting}
|
||||||
|
isDisabled={!formik.isValid || token !== null}>
|
||||||
|
{isMessageServiceEnabled ?
|
||||||
|
<p>Send invitation</p> :
|
||||||
|
<p>Generate invitation link</p>
|
||||||
|
}
|
||||||
</Button>
|
</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</>
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
)}
|
)}
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
Reference in New Issue
Block a user