feat: create tabs on user friend modal

This commit is contained in:
Zamitto 2024-07-16 14:52:39 -03:00
parent d0406282ce
commit 7f3d7a56c3
8 changed files with 202 additions and 152 deletions

View File

@ -248,6 +248,7 @@
"see_profile": "See profile",
"sending": "Sending",
"friend_request_sent": "Friend request sent",
"friends": "Friends"
"friends": "Friends",
"friends_list": "Friends list"
}
}

View File

@ -248,6 +248,7 @@
"friend_request_sent": "Pedido de amizade enviado",
"friends": "Amigos",
"add": "Adicionar",
"sending": "Enviando"
"sending": "Enviando",
"friends_list": "Lista de amigos"
}
}

View File

@ -1,149 +0,0 @@
import { Button, Modal, TextField } from "@renderer/components";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useState } from "react";
import { useToast, useUserDetails } from "@renderer/hooks";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { UserFriendRequest } from "./user-friend-request";
export interface UserAddFriendsModalProps {
visible: boolean;
onClose: () => void;
}
export const UserFriendModal = ({
visible,
onClose,
}: UserAddFriendsModalProps) => {
const { t } = useTranslation("user_profile");
const [friendCode, setFriendCode] = useState("");
const [isAddingFriend, setIsAddingFriend] = useState(false);
const navigate = useNavigate();
const { sendFriendRequest, updateFriendRequestState, friendRequests } =
useUserDetails();
const { showErrorToast } = useToast();
const handleClickAddFriend = () => {
setIsAddingFriend(true);
sendFriendRequest(friendCode)
.then(() => {
setFriendCode("");
})
.catch(() => {
showErrorToast("Não foi possível enviar o pedido de amizade");
})
.finally(() => {
setIsAddingFriend(false);
});
};
const handleClickRequest = (userId: string) => {
resetAndClose();
navigate(`/user/${userId}`);
};
const handleClickSeeProfile = () => {
resetAndClose();
navigate(`/user/${friendCode}`);
};
const handleClickCancelFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "CANCEL").catch(() => {
showErrorToast("Falha ao cancelar convite");
});
};
const handleClickAcceptFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "ACCEPTED").catch(() => {
showErrorToast("Falha ao aceitar convite");
});
};
const handleClickRefuseFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "REFUSED").catch(() => {
showErrorToast("Falha ao recusar convite");
});
};
const resetAndClose = () => {
setFriendCode("");
onClose();
};
return (
<Modal visible={visible} title={t("friends")} onClose={resetAndClose}>
<div
style={{
display: "flex",
width: "500px",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
gap: `${SPACING_UNIT}px`,
}}
>
<TextField
label={t("friend_code")}
value={friendCode}
minLength={8}
maxLength={8}
containerProps={{ style: { width: "100%" } }}
onChange={(e) => setFriendCode(e.target.value)}
/>
<Button
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="button"
onClick={handleClickAddFriend}
>
{isAddingFriend ? t("sending") : t("add")}
</Button>
<Button
onClick={handleClickSeeProfile}
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="button"
>
{t("see_profile")}
</Button>
</div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h3>Pendentes</h3>
{friendRequests?.map((request) => {
return (
<UserFriendRequest
key={request.id}
displayName={request.displayName}
isRequestSent={request.type === "SENT"}
profileImageUrl={request.profileImageUrl}
userId={request.id}
onClickAcceptRequest={handleClickAcceptFriendRequest}
onClickCancelRequest={handleClickCancelFriendRequest}
onClickRefuseRequest={handleClickRefuseFriendRequest}
onClickRequest={handleClickRequest}
/>
);
})}
</div>
</div>
</Modal>
);
};

View File

@ -0,0 +1 @@
export * from "./user-friend-modal";

View File

@ -0,0 +1,138 @@
import { Button, TextField } from "@renderer/components";
import { useToast, useUserDetails } from "@renderer/hooks";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { UserFriendRequest } from "./user-friend-request";
export interface UserFriendModalAddFriendProps {
closeModal: () => void;
}
export const UserFriendModalAddFriend = ({
closeModal,
}: UserFriendModalAddFriendProps) => {
const { t } = useTranslation("user_profile");
const [friendCode, setFriendCode] = useState("");
const [isAddingFriend, setIsAddingFriend] = useState(false);
const navigate = useNavigate();
const { sendFriendRequest, updateFriendRequestState, friendRequests } =
useUserDetails();
const { showErrorToast } = useToast();
const handleClickAddFriend = () => {
setIsAddingFriend(true);
sendFriendRequest(friendCode)
.then(() => {
setFriendCode("");
})
.catch(() => {
showErrorToast("Não foi possível enviar o pedido de amizade");
})
.finally(() => {
setIsAddingFriend(false);
});
};
const resetAndClose = () => {
setFriendCode("");
closeModal();
};
const handleClickRequest = (userId: string) => {
resetAndClose();
navigate(`/user/${userId}`);
};
const handleClickSeeProfile = () => {
resetAndClose();
navigate(`/user/${friendCode}`);
};
const handleClickCancelFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "CANCEL").catch(() => {
showErrorToast("Falha ao cancelar convite");
});
};
const handleClickAcceptFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "ACCEPTED").catch(() => {
showErrorToast("Falha ao aceitar convite");
});
};
const handleClickRefuseFriendRequest = (userId: string) => {
updateFriendRequestState(userId, "REFUSED").catch(() => {
showErrorToast("Falha ao recusar convite");
});
};
return (
<>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
gap: `${SPACING_UNIT}px`,
}}
>
<TextField
label={t("friend_code")}
value={friendCode}
minLength={8}
maxLength={8}
containerProps={{ style: { width: "100%" } }}
onChange={(e) => setFriendCode(e.target.value)}
/>
<Button
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="button"
onClick={handleClickAddFriend}
>
{isAddingFriend ? t("sending") : t("add")}
</Button>
<Button
onClick={handleClickSeeProfile}
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="button"
>
{t("see_profile")}
</Button>
</div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h3>Pendentes</h3>
{friendRequests?.map((request) => {
return (
<UserFriendRequest
key={request.id}
displayName={request.displayName}
isRequestSent={request.type === "SENT"}
profileImageUrl={request.profileImageUrl}
userId={request.id}
onClickAcceptRequest={handleClickAcceptFriendRequest}
onClickCancelRequest={handleClickCancelFriendRequest}
onClickRefuseRequest={handleClickRefuseFriendRequest}
onClickRequest={handleClickRequest}
/>
);
})}
</div>
</>
);
};

View File

@ -1,4 +1,4 @@
import { SPACING_UNIT, vars } from "../../theme.css";
import { SPACING_UNIT, vars } from "../../../theme.css";
import { style } from "@vanilla-extract/css";
export const profileContentBox = style({

View File

@ -0,0 +1,58 @@
import { Button, Modal } from "@renderer/components";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { UserFriendModalAddFriend } from "./user-friend-modal-add-friend";
export interface UserAddFriendsModalProps {
visible: boolean;
onClose: () => void;
}
export const UserFriendModal = ({
visible,
onClose,
}: UserAddFriendsModalProps) => {
const { t } = useTranslation("user_profile");
const tabs = [t("add_friends"), t("friends_list")];
const [currentTabIndex, setCurrentTabIndex] = useState(0);
const renderTab = () => {
if (currentTabIndex == 0) {
return <UserFriendModalAddFriend closeModal={onClose} />;
}
return <></>;
};
return (
<Modal visible={visible} title={t("friends")} onClose={onClose}>
<div
style={{
display: "flex",
width: "500px",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<section style={{ display: "flex", gap: `${SPACING_UNIT}px` }}>
{tabs.map((tab, index) => {
return (
<Button
key={tab}
theme={index === currentTabIndex ? "primary" : "outline"}
onClick={() => setCurrentTabIndex(index)}
>
{tab}
</Button>
);
})}
</section>
<h2>{tabs[currentTabIndex]}</h2>
{renderTab()}
</div>
</Modal>
);
};