Add share with friends functionality

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

@ -1,8 +1,11 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useToast } from '../../hooks/use-toast'; import { useToast } from '../../hooks/use-toast';
import { UserItem } from './UserItem'; import { UserItem } from './UserItem';
import { Users2 } from 'lucide-react'; import { Check, Copy, Group, UserPlus2, Users2 } from 'lucide-react';
import {httpGet} from "../../lib/http"; 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 = export type FriendshipStatus =
| 'none' | 'none'
@ -41,10 +44,13 @@ type ShareFriendListProps = {
}; };
export function ShareFriendList(props: ShareFriendListProps) { export function ShareFriendList(props: ShareFriendListProps) {
const userId = getUser()?.id!;
const { setFriends, friends, sharedFriendIds, setSharedFriendIds } = props; const { setFriends, friends, sharedFriendIds, setSharedFriendIds } = props;
const toast = useToast(); const toast = useToast();
const { isCopied, copyText } = useCopyText();
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [isAddingFriend, setIsAddingFriend] = useState(false);
async function loadFriends() { async function loadFriends() {
if (friends.length > 0) { if (friends.length > 0) {
@ -53,7 +59,7 @@ export function ShareFriendList(props: ShareFriendListProps) {
setIsLoading(true); setIsLoading(true);
const { response, error } = await httpGet<ListFriendsResponse>( 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) { if (error || !response) {
@ -87,6 +93,10 @@ export function ShareFriendList(props: ShareFriendListProps) {
</ul> </ul>
); );
const isDev = import.meta.env.DEV;
const baseWebUrl = isDev ? 'http://localhost:3000' : 'https://roadmap.sh';
const befriendUrl = `${baseWebUrl}/befriend?u=${userId}`;
return ( return (
<> <>
{(friends.length > 0 || isLoading) && ( {(friends.length > 0 || isLoading) && (
@ -112,6 +122,7 @@ export function ShareFriendList(props: ShareFriendListProps) {
{loadingFriends} {loadingFriends}
{friends.length > 0 && !isLoading && ( {friends.length > 0 && !isLoading && (
<>
<ul className="mt-2 grid grid-cols-3 gap-1.5"> <ul className="mt-2 grid grid-cols-3 gap-1.5">
{friends.map((friend) => { {friends.map((friend) => {
const isSelected = sharedFriendIds?.includes(friend.userId); const isSelected = sharedFriendIds?.includes(friend.userId);
@ -127,7 +138,7 @@ export function ShareFriendList(props: ShareFriendListProps) {
onClick={() => { onClick={() => {
if (isSelected) { if (isSelected) {
setSharedFriendIds( setSharedFriendIds(
sharedFriendIds.filter((id) => id !== friend.userId) sharedFriendIds.filter((id) => id !== friend.userId),
); );
} else { } else {
setSharedFriendIds([...sharedFriendIds, friend.userId]); setSharedFriendIds([...sharedFriendIds, friend.userId]);
@ -138,6 +149,58 @@ export function ShareFriendList(props: ShareFriendListProps) {
); );
})} })}
</ul> </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,
},
)}
/>
<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 && ( {friends.length === 0 && !isLoading && (

Loading…
Cancel
Save