This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / webapp / features / follows / components / followButton / FollowButton.tsx
2.3 kB 85 lines
1'use client'; 2 3import { Button } from '@mantine/core'; 4import { useState, useEffect } from 'react'; 5import useFollowTarget from '../../lib/mutations/useFollowTarget'; 6import useUnfollowTarget from '../../lib/mutations/useUnfollowTarget'; 7import { useFeatureFlags } from '@/lib/clientFeatureFlags'; 8import { isApprovedHandle } from '@/lib/approvedHandles'; 9 10interface Props { 11 targetId: string; 12 targetType: 'USER' | 'COLLECTION'; 13 targetHandle?: string; // Handle of the user or collection author 14 initialIsFollowing?: boolean; 15 variant?: 'filled' | 'light' | 'outline' | 'subtle'; 16 size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; 17 followText?: string; 18} 19 20export default function FollowButton({ 21 targetId, 22 targetType, 23 targetHandle, 24 initialIsFollowing = false, 25 variant = 'filled', 26 size = 'sm', 27 followText = 'Follow', 28}: Props) { 29 const { data: featureFlags } = useFeatureFlags(); 30 const [isFollowing, setIsFollowing] = useState(initialIsFollowing); 31 const followMutation = useFollowTarget(); 32 const unfollowMutation = useUnfollowTarget(); 33 34 // Sync local state when the prop changes (e.g., after query refetch) 35 useEffect(() => { 36 setIsFollowing(initialIsFollowing); 37 }, [initialIsFollowing]); 38 39 // Check if following feature is enabled for current user and target user is approved 40 const isFollowingEnabled = 41 featureFlags?.following && isApprovedHandle(targetHandle); 42 43 // Return early only AFTER all hooks have been called 44 if (!isFollowingEnabled) { 45 return null; 46 } 47 48 const isLoading = followMutation.isPending || unfollowMutation.isPending; 49 50 const handleClick = async () => { 51 if (isFollowing) { 52 setIsFollowing(false); 53 unfollowMutation.mutate( 54 { targetId, targetType }, 55 { 56 onError: () => { 57 setIsFollowing(true); 58 }, 59 }, 60 ); 61 } else { 62 setIsFollowing(true); 63 followMutation.mutate( 64 { targetId, targetType }, 65 { 66 onError: () => { 67 setIsFollowing(false); 68 }, 69 }, 70 ); 71 } 72 }; 73 74 return ( 75 <Button 76 onClick={handleClick} 77 loading={isLoading} 78 variant={isFollowing ? 'outline' : 'light'} 79 color={isFollowing ? 'gray' : 'cyan'} 80 size={size} 81 > 82 {isFollowing ? 'Following' : followText} 83 </Button> 84 ); 85}