Skip to content

Commit

Permalink
feat: implement improved UX for non-connected users profile (#1992)
Browse files Browse the repository at this point in the history
  • Loading branch information
OgDev-01 authored Oct 25, 2023
1 parent 7f344ee commit f11160c
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { OptionKeys } from "components/atoms/Select/multi-select";
import { addListContributor, useFetchAllLists } from "lib/hooks/useList";
import { useFetchUser } from "lib/hooks/useFetchUser";
import { cardPageUrl } from "lib/utils/urls";
import { copyToClipboard } from "lib/utils/copy-to-clipboard";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../Dialog/dialog";

const MultiSelect = dynamic(() => import("components/atoms/Select/multi-select"), { ssr: false });
Expand Down Expand Up @@ -65,6 +66,7 @@ const ContributorProfileHeader = ({
}: ContributorProfileHeaderProps) => {
const router = useRouter();
const currentPath = router.asPath;

const [isDialogOpen, setIsDialogOpen] = useState(false);
const [loading, setLoading] = useState(false);
const { requestConnection } = useUserConnections();
Expand Down Expand Up @@ -182,7 +184,7 @@ const ContributorProfileHeader = ({
</div>
</Link>
</div>
{isConnected && (
{isConnected ? (
<div className="flex flex-col items-center gap-3 translate-y-24 md:translate-y-0 md:flex-row">
<div className="flex flex-wrap items-center justify-center gap-2 mb-10 md:gap-6">
{user ? (
Expand Down Expand Up @@ -313,6 +315,25 @@ const ContributorProfileHeader = ({
</DropdownMenu>
</div>
</div>
) : (
<div className="flex flex-wrap items-center justify-center max-md:translate-y-14">
{!isOwner && (
<Button
onClick={() => {
copyToClipboard(`${new URL(currentPath, location.origin)}`).then(() => {
toast({
title: "Copied to clipboard",
description: "Share this link with your friend to invite them to OpenSauced!",
variant: "success",
});
});
}}
variant="primary"
>
Invite to opensauced
</Button>
)}
</div>
)}
</div>

Expand Down
18 changes: 7 additions & 11 deletions components/molecules/InsightPageCard/insight-page-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { getRelativeDays } from "lib/utils/date-utils";
import getRepoInsights from "lib/utils/get-repo-insights";

import useRepositories from "lib/hooks/api/useRepositories";
import { copyToClipboard } from "lib/utils/copy-to-clipboard";

import CardRepoList from "../CardRepoList/card-repo-list";
import PieChart, { PieData } from "../PieChart/pie-chart";
import StackedAvatar from "../StackedAvatar/stacked-avatar";
Expand Down Expand Up @@ -52,16 +54,6 @@ const InsightPageCard = ({ insight, user }: InsightPageCardProps): JSX.Element =
},
];

// Function to handle copy to clipboard
const handleCopyToClipboard = async (content: any) => {
const url = new URL(content, window.location.origin).toString();
try {
await navigator.clipboard.writeText(url);
} catch (error) {
console.log(error);
}
};

const averagePrOpened = repoData.length > 0 ? Math.round(((open || 0) / total) * 100) : 0;

return (
Expand Down Expand Up @@ -116,7 +108,11 @@ const InsightPageCard = ({ insight, user }: InsightPageCardProps): JSX.Element =
{/* Card footer */}
<div className="flex mt-4 justify-between">
<Button
onClick={() => handleCopyToClipboard(`/pages/${user?.user_metadata.user_name}/${insight.id}/dashboard`)}
onClick={() =>
copyToClipboard(
`${new URL(`/pages/${user?.user_metadata.user_name}/${insight.id}/dashboard`, location.origin)}`
)
}
className="w-48"
variant="outline"
>
Expand Down
133 changes: 126 additions & 7 deletions components/organisms/ContributorProfileTab/contributor-profile-tab.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import Link from "next/link";
import Image from "next/image";
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import clsx from "clsx";
import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict";

import { MdClose } from "react-icons/md";
import { FaLinkedinIn, FaXTwitter } from "react-icons/fa6";
import { TbMailFilled } from "react-icons/tb";
import Avatar from "components/atoms/Avatar/avatar";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "components/atoms/Tabs/tabs";
import HighlightInputForm from "components/molecules/HighlightInput/highlight-input-form";
Expand All @@ -19,11 +23,16 @@ import Button from "components/atoms/Button/button";
import useSupabaseAuth from "lib/hooks/useSupabaseAuth";
import useFetchAllEmojis from "lib/hooks/useFetchAllEmojis";
import { setQueryParams } from "lib/utils/query-params";
import { copyToClipboard } from "lib/utils/copy-to-clipboard";

import openSaucedImg from "img/openSauced-icon.png";

import Title from "components/atoms/Typography/title";
import PaginationResults from "components/molecules/PaginationResults/pagination-result";
import Pagination from "components/molecules/Pagination/pagination";
import DashContainer from "components/atoms/DashedContainer/DashContainer";
import SkeletonWrapper from "components/atoms/SkeletonLoader/skeleton-wrapper";
import { useToast } from "lib/hooks/useToast";
import ConnectionRequestsWrapper from "../ConnectionRequestWrapper/connection-requests-wrapper";
import UserRepositoryRecommendations from "../UserRepositoryRecommendations/user-repository-recommendations";

Expand Down Expand Up @@ -64,9 +73,21 @@ const ContributorProfileTab = ({
recentContributionCount,
repoList,
}: ContributorProfileTabProps): JSX.Element => {
const { login, interests: userInterests, receive_collaboration } = contributor || {};
const { user } = useSupabaseAuth();
const {
login,
interests: userInterests,
receive_collaboration,
email,
twitter_username,
linkedin_url,
display_email,
is_open_sauced_member,
} = contributor || {};
const { user, signIn } = useSupabaseAuth();
const { user_name } = user?.user_metadata || {};
const [showInviteJumbotron, setShowInviteJumbotron] = useState(!!is_open_sauced_member ? false : true);
const [showSocialLinks, setShowSocialLinks] = useState(false);
const { toast } = useToast();

const { data: highlights, isError, isLoading, mutate, meta, setPage } = useFetchUserHighlights(login || "");
const { data: emojis } = useFetchAllEmojis();
Expand All @@ -85,8 +106,8 @@ const ContributorProfileTab = ({
setQueryParams({ tab: tabValue } satisfies QueryParams);
}

// Setting the query param "tab" if none exists
useEffect(() => {
// Setting the query param "tab" if none exists
if (
!tab ||
!Object.keys(tabs).includes(tab as string) ||
Expand All @@ -96,8 +117,6 @@ const ContributorProfileTab = ({
) {
setQueryParams({ tab: currentTab } satisfies QueryParams);
}

// If the user is not the owner of the profile, block them from accessing the recommendations tab
}, [tab, currentTab]);

const getTabTriggerClassName = (tab: TabKey): string => {
Expand All @@ -113,6 +132,24 @@ const ContributorProfileTab = ({
);
};

const emailBody = `Hey ${login}. I'm using OpenSauced to keep track of my contributions and discover new projects. Try connecting your GitHub to https://opensauced.pizza/`;

const handleInviteClick = () => {
const hasSocials = !!(twitter_username || display_email || linkedin_url);

if (!hasSocials) {
copyToClipboard(`${new URL(`/user/${login}`, location.origin)}`).then(() => {
toast({
title: "Copied to clipboard",
description: "Share this link with your friend to invite them to OpenSauced!",
variant: "success",
});
});
} else {
setShowSocialLinks(true);
}
};

const getEmptyHighlightPreset = (): JSX.Element => {
switch (user_name === login) {
case true:
Expand Down Expand Up @@ -164,6 +201,90 @@ const ContributorProfileTab = ({

{/* Highlights Tab details */}

{showInviteJumbotron && (
<div className="bg-white relative p-6 my-10 rounded-xl gap-4 flex flex-col md:flex-row items-center justify-between shadow-xl md:pr-14">
<MdClose
onClick={() => setShowInviteJumbotron(!showInviteJumbotron)}
role="button"
className="absolute right-5 top-5 text-xl text-slate-600"
/>
<div className="flex-1 md:flex-[2.5]">
<div className="flex items-center gap-2">
<Image className="rounded" alt="Open Sauced Logo" width={30} height={30} src={openSaucedImg} />
<Title className="font-semibold text-lg" level={4}>
Do you know {login}?
</Title>
</div>

<p className="text-slate-500 text-sm mt-2">
Invite {login} to join OpenSauced to be able to access insights, interact with other developers and find
new open source opportunities!
</p>
</div>
<div className="flex items-end flex-col gap-2 self-end flex-1 max-md:w-full">
{!showSocialLinks && (
<Button
onClick={handleInviteClick}
className="max-md:w-full md:w-40 flex justify-center"
variant="primary"
>
Invite to opensauced
</Button>
)}

{showSocialLinks && (
<div className="flex items-center gap-3">
{twitter_username && (
<a
href={`https://twitter.com/intent/tweet?text=${encodeURIComponent(
`Check out @saucedopen. The platform for open source contributors to find their next contribution. https://opensauced.pizza/blog/social-coding-is-back. @${twitter_username}`
)}&hashtags=opensource,github`}
target="_blank"
rel="noopener noreferrer"
className="text-white bg-blue-400 rounded-full p-3"
>
<FaXTwitter className="text-lg" />
</a>
)}
{!!display_email && (
<a
href={`mailto:${email}?subject=${encodeURIComponent(
"Invitation to join OpenSauced!"
)}&body=${encodeURIComponent(emailBody)}`}
className="text-white bg-red-400 rounded-full p-3"
>
<TbMailFilled className="text-lg" />
</a>
)}
{!!linkedin_url && (
<a
href={`https://www.linkedin.com/in/${linkedin_url}`}
className="text-white bg-blue-600 rounded-full p-3"
>
<FaLinkedinIn className="text-lg" />
</a>
)}
</div>
)}

{!user && !showSocialLinks && (
<Button
onClick={() =>
signIn({
provider: "github",
options: { redirectTo: `${window.location.origin}/user/${login}` },
})
}
className="max-md:w-full md:w-40 flex justify-center"
variant="text"
>
This is me!
</Button>
)}
</div>
</div>
)}

<TabsContent value={"highlights" satisfies TabKey}>
{(hasHighlights || inputVisible) && user_name === login && (
<div className="lg:pl-20 lg:gap-x-4 pt-4 flex max-w-[48rem]">
Expand All @@ -179,8 +300,6 @@ const ContributorProfileTab = ({
</div>
)}
<div className="flex flex-col gap-8 mt-8">
{/* <HightlightEmptyState /> */}

{isError && <>An error occured</>}
{isLoading && (
<>
Expand Down
7 changes: 7 additions & 0 deletions lib/utils/copy-to-clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const copyToClipboard = async (content: string) => {
try {
await navigator.clipboard.writeText(content);
} catch (error) {
console.log("This browser does not support the clipboard.", error);
}
};

0 comments on commit f11160c

Please sign in to comment.