Skip to content

Commit

Permalink
Improved favourite add button
Browse files Browse the repository at this point in the history
  • Loading branch information
dkildar committed Dec 21, 2024
1 parent c5543d8 commit 267c3b2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 50 deletions.
6 changes: 3 additions & 3 deletions src/api/mutations/favourites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export function useAddFavourite(onSuccess: () => void) {
throw new Error("Cannot add to favourite. Active user missed");
}
const data = { code: getAccessToken(activeUser.username), account };
const response = await appAxios.post<Favorite>(apiBase(`/private-api/favorites-add`), data);
const response = await appAxios.post<Favorite[]>(apiBase(`/private-api/favorites-add`), data);
return response.data;
},
onSuccess: (created: Favorite) => {
onSuccess: (next: Favorite[]) => {
queryClient.setQueryData<Favorite[]>(
[QueryIdentifiers.FAVOURITES, activeUser?.username],
(data) => [...(data ?? []), created]
() => [...next]
);

success(i18next.t("favorite-btn.added"));
Expand Down
3 changes: 1 addition & 2 deletions src/api/queries/favourites-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export function useFavouritesQuery() {
const resp = await appAxios.post<Favorite[]>(apiBase(`/private-api/favorites`), data);
return resp.data;
},
enabled: !!activeUser,
initialData: []
enabled: !!activeUser
});
}
74 changes: 32 additions & 42 deletions src/features/shared/favorite-btn/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useEffect, useMemo, useState } from "react";
import React, { useMemo } from "react";
import { Button } from "@ui/button";
import { useGlobalStore } from "@/core/global-store";
import { LoginRequired } from "@/features/shared";
import { Tooltip } from "@ui/tooltip";
import { personFavoriteOutlineSvg, personFavoriteSvg } from "@ui/svg";
import i18next from "i18next";
import { useAddFavourite, useCheckFavourite, useDeleteFavourite } from "@/api/mutations";
import { useAddFavourite, useDeleteFavourite } from "@/api/mutations";
import { useFavouritesQuery } from "@/api/queries";
import { UilHeart } from "@tooni/iconscout-unicons-react";

interface Props {
targetUsername: string;
Expand All @@ -14,24 +15,20 @@ interface Props {
export function FavouriteBtn({ targetUsername }: Props) {
const activeUser = useGlobalStore((s) => s.activeUser);

const [favourited, setFavourited] = useState(false);
const { data, isPending } = useFavouritesQuery();

const { mutateAsync: detect, isPending: isCheckPending } = useCheckFavourite();
const { mutateAsync: add, isPending: isAddPending } = useAddFavourite(() => {
detect({ account: targetUsername }).then((r) => setFavourited(r));
});
const { mutateAsync: deleteFrom, isPending: isDeletePending } = useDeleteFavourite(() => {
detect({ account: targetUsername }).then((r) => setFavourited(r));
});
const { mutateAsync: add, isPending: isAddPending } = useAddFavourite(() => {});
const { mutateAsync: deleteFrom, isPending: isDeletePending } = useDeleteFavourite(() => {});

const inProgress = useMemo(
() => isAddPending || isDeletePending || isCheckPending,
[isAddPending, isDeletePending, isCheckPending]
const favourited = useMemo(
() => data?.some((item) => item.account === targetUsername),
[data, targetUsername]
);

useEffect(() => {
detect({ account: targetUsername });
}, [activeUser, detect, targetUsername]);
const inProgress = useMemo(
() => isAddPending || isDeletePending || isPending,
[isAddPending, isDeletePending, isPending]
);

return (
<>
Expand All @@ -41,37 +38,30 @@ export function FavouriteBtn({ targetUsername }: Props) {
<Tooltip content={i18next.t("favorite-btn.add")}>
<Button
size="sm"
disabled={inProgress}
isLoading={inProgress}
onClick={() => deleteFrom({ account: targetUsername })}
icon={personFavoriteOutlineSvg}
icon={<UilHeart />}
/>
</Tooltip>
</span>
</LoginRequired>
)}
{activeUser && favourited && (
<span className="favorite-btn">
<Tooltip content={i18next.t("favorite-btn.delete")}>
<Button
size="sm"
disabled={inProgress}
onClick={() => deleteFrom({ account: targetUsername })}
icon={personFavoriteSvg}
/>
</Tooltip>
</span>
)}
{activeUser && !favourited && (
<span className="favorite-btn">
<Tooltip content={i18next.t("favorite-btn.add")}>
<Button
size="sm"
disabled={inProgress}
onClick={() => add({ account: targetUsername })}
icon={personFavoriteOutlineSvg}
/>
</Tooltip>
</span>
{activeUser && (
<Tooltip content={i18next.t(favourited ? "favorite-btn.delete" : "favorite-btn.add")}>
<Button
appearance={favourited ? "pressed" : "primary"}
size="sm"
noPadding={true}
className="w-8"
isLoading={inProgress}
onClick={() =>
favourited
? deleteFrom({ account: targetUsername })
: add({ account: targetUsername })
}
icon={<UilHeart />}
/>
</Tooltip>
)}
</>
);
Expand Down
4 changes: 3 additions & 1 deletion src/features/ui/button/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export type ButtonAppearance =
| "success"
| "warning"
| "info"
| "white-link";
| "white-link"
// User pressed style for buttons with pressed(not) statements like favourite like button
| "pressed";
export type ButtonSize = "xxs" | "xs" | "sm" | "md" | "lg" | "display";

interface RegularButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
Expand Down
6 changes: 4 additions & 2 deletions src/features/ui/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ export const BUTTON_STYLES: Record<ButtonAppearance, string> = {
warning: "",
info: "bg-info-default hover:info-hover focus:bg-info-focus text-white disabled:opacity-50 disabled:hover:bg-info-default disabled:focus:bg-info-default",
"gray-link": "text-gray-600 hover:text-blue-dark-sky focus:text-blue-dark-sky-active",
"white-link": "text-white hover:opacity-50 focus:opacity-75"
"white-link": "text-white hover:opacity-50 focus:opacity-75",
pressed: "text-red hover:text-red-040 bg:blue-duck-egg dark:bg-dark-default"
};

export const BUTTON_OUTLINE_STYLES: Record<ButtonAppearance, string> = {
Expand All @@ -26,7 +27,8 @@ export const BUTTON_OUTLINE_STYLES: Record<ButtonAppearance, string> = {
warning: "",
info: "border-info-default hover:border-info-hover focus:border-info-focus text-info-default hover:text-info-hover focus:text-info-focus",
"gray-link": "",
"white-link": ""
"white-link": "",
pressed: ""
};

export const BUTTON_SIZES: Record<ButtonSize, string> = {
Expand Down

0 comments on commit 267c3b2

Please sign in to comment.