@@ -4,44 +4,42 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/Components/Ui/Avatar";
44import { Button } from "@/Components/Ui/Form/Button" ;
55import { Card , CardContent } from "@/Components/Ui/Card" ;
66import { HoverCard , HoverCardContent , HoverCardTrigger } from "@/Components/Ui/HoverCard" ;
7- import ApiService from "@/Services/ApiService" ;
87import { Link } from "@inertiajs/react" ;
98import { useAuthStore } from "@/Stores/AuthStore" ;
109import { Trans , useTranslation } from "react-i18next" ;
1110import { toast } from "@/Hooks/useToast" ;
11+ import { useMutation } from "@tanstack/react-query" ;
12+ import ReactApi from "@/Api/ReactApi" ;
13+ import UserApi from "@/Api/UserApi" ;
1214
1315export function UserProfileHover ( { username, children } ) {
1416 const [ isFollowing , setIsFollowing ] = useState ( false ) ;
1517 const [ followers , setFollowers ] = useState ( 0 ) ;
1618 const [ followings , setFollowings ] = useState ( 0 ) ;
1719 const [ user , setUser ] = useState ( { } ) ;
1820 const [ profile , setProfile ] = useState ( { } ) ;
19- const [ isLoading , setIsLoading ] = useState ( true ) ;
2021 const [ hasFetched , setHasFetched ] = useState ( false ) ;
2122 const authStore = useAuthStore ( ) ;
2223 const [ isOwnProfile , setIsOwnProfile ] = useState ( false ) ;
2324 const hoverTimeoutRef = useRef ( null ) ;
2425 const { t } = useTranslation ( ) ;
2526
27+ const previewMutation = useMutation ( {
28+ mutationFn : ( ) => UserApi . preview ( { username } ) ,
29+ onSuccess : ( response ) => {
30+ setUser ( response . user ) ;
31+ setProfile ( response . profile ) ;
32+ setFollowers ( Number ( response . user . followers ) ) ;
33+ setFollowings ( Number ( response . user . followings ) ) ;
34+ setIsFollowing ( response . user . isFollowing ) ;
35+ setHasFetched ( true ) ;
36+ } ,
37+ } ) ;
38+
2639 const handleHover = ( ) => {
2740 if ( hasFetched ) return ;
28- setIsLoading ( true ) ;
29-
3041 hoverTimeoutRef . current = setTimeout ( ( ) => {
31- setIsLoading ( true ) ;
32- ApiService . fetchJson (
33- route ( "api.user.preview" , { username } ) ,
34- { } ,
35- { method : "GET" } ,
36- ) . then ( ( response ) => {
37- setUser ( response . user ) ;
38- setProfile ( response . profile ) ;
39- setFollowers ( Number ( response . user . followers ) ) ;
40- setFollowings ( Number ( response . user . followings ) ) ;
41- setIsFollowing ( response . user . isFollowing ) ;
42- setIsLoading ( false ) ;
43- setHasFetched ( true ) ;
44- } ) ;
42+ previewMutation . mutate ( ) ;
4543 } , 600 ) ;
4644 } ;
4745
@@ -61,26 +59,26 @@ export function UserProfileHover({ username, children }) {
6159 } , [ ] ) ;
6260
6361 useEffect ( ( ) => {
64- setIsOwnProfile ( authStore . isAuthenticated && user . username == authStore . user . username ) ;
62+ setIsOwnProfile ( authStore . isAuthenticated && username == authStore . user . username ) ;
6563 } , [ user ] ) ;
6664
67- const handleFollow = async ( ) => {
68- ApiService . fetchJson (
69- route ( "api.react.follow" , { type : "user" , slug : user . username } ) ,
70- { } ,
71- { method : "POST" } ,
72- )
73- . then ( ( ) => {
74- setIsFollowing ( ! isFollowing ) ;
75- setFollowers ( isFollowing ? followers - 1 : followers + 1 ) ;
76- } )
77- . catch ( ( ) => {
78- toast ( {
79- title : t ( "Error" ) ,
80- description : t ( "You can react to the same user once a day" ) ,
81- variant : "destructive" ,
82- } ) ;
65+ const followMutation = useMutation ( {
66+ mutationFn : ( ) => ReactApi . follow ( { type : "user" , slug : username } ) ,
67+ onSuccess : ( ) => {
68+ setIsFollowing ( ! isFollowing ) ;
69+ setFollowers ( isFollowing ? followers - 1 : followers + 1 ) ;
70+ } ,
71+ onError : ( ) => {
72+ toast ( {
73+ title : t ( "Error" ) ,
74+ description : t ( "You can react to the same user once a day" ) ,
75+ variant : "destructive" ,
8376 } ) ;
77+ } ,
78+ } ) ;
79+
80+ const handleFollow = ( ) => {
81+ followMutation . mutate ( ) ;
8482 } ;
8583
8684 return (
@@ -97,7 +95,7 @@ export function UserProfileHover({ username, children }) {
9795 < HoverCardContent className = "w-80" side = "bottom" align = "start" >
9896 < Card className = "border-0 shadow-none" >
9997 < CardContent className = "p-4" >
100- { isLoading && (
98+ { previewMutation . isPending && (
10199 < div className = "flex justify-center py-8" >
102100 < div className = "animate-spin rounded-full h-8 w-8 border-b-2 border-primary" > </ div >
103101 </ div >
0 commit comments