This repository has no description
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}