mirror of
https://github.com/QuivrHQ/quivr.git
synced 2024-12-15 09:32:22 +03:00
Minor UX improvments (#717)
* feat: display user rights on invitation page * feat: add brain name in invitation email
This commit is contained in:
parent
d7ca11f5d1
commit
eb779f9e58
@ -1,11 +1,10 @@
|
|||||||
from typing import Optional
|
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
import resend
|
|
||||||
from logger import get_logger
|
from logger import get_logger
|
||||||
from models.settings import BrainSettings, CommonsDep, common_dependencies
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from models.settings import CommonsDep, common_dependencies
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,31 +1,43 @@
|
|||||||
import resend
|
import resend
|
||||||
from logger import get_logger
|
from logger import get_logger
|
||||||
|
from models.brains import Brain
|
||||||
from models.brains_subscription_invitations import BrainSubscription
|
from models.brains_subscription_invitations import BrainSubscription
|
||||||
from models.settings import BrainSettings
|
from models.settings import BrainSettings
|
||||||
|
|
||||||
from repository.brain_subscription.get_brain_url import get_brain_url
|
from repository.brain_subscription.get_brain_url import get_brain_url
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
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
|
brains_settings = BrainSettings() # pyright: ignore reportPrivateUsage=none
|
||||||
resend.api_key = brains_settings.resend_api_key
|
resend.api_key = brains_settings.resend_api_key
|
||||||
|
|
||||||
brain_url = get_brain_url(origin, brain_subscription.brain_id)
|
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"""
|
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>
|
<p><a href='{brain_url}'>Click here</a> to access your brain.</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = resend.Emails.send({
|
r = resend.Emails.send(
|
||||||
|
{
|
||||||
"from": brains_settings.resend_email_address,
|
"from": brains_settings.resend_email_address,
|
||||||
"to": brain_subscription.email,
|
"to": brain_subscription.email,
|
||||||
"subject": "Quivr - Brain Shared With You",
|
"subject": "Quivr - Brain Shared With You",
|
||||||
"html": html_body
|
"html": html_body,
|
||||||
})
|
}
|
||||||
logger.info('Resend response', r)
|
)
|
||||||
|
logger.info("Resend response", r)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error sending email: {e}")
|
logger.error(f"Error sending email: {e}")
|
||||||
return
|
return
|
||||||
|
@ -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",
|
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(
|
@subscription_router.post(
|
||||||
|
@ -6,6 +6,7 @@ import { useParams, useRouter } from "next/navigation";
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
import { useSubscriptionApi } from "@/lib/api/subscription/useSubscriptionApi";
|
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 { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||||
import { useToast } from "@/lib/hooks";
|
import { useToast } from "@/lib/hooks";
|
||||||
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
||||||
@ -16,6 +17,7 @@ export const useInvitation = () => {
|
|||||||
const brainId = params?.brainId as UUID | undefined;
|
const brainId = params?.brainId as UUID | undefined;
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [brainName, setBrainName] = useState<string>("");
|
const [brainName, setBrainName] = useState<string>("");
|
||||||
|
const [rights, setRights] = useState<BrainRoleType | undefined>();
|
||||||
const [isProcessingRequest, setIsProcessingRequest] = useState(false);
|
const [isProcessingRequest, setIsProcessingRequest] = useState(false);
|
||||||
|
|
||||||
const { publish } = useToast();
|
const { publish } = useToast();
|
||||||
@ -35,8 +37,9 @@ export const useInvitation = () => {
|
|||||||
|
|
||||||
const checkInvitationValidity = async () => {
|
const checkInvitationValidity = async () => {
|
||||||
try {
|
try {
|
||||||
const invitationBrain = await getInvitation(brainId);
|
const { name, rights: assignedRights } = await getInvitation(brainId);
|
||||||
setBrainName(invitationBrain.name);
|
setBrainName(name);
|
||||||
|
setRights(assignedRights);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (axios.isAxiosError(error) && error.response?.status === 404) {
|
if (axios.isAxiosError(error) && error.response?.status === 404) {
|
||||||
publish({
|
publish({
|
||||||
@ -126,8 +129,9 @@ export const useInvitation = () => {
|
|||||||
return {
|
return {
|
||||||
handleAccept,
|
handleAccept,
|
||||||
handleDecline,
|
handleDecline,
|
||||||
isLoading,
|
|
||||||
brainName,
|
brainName,
|
||||||
|
rights,
|
||||||
|
isLoading,
|
||||||
isProcessingRequest,
|
isProcessingRequest,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,7 @@ const InvitationPage = (): JSX.Element => {
|
|||||||
handleDecline,
|
handleDecline,
|
||||||
isLoading,
|
isLoading,
|
||||||
brainName,
|
brainName,
|
||||||
|
rights,
|
||||||
} = useInvitation();
|
} = useInvitation();
|
||||||
const { session } = useSupabase();
|
const { session } = useSupabase();
|
||||||
|
|
||||||
@ -26,11 +27,15 @@ const InvitationPage = (): JSX.Element => {
|
|||||||
redirectToLogin();
|
redirectToLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rights === undefined) {
|
||||||
|
throw new Error("Rights are undefined");
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="pt-10">
|
<main className="pt-10">
|
||||||
<PageHeading
|
<PageHeading
|
||||||
title={`Welcome to ${brainName}!`}
|
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 ? (
|
{isProcessingRequest ? (
|
||||||
<div className="flex flex-col items-center justify-center mt-5">
|
<div className="flex flex-col items-center justify-center mt-5">
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { AxiosInstance } from "axios";
|
import { AxiosInstance } from "axios";
|
||||||
import { UUID } from "crypto";
|
import { UUID } from "crypto";
|
||||||
|
|
||||||
|
import { BrainRoleType } from "@/lib/components/NavBar/components/NavItems/components/BrainsDropDown/components/BrainActions/types";
|
||||||
|
|
||||||
export const acceptInvitation = async (
|
export const acceptInvitation = async (
|
||||||
brainId: UUID,
|
brainId: UUID,
|
||||||
axiosInstance: AxiosInstance
|
axiosInstance: AxiosInstance
|
||||||
@ -31,6 +33,7 @@ export const declineInvitation = async (
|
|||||||
|
|
||||||
export type InvitationBrain = {
|
export type InvitationBrain = {
|
||||||
name: string;
|
name: string;
|
||||||
|
rights: BrainRoleType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getInvitation = async (
|
export const getInvitation = async (
|
||||||
|
Loading…
Reference in New Issue
Block a user