Add share with friends functionality

feat/readonly-editor
Kamran Ahmed 1 year ago
parent c2fc54291c
commit 319188bbcc
  1. 117
      src/components/ShareOptions/ShareFriendList.tsx

@ -1,8 +1,11 @@
import { useEffect, useState } from 'react';
import { useToast } from '../../hooks/use-toast';
import { UserItem } from './UserItem';
import { Users2 } from 'lucide-react';
import {httpGet} from "../../lib/http";
import { Check, Copy, Group, UserPlus2, Users2 } from 'lucide-react';
import { httpGet } from '../../lib/http';
import { getUser } from '../../lib/jwt.ts';
import { useCopyText } from '../../hooks/use-copy-text.ts';
import { cn } from '../../lib/classname.ts';
export type FriendshipStatus =
| 'none'
@ -41,10 +44,13 @@ type ShareFriendListProps = {
};
export function ShareFriendList(props: ShareFriendListProps) {
const userId = getUser()?.id!;
const { setFriends, friends, sharedFriendIds, setSharedFriendIds } = props;
const toast = useToast();
const { isCopied, copyText } = useCopyText();
const [isLoading, setIsLoading] = useState(true);
const [isAddingFriend, setIsAddingFriend] = useState(false);
async function loadFriends() {
if (friends.length > 0) {
@ -53,7 +59,7 @@ export function ShareFriendList(props: ShareFriendListProps) {
setIsLoading(true);
const { response, error } = await httpGet<ListFriendsResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-list-friends`
`${import.meta.env.PUBLIC_API_URL}/v1-list-friends`,
);
if (error || !response) {
@ -87,6 +93,10 @@ export function ShareFriendList(props: ShareFriendListProps) {
</ul>
);
const isDev = import.meta.env.DEV;
const baseWebUrl = isDev ? 'http://localhost:3000' : 'https://roadmap.sh';
const befriendUrl = `${baseWebUrl}/befriend?u=${userId}`;
return (
<>
{(friends.length > 0 || isLoading) && (
@ -112,32 +122,85 @@ export function ShareFriendList(props: ShareFriendListProps) {
{loadingFriends}
{friends.length > 0 && !isLoading && (
<ul className="mt-2 grid grid-cols-3 gap-1.5">
{friends.map((friend) => {
const isSelected = sharedFriendIds?.includes(friend.userId);
return (
<li key={friend.userId}>
<UserItem
user={{
name: friend.name,
avatar: friend.avatar,
email: friend.email,
}}
isSelected={isSelected}
onClick={() => {
if (isSelected) {
setSharedFriendIds(
sharedFriendIds.filter((id) => id !== friend.userId)
);
} else {
setSharedFriendIds([...sharedFriendIds, friend.userId]);
}
<>
<ul className="mt-2 grid grid-cols-3 gap-1.5">
{friends.map((friend) => {
const isSelected = sharedFriendIds?.includes(friend.userId);
return (
<li key={friend.userId}>
<UserItem
user={{
name: friend.name,
avatar: friend.avatar,
email: friend.email,
}}
isSelected={isSelected}
onClick={() => {
if (isSelected) {
setSharedFriendIds(
sharedFriendIds.filter((id) => id !== friend.userId),
);
} else {
setSharedFriendIds([...sharedFriendIds, friend.userId]);
}
}}
/>
</li>
);
})}
</ul>
{!isAddingFriend && (
<p className="mt-6 text-sm text-gray-600">
Don't see a Friend?{' '}
<button
onClick={() => {
setIsAddingFriend(true);
}}
className="font-semibold text-gray-900 underline"
>
Add them
</button>
</p>
)}
{isAddingFriend && (
<div className="-mx-4 -mb-4 mt-6 border-t bg-gray-50 px-4 py-4">
<p className="mb-1.5 flex items-center gap-1 text-sm text-gray-800">
<UserPlus2 className="text-gray-500" size="20px" />
Share the link below with your friends to invite them
</p>
<div className="relative">
<input
readOnly
type="text"
value={befriendUrl}
onClick={(e) => {
e.preventDefault();
(e.target as HTMLInputElement).select();
copyText(befriendUrl);
}}
className={cn(
'w-full rounded-md border px-2 py-2 text-sm focus:shadow-none focus:outline-0',
{
'border-green-400 bg-green-50': isCopied,
},
)}
/>
</li>
);
})}
</ul>
<button
onClick={() => copyText(befriendUrl)}
className="absolute bottom-0 right-0 top-0 flex items-center px-2.5"
>
{isCopied ? (
<span className="flex items-center gap-1 text-sm font-medium text-green-600">
<Check className="text-green-600" size="18px" /> Copied
</span>
) : (
<Copy className="text-gray-400" size="18px" />
)}
</button>
</div>
</div>
)}
</>
)}
{friends.length === 0 && !isLoading && (

Loading…
Cancel
Save