Skip to content

Commit

Permalink
Merge pull request #1785 from ResearchHub/profile-page-changes
Browse files Browse the repository at this point in the history
[Profile] Rewards related changes
  • Loading branch information
yattias authored Jul 28, 2024
2 parents 979cac6 + 84ad723 commit 976a8a2
Show file tree
Hide file tree
Showing 9 changed files with 309 additions and 83 deletions.
1 change: 1 addition & 0 deletions components/Author/Profile/AuthorHeaderExpertise.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const AuthorHeaderExpertise = ({ profile }: { profile: FullAuthorProfile }) => {
{profile.reputationList.slice(0, REP_GAUGES_TO_SHOW).map((rep, index) => (
<div className={css(styles.reputation)}>
<div className={css(styles.reputationHubLabel)}>{rep.hub.name}</div>
{/* {rep.percentile} */}
<ReputationGauge reputation={rep} key={`reputation-` + index} />
</div>
))}
Expand Down
38 changes: 33 additions & 5 deletions components/Author/Profile/AuthorProfileHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,25 @@ const AuthorProfileHeader = () => {
<Avatar src={profile.profileImage} sx={{ width: 128, height: 128, fontSize: 48 }}>
{isEmpty(profile.profileImage) && profile.firstName?.[0] + profile.lastName?.[0]}
</Avatar>
<div>
<div className={css(styles.lineItems)}>
<div className={css(styles.name)}>{profile.firstName} {profile.lastName}</div>
<div className={css(styles.headline)}>{profile.headline}</div>
<div className={css(styles.inlineLineItem)}>
<div className={css(styles.label)}>Education:</div>
{profile.education.map((edu, index) => (
<div>{edu.summary} {index < profile.education.length ? "" : ", "}</div>
))}
</div>

<div className={css(styles.institutions)}>
{/* Kobe 07-27-24: Temporarily disabling rendering of new institutions */}
{/* <div className={css(styles.institutions)}>
<AuthorInstitutions institutions={profile.institutions} />
</div>
</div> */}

<div>{profile.description}</div>
<div className={css(styles.inlineLineItem)}>
<div className={css(styles.label)}>About:</div>
<div className={css(styles.description)}>{profile.description}</div>
</div>

<div className={css(styles.authorSocialMedia)}>
<AuthorSocialMediaIcons profile={profile} />
Expand Down Expand Up @@ -128,6 +138,22 @@ const AuthorProfileHeader = () => {
)
}
const styles = StyleSheet.create({
lineItems: {
display: "flex",
flexDirection: "column",
gap: 4,
},
inlineLineItem: {
display: "flex",
columnGap: "5px",
color: colors.BLACK(0.9),
},
label: {
fontWeight: 500,
color: colors.BLACK(1.0),
},
description: {
},
textBtn: {
cursor: "pointer",
color: colors.NEW_BLUE(),
Expand Down Expand Up @@ -185,7 +211,9 @@ const styles = StyleSheet.create({
marginTop: 10,
},
headline: {
marginTop: 10,
fontSize: 18,
marginBottom: 10,
color: colors.BLACK(0.9),
},
institutions: {
marginTop: 10,
Expand Down
129 changes: 62 additions & 67 deletions components/Author/Profile/AuthorPublications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from "~/components/Notifications/lib/types";
import { authorProfileContext } from "../lib/AuthorProfileContext";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlus } from "@fortawesome/pro-light-svg-icons";
import { faPlus, faTrash } from "@fortawesome/pro-light-svg-icons";
import {
RESEARCHHUB_POST_DOCUMENT_TYPES,
getFEUnifiedDocType,
Expand All @@ -36,11 +36,14 @@ import {
parseGenericDocument,
parsePaper,
} from "~/components/Document/lib/types";
import { Button as Btn, IconButton } from "@mui/material";
import ResearchCoinIcon from "~/components/Icons/ResearchCoinIcon";
import colors from "~/config/themes/colors";
import MoreHoriz from "@mui/icons-material/MoreHoriz";
import ClaimRewardsModal from "~/components/ResearchCoin/ClaimRewardsModal";
import ClaimRewardsButton from "~/components/shared/ClaimRewardsButton";
import { getRewardsEligibilityInfo } from "~/components/ResearchCoin/lib/rewardsUtil";
import GenericMenu, { MenuOption } from "~/components/shared/GenericMenu";
import IconButton from "~/components/Icons/IconButton";
import { faEllipsis } from "@fortawesome/pro-solid-svg-icons";
import colors from "~/config/themes/colors";

const AuthorPublications = ({
initialPaginatedPublicationsResponse,
Expand Down Expand Up @@ -129,7 +132,7 @@ const AuthorPublications = ({
{isLoadingPublications && (
<>
{Array.from({ length: 10 }).map((_, i) => (
<UnifiedDocFeedCardPlaceholder color="#efefef" />
<UnifiedDocFeedCardPlaceholder color="#efefef" key={i} />
))}
</>
)}
Expand All @@ -138,11 +141,9 @@ const AuthorPublications = ({
<div className={css(styles.publicationsHeader)}>
<div className={css(styles.sectionHeader)}>Publications</div>
{currentUser?.authorProfile?.id === fullAuthorProfile.id && (
// @ts-ignore legacy
<AddPublicationsModal
// @ts-ignore legacy
// @ts-ignore legacy hook
wsUrl={WS_ROUTES.NOTIFICATIONS(auth?.user?.id)}
// @ts-ignore legacy
wsAuth
>
<Button>
Expand Down Expand Up @@ -179,62 +180,51 @@ const AuthorPublications = ({

const authorships: Authorship[] =
targetDoc.authorships.map(parseAuthorship);
const isFirstAuthor = authorships.find(
(authorship) =>
authorship.authorPosition === "first" &&
authorship.authorId === fullAuthorProfile.id
);


const rewardEligibilityInfo = getRewardsEligibilityInfo({ authorships, fullAuthorProfile, targetDoc });


const menuOptions = [ {
label: "Remove",
icon: <FontAwesomeIcon icon={faTrash} />,
value: "remove-from-feed",
onClick: () => {
alert('hi')
},
},]

return (
<div className={css(styles.wrapper)}>
<div className={css(styles.wrapper)} key={`doc-${docID}`}>
<div className={css(styles.docControls)}>
{isFirstAuthor && (
<>
<Button
size="small"
variant="contained"
customButtonStyle={styles.claimButton}
onClick={() =>
setRewardsModalState({
paperId: targetDoc.id,
paperTitle: targetDoc.title,
authorship:
authorships.find(
(authorship) =>
authorship.authorId ===
fullAuthorProfile.id
) || null,
isOpen: true,
})
}
>
<div
style={{
color: colors.NEW_GREEN(),
display: "flex",
alignItems: "center",
columnGap: 10,
}}
>
<ResearchCoinIcon
version={4}
color={colors.NEW_GREEN()}
/>{" "}
Claim rewards
</div>
</Button>
<div style={{ display: "inline-flex" }}>
<IconButton
aria-label="more"
id="long-button"
aria-haspopup="true"
onClick={() => null}
<ClaimRewardsButton
handleClick={() => {
setRewardsModalState({
paperId: targetDoc.id,
paperTitle: targetDoc.title,
authorship:
authorships.find(
(authorship) =>
authorship.authorId ===
fullAuthorProfile.id
) || null,
isOpen: true,
})
}}
rewardEligibilityInfo={rewardEligibilityInfo}
/>

<GenericMenu
softHide={true}
options={menuOptions}
width={200}
id={"options-for-doc-" + docID}
direction="bottom-right"
>
<MoreHoriz />
</IconButton>
</div>
</>
)}
<IconButton overrideStyle={styles.btnDots}>
<FontAwesomeIcon icon={faEllipsis} />
</IconButton>
</GenericMenu>
</div>
<FeedCard
{...targetDoc}
Expand Down Expand Up @@ -279,16 +269,22 @@ const AuthorPublications = ({
};

const styles = StyleSheet.create({
btnDots: {
fontSize: 22,
borderRadius: "50px",
color: colors.BLACK(1.0),
background: colors.LIGHTER_GREY(),
border: `1px solid ${colors.LIGHTER_GREY()}`,
padding: "6px 12px",
":hover": {
background: colors.DARKER_GREY(0.2),
transition: "0.2s",
},
},
docControls: {
display: "flex",
justifyContent: "space-between",
},
claimButton: {
background: colors.NEW_GREEN(0.1),
border: `1px solid ${colors.NEW_GREEN()}`,
marginTop: 20,
marginBottom: 5,
},
publicationsHeader: {
display: "flex",
justifyContent: "space-between",
Expand Down Expand Up @@ -321,7 +317,6 @@ const styles = StyleSheet.create({
margin: "0 auto",
marginTop: 20,
},

wrapper: {},
contentWrapper: {
display: "flex",
Expand Down
31 changes: 23 additions & 8 deletions components/Author/Profile/WelcomeToProfileBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,47 @@ import { FullAuthorProfile } from "../lib/types";
import ResearchCoinIcon from "~/components/Icons/ResearchCoinIcon";
import colors from "~/config/themes/colors";
import { useState } from "react";
import { RootState } from "~/redux";
import { useDismissableFeature } from "~/config/hooks/useDismissableFeature";
import { useSelector } from "react-redux";

const WelcomeToProfileBanner = ({
profile,
}: {
profile: FullAuthorProfile;
}) => {
const auth = useSelector((state: RootState) => state.auth);
const {
isDismissed,
dismissFeature,
dismissStatus
} = useDismissableFeature({ auth, featureName: "research-rewards-banner" })


const [isVisible, setIsVisible] = useState(true);

if (!isVisible) {
if (!isVisible || dismissStatus === "unchecked" || (dismissStatus === "checked" && isDismissed)) {
return null;
}

return (
<div className={css(styles.rootWrapper)}>
<div>
<div className={css(styles.header)}>
<ResearchCoinIcon version={4} color="#999999" />
View your rewards
<ResearchCoinIcon version={4} color={colors.NEW_GREEN()} />
Healthy Research Rewards
</div>
<div className={css(styles.descriptionWrapper)}>
ResearchHub is incentivizing healthy research behavior. At this time,
first authors of open access papers are eligible for rewards. Visit
the publications tab to view eligible publications.
the publications tab to view your eligible publications.
</div>
<div
className={css(styles.dismissBtn)}
onClick={() => setIsVisible(false)}
onClick={() => {
setIsVisible(false)
dismissFeature();
}}
>
Got it
</div>
Expand All @@ -49,8 +63,8 @@ const styles = StyleSheet.create({
justifyContent: "space-between",
alignItems: "center",
borderRadius: 20,
border: `1px solid #cecece`,
background: "rgb(242, 242, 242)",
border: "1px solid rgb(10 174 66)",
background: "rgb(243 255 247)",
padding: 20,
},
btn: {
Expand All @@ -64,13 +78,14 @@ const styles = StyleSheet.create({
alignItems: "center",
fontWeight: 500,
gap: 10,
color: colors.BLACK(),
color: "rgb(10 174 66)",
},
descriptionWrapper: {
display: "flex",
alignItems: "center",
fontSize: 16,
marginTop: 10,
color: colors.BLACK(0.9),
},
rscIcon: {},
badge: {
Expand Down
14 changes: 13 additions & 1 deletion components/Author/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import {
import { Hub, parseHub } from "~/config/types/hub";
import {
AuthorProfile,
Education,
ID,
parseAuthorProfile,
parseEducation,
} from "~/config/types/root_types";

export type Achievement = "CITED_AUTHOR" | "OPEN_ACCESS";
Expand All @@ -28,6 +30,7 @@ export type FullAuthorProfile = {
worksCount: number;
citationCount: number;
}>;
education: Array<Education>;
achievements: Array<Achievement>;
openAccessPct: number;
hIndex: number;
Expand All @@ -50,14 +53,22 @@ export type Reputation = {
score: number;
bins: Array<Array<number>>;
hub: Hub;

percentile: number;
};

export const parseReputation = (raw: any): Reputation => {

let percentile = 0;
if (Array.isArray(raw.bins)) {
percentile = (raw.score / raw.bins[raw.bins.length - 1][1]) * 100
}


return {
score: raw.score,
bins: raw.bins,
hub: parseHub(raw.hub),
percentile,
}
}

Expand All @@ -79,6 +90,7 @@ export const parseFullAuthorProfile = (raw: any): FullAuthorProfile => {
isHubEditor: raw.is_hub_editor,
openAlexIds: raw.openalex_ids || [],
achievements: raw.achievements || [],
education: Array.isArray(raw.education) ? raw.education.map(edu => parseEducation(edu)) : [],
openAccessPct: Math.round((raw.open_access_pct || 0) * 100),
hIndex: raw.h_index,
i10Index: raw.i10_index,
Expand Down
Loading

0 comments on commit 976a8a2

Please sign in to comment.