Skip to content

Commit 25b1c0c

Browse files
committed
feat: added email and name sharing with url injection in profile
1 parent b28980d commit 25b1c0c

File tree

4 files changed

+103
-16
lines changed

4 files changed

+103
-16
lines changed

src/app/routes/_app.subject.$id/route.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import { ActivityListSearch } from './components/activity-list-search';
4343
import { EvidenceListSearch } from './components/evidence-list-search';
4444
import SubjectProfileHeader from './components/header';
4545
import ProfileTabs from './components/profile-tabs';
46+
import { useGetGravatarProfileByHashedEmailQuery } from '@/store/api/profile';
47+
import { skipToken } from '@reduxjs/toolkit/query';
4648

4749
const connectionLevelPriority: {
4850
[key in ConnectionLevel | 'aura only']: number;
@@ -72,6 +74,12 @@ export const SubjectProfileBody = ({ subjectId }: { subjectId: string }) => {
7274
const [credibilityDetailsProps, setCredibilityDetailsProps] =
7375
useState<CredibilityDetailsProps | null>(null);
7476

77+
const name = useMemo(() => query.get('name'), [query]);
78+
79+
const profilePhotoFetch = useGetGravatarProfileByHashedEmailQuery(
80+
query.has('gravatar') ? query.get('gravatar')! : skipToken,
81+
);
82+
7583
const {
7684
currentViewMode,
7785
currentEvaluationCategory,
@@ -217,6 +225,8 @@ export const SubjectProfileBody = ({ subjectId }: { subjectId: string }) => {
217225
subjectId={subjectId}
218226
setShowEvaluationFlow={setShowEvaluationFlow}
219227
setSelectedTab={setSelectedTab}
228+
injectedProfileImage={profilePhotoFetch.data?.avatar_url}
229+
injectedProfileName={name}
220230
/>
221231

222232
<Modal
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { HoverCard, HoverCardContent, HoverCardTrigger } from './ui/hover-card';
2+
3+
const GravatarProfilePicture = ({
4+
image,
5+
withoutHover = false,
6+
...props
7+
}: React.HTMLAttributes<HTMLImageElement> & {
8+
image: string | undefined;
9+
withoutHover?: boolean;
10+
}) => {
11+
if (withoutHover)
12+
return (
13+
<img
14+
{...props}
15+
className={`${props.className ?? ''} object-cover`}
16+
src={image || '/placeholder.svg'}
17+
/>
18+
);
19+
20+
return (
21+
<HoverCard openDelay={100}>
22+
<HoverCardTrigger asChild>
23+
<img
24+
{...props}
25+
className={`${props.className ?? ''} object-cover transition-transform duration-200 hover:scale-105`}
26+
src={image || '/placeholder.svg'}
27+
/>
28+
</HoverCardTrigger>
29+
<HoverCardContent className="w-auto p-1">
30+
<img
31+
src={image}
32+
className="h-auto max-h-[300px] w-auto max-w-[300px] rounded-md object-cover"
33+
/>
34+
</HoverCardContent>
35+
</HoverCard>
36+
);
37+
};
38+
39+
export default GravatarProfilePicture;

src/components/Shared/ProfileInfo/index.tsx

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useSubjectName } from 'hooks/useSubjectName';
99
import { useSubjectVerifications } from 'hooks/useSubjectVerifications';
1010
import useViewMode from 'hooks/useViewMode';
1111
import moment from 'moment';
12-
import { useContext, useMemo } from 'react';
12+
import { FC, useContext, useMemo } from 'react';
1313
import { useSelector } from 'react-redux';
1414
import { selectAuthData } from 'store/profile/selectors';
1515
import { EvaluationCategory, ProfileTab } from 'types/dashboard';
@@ -21,17 +21,24 @@ import BrightIdProfilePicture from '../../BrightIdProfilePicture';
2121
import { YourEvaluationInfo } from '../EvaluationInfo/YourEvaluationInfo';
2222
import { HorizontalProgressBar } from '../HorizontalProgressBar';
2323
import NewEvaluationCard from '@/app/routes/_app.subject.$id/components/new-evaluation-card';
24+
import GravatarProfilePicture from '@/components/GravatarPoriflePicture';
2425

25-
export const ProfileInfo = ({
26-
isPerformance = false,
27-
subjectId,
28-
setShowEvaluationFlow,
29-
setSelectedTab,
30-
}: {
26+
export interface ProfileInfoProps {
27+
injectedProfileImage?: string;
3128
isPerformance?: boolean;
3229
subjectId: string;
3330
setShowEvaluationFlow: (value: boolean) => void;
3431
setSelectedTab?: (value: ProfileTab) => void;
32+
injectedProfileName?: string | null;
33+
}
34+
35+
export const ProfileInfo: FC<ProfileInfoProps> = ({
36+
isPerformance = false,
37+
subjectId,
38+
setShowEvaluationFlow,
39+
setSelectedTab,
40+
injectedProfileImage,
41+
injectedProfileName,
3542
}) => {
3643
const { currentViewMode, currentEvaluationCategory, updateViewAs } =
3744
useViewMode();
@@ -87,15 +94,33 @@ export const ProfileInfo = ({
8794
<div className="card flex flex-col gap-3 border dark:bg-dark-primary">
8895
<div className="card--header flex w-full items-center justify-between">
8996
<div className="card--header__left flex gap-4">
90-
<BrightIdProfilePicture
91-
key={subjectId}
92-
className={`card--header__left__avatar rounded-full border-[3px] ${getViewModeSubjectBorderColorClass(
93-
currentViewMode,
94-
)} h-[51px] w-[51px]`}
95-
subjectId={subjectId}
96-
/>
97+
{injectedProfileImage ? (
98+
<GravatarProfilePicture
99+
key={injectedProfileImage}
100+
image={injectedProfileImage}
101+
className={`card--header__left__avatar rounded-full border-[3px] ${getViewModeSubjectBorderColorClass(
102+
currentViewMode,
103+
)} h-[51px] w-[51px]`}
104+
/>
105+
) : (
106+
<BrightIdProfilePicture
107+
key={subjectId}
108+
className={`card--header__left__avatar rounded-full border-[3px] ${getViewModeSubjectBorderColorClass(
109+
currentViewMode,
110+
)} h-[51px] w-[51px]`}
111+
subjectId={subjectId}
112+
/>
113+
)}
97114
<div className="card--header__left__info flex flex-col justify-center">
98-
<h3 className="truncate text-lg font-medium leading-5">{name}</h3>
115+
<h3 className="truncate text-lg font-medium leading-5">
116+
{injectedProfileName ? (
117+
<span>
118+
{injectedProfileName} <small>({name})</small>
119+
</span>
120+
) : (
121+
name
122+
)}
123+
</h3>
99124
<div className="flex gap-1">
100125
<span className="text-sm">
101126
Level: <strong>{auraLevel}</strong>

src/store/api/profile.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ export const profileApi = apiSlice.injectEndpoints({
1111
providesTags: (res) =>
1212
res?.id ? [{ type: 'BrightID' as const, id: res.id }] : [],
1313
}),
14-
14+
getGravatarProfileByHashedEmail: build.query<
15+
{
16+
display_name: string;
17+
profile_url: string;
18+
avatar_url: string;
19+
},
20+
string
21+
>({
22+
query: (hashedEmail) => ({
23+
url: `https://api.gravatar.com/v3/profiles/${hashedEmail}`,
24+
method: 'GET',
25+
}),
26+
}),
1527
getConnections: build.query<
1628
ConnectionInfo[],
1729
{ id: string; direction: 'inbound' | 'outbound' }
@@ -29,4 +41,5 @@ export const {
2941
useGetConnectionsQuery,
3042
useGetBrightIDProfileQuery,
3143
useLazyGetBrightIDProfileQuery,
44+
useGetGravatarProfileByHashedEmailQuery,
3245
} = profileApi;

0 commit comments

Comments
 (0)