Minor UX improvments (#717)

* feat: display user rights on invitation page

* feat: add brain name in invitation email
This commit is contained in:
Mamadou DICKO 2023-07-20 15:15:43 +02:00 committed by GitHub
parent d7ca11f5d1
commit eb779f9e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 18 deletions

View File

@ -1,11 +1,10 @@
from typing import Optional
from uuid import UUID
import resend
from logger import get_logger
from models.settings import BrainSettings, CommonsDep, common_dependencies
from pydantic import BaseModel
from models.settings import CommonsDep, common_dependencies
logger = get_logger(__name__)
@ -64,4 +63,4 @@ class BrainSubscription(BaseModel):
else:
response = self.create_subscription_invitation()
return response
return response

View File

@ -1,31 +1,43 @@
import resend
from logger import get_logger
from models.brains import Brain
from models.brains_subscription_invitations import BrainSubscription
from models.settings import BrainSettings
from repository.brain_subscription.get_brain_url import get_brain_url
logger = get_logger(__name__)
def resend_invitation_email(brain_subscription: BrainSubscription, inviter_email: str, origin: str = "https://www.quivr.app"):
def resend_invitation_email(
brain_subscription: BrainSubscription,
inviter_email: str,
origin: str = "https://www.quivr.app",
):
brains_settings = BrainSettings() # pyright: ignore reportPrivateUsage=none
resend.api_key = brains_settings.resend_api_key
brain_url = get_brain_url(origin, brain_subscription.brain_id)
invitation_brain_client = Brain(id=brain_subscription.brain_id)
invitation_brain = invitation_brain_client.get_brain_details()[0]
brain_name = invitation_brain["name"]
html_body = f"""
<p>This brain has been shared with you by {inviter_email}.</p>
<p>Brain {brain_name} has been shared with you by {inviter_email}.</p>
<p><a href='{brain_url}'>Click here</a> to access your brain.</p>
"""
try:
r = resend.Emails.send({
"from": brains_settings.resend_email_address,
"to": brain_subscription.email,
"subject": "Quivr - Brain Shared With You",
"html": html_body
})
logger.info('Resend response', r)
r = resend.Emails.send(
{
"from": brains_settings.resend_email_address,
"to": brain_subscription.email,
"subject": "Quivr - Brain Shared With You",
"html": html_body,
}
)
logger.info("Resend response", r)
except Exception as e:
logger.error(f"Error sending email: {e}")
return

View File

@ -179,7 +179,7 @@ def get_user_invitation(brain_id: UUID, current_user: User = Depends(get_current
detail="Brain not found while trying to get invitation",
)
return {"name": brain_details[0]["name"]}
return {"name": brain_details[0]["name"], "rights": invitation["rights"]}
@subscription_router.post(

View File

@ -6,6 +6,7 @@ import { useParams, useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useSubscriptionApi } from "@/lib/api/subscription/useSubscriptionApi";
import { BrainRoleType } from "@/lib/components/NavBar/components/NavItems/components/BrainsDropDown/components/BrainActions/types";
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { useToast } from "@/lib/hooks";
import { useEventTracking } from "@/services/analytics/useEventTracking";
@ -16,6 +17,7 @@ export const useInvitation = () => {
const brainId = params?.brainId as UUID | undefined;
const [isLoading, setIsLoading] = useState(false);
const [brainName, setBrainName] = useState<string>("");
const [rights, setRights] = useState<BrainRoleType | undefined>();
const [isProcessingRequest, setIsProcessingRequest] = useState(false);
const { publish } = useToast();
@ -35,8 +37,9 @@ export const useInvitation = () => {
const checkInvitationValidity = async () => {
try {
const invitationBrain = await getInvitation(brainId);
setBrainName(invitationBrain.name);
const { name, rights: assignedRights } = await getInvitation(brainId);
setBrainName(name);
setRights(assignedRights);
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 404) {
publish({
@ -126,8 +129,9 @@ export const useInvitation = () => {
return {
handleAccept,
handleDecline,
isLoading,
brainName,
rights,
isLoading,
isProcessingRequest,
};
};

View File

@ -15,6 +15,7 @@ const InvitationPage = (): JSX.Element => {
handleDecline,
isLoading,
brainName,
rights,
} = useInvitation();
const { session } = useSupabase();
@ -26,11 +27,15 @@ const InvitationPage = (): JSX.Element => {
redirectToLogin();
}
if (rights === undefined) {
throw new Error("Rights are undefined");
}
return (
<main className="pt-10">
<PageHeading
title={`Welcome to ${brainName}!`}
subtitle="You have been invited to join this brain and start exploring. Do you accept this exciting journey?"
subtitle={`You have been invited to join this brain as a ${rights} and start exploring. Do you accept this exciting journey?`}
/>
{isProcessingRequest ? (
<div className="flex flex-col items-center justify-center mt-5">

View File

@ -1,6 +1,8 @@
import { AxiosInstance } from "axios";
import { UUID } from "crypto";
import { BrainRoleType } from "@/lib/components/NavBar/components/NavItems/components/BrainsDropDown/components/BrainActions/types";
export const acceptInvitation = async (
brainId: UUID,
axiosInstance: AxiosInstance
@ -31,6 +33,7 @@ export const declineInvitation = async (
export type InvitationBrain = {
name: string;
rights: BrainRoleType;
};
export const getInvitation = async (