feat: pending requests on modal

This commit is contained in:
Zamitto 2024-07-09 16:14:47 -03:00
parent 6ccbff0160
commit 6cc8e8f5fe
5 changed files with 244 additions and 55 deletions

View file

@ -1,11 +1,11 @@
import { Button, Modal, TextField } from "@renderer/components";
import { PendingFriendRequest } from "@types";
import * as styles from "./user.css";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useEffect, useState } from "react";
import { useToast, useUserDetails } from "@renderer/hooks";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { UserFriendPendingRequest } from "./user-friend-pending-request";
export interface UserAddFriendsModalProps {
visible: boolean;
@ -26,14 +26,11 @@ export const UserAddFriendsModal = ({
const navigate = useNavigate();
const { sendFriendRequest } = useUserDetails();
const { userDetails, sendFriendRequest } = useUserDetails();
const { showSuccessToast, showErrorToast } = useToast();
const handleAddFriend: React.FormEventHandler<HTMLFormElement> = async (
event
) => {
event.preventDefault();
const handleClickAddFriend = () => {
setIsAddingFriend(true);
sendFriendRequest(friendCode)
.then(() => {
@ -47,12 +44,46 @@ export const UserAddFriendsModal = ({
});
};
useEffect(() => {
setPendingRequests([]);
});
const handleClickFriend = (userId: string) => {
navigate(userId);
};
const handleSeeProfileClick = () => {
navigate(`profile/${friendCode}`);
useEffect(() => {
setPendingRequests([
{
AId: "abcd1234",
ADisplayName: "Punheta Master 123",
AProfileImageUrl:
"https://cdn.discordapp.com/avatars/1239959140785455295/4aff4b901c7a9f5f814b4379b6cfd58a.webp",
BId: "BMmNRmP3",
BDisplayName: "Hydra",
BProfileImageUrl: null,
},
{
AId: "BMmNRmP3",
ADisplayName: "Hydra",
AProfileImageUrl: null,
BId: "12345678",
BDisplayName: "Deyvis0n",
BProfileImageUrl: null,
},
]);
}, []);
const handleClickSeeProfile = () => {
// navigate(`profile/${friendCode}`);
};
const handleClickCancelFriendRequest = (userId: string) => {
console.log(userId);
};
const handleClickAcceptFriendRequest = (userId: string) => {
console.log(userId);
};
const handleClickRefuseFriendRequest = (userId: string) => {
console.log(userId);
};
const resetModal = () => {
@ -71,21 +102,26 @@ export const UserAddFriendsModal = ({
title={t("add_friends")}
onClose={cleanFormAndClose}
>
<form
onSubmit={handleAddFriend}
<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 * 3}px`,
width: "350px",
gap: `${SPACING_UNIT}px`,
}}
>
<TextField
label={t("friend_code")}
value={friendCode}
required
minLength={8}
maxLength={8}
containerProps={{ style: { width: "100%" } }}
@ -94,29 +130,62 @@ export const UserAddFriendsModal = ({
<Button
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="submit"
type="button"
onClick={handleClickAddFriend}
>
{isAddingFriend ? t("sending") : t("send")}
</Button>
<Button
onClick={handleSeeProfileClick}
onClick={handleClickSeeProfile}
disabled={isAddingFriend}
style={{ alignSelf: "end" }}
type="button"
>
{t("see_profile")}
</Button>
</form>
</div>
<div>
<div
style={{
display: "flex",
flexDirection: "column",
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h3>Pendentes</h3>
{pendingRequests.map((request) => {
if (request.AId === userDetails?.id) {
return (
<p>
{request.AId} - {request.BId}
</p>
<UserFriendPendingRequest
key={request.AId}
displayName={request.BDisplayName}
isRequestSent={true}
profileImageUrl={request.BProfileImageUrl}
userId={request.BId}
onClickAcceptRequest={handleClickAcceptFriendRequest}
onClickCancelRequest={handleClickCancelFriendRequest}
onClickRefuseRequest={handleClickRefuseFriendRequest}
onClickRequest={handleClickFriend}
/>
);
}
return (
<UserFriendPendingRequest
key={request.BId}
displayName={request.ADisplayName}
isRequestSent={false}
profileImageUrl={request.AProfileImageUrl}
userId={request.AId}
onClickAcceptRequest={handleClickAcceptFriendRequest}
onClickCancelRequest={handleClickCancelFriendRequest}
onClickRefuseRequest={handleClickRefuseFriendRequest}
onClickRequest={handleClickFriend}
/>
);
})}
</div>
</div>
</Modal>
</>
);

View file

@ -17,7 +17,6 @@ import { buildGameDetailsPath, steamUrlBuilder } from "@renderer/helpers";
import {
PersonAddIcon,
PersonIcon,
PlusCircleIcon,
TelescopeIcon,
} from "@primer/octicons-react";
import { Button, Link } from "@renderer/components";
@ -79,6 +78,10 @@ export function UserContent({
setShowEditProfileModal(true);
};
const handleOnClickFriend = (userId: string) => {
console.log(userId);
};
const handleConfirmSignout = async () => {
await signOut();
@ -359,6 +362,7 @@ export function UserContent({
>
<button
className={cn(styles.friendListItem, styles.profileContentBox)}
onClick={() => handleOnClickFriend("123abcde")}
>
<img
className={styles.friendProfileIcon}
@ -373,11 +377,15 @@ export function UserContent({
<button
className={cn(styles.friendListItem, styles.profileContentBox)}
>
{userProfile.profileImageUrl ? (
<img
className={styles.friendProfileIcon}
src={userProfile.profileImageUrl || ""}
alt={"Hydra Launcher"}
alt={userProfile.displayName}
src={userProfile.profileImageUrl}
/>
) : (
<PersonIcon size={48} />
)}
<h4>Hydra Launcher</h4>
</button>
</div>

View file

@ -0,0 +1,81 @@
import { CheckCircleIcon, XCircleIcon } from "@primer/octicons-react";
import { SPACING_UNIT, vars } from "@renderer/theme.css";
import * as styles from "./user.css";
import cn from "classnames";
export interface UserFriendPendingRequestProps {
userId: string;
profileImageUrl: string | null;
displayName: string;
isRequestSent: boolean;
onClickCancelRequest: (userId: string) => void;
onClickAcceptRequest: (userId: string) => void;
onClickRefuseRequest: (userId: string) => void;
onClickRequest: (userId: string) => void;
}
export const UserFriendPendingRequest = ({
userId,
profileImageUrl,
displayName,
isRequestSent,
onClickCancelRequest,
onClickAcceptRequest,
onClickRefuseRequest,
onClickRequest,
}: UserFriendPendingRequestProps) => {
return (
<button
type="button"
className={cn(styles.friendListItem, styles.profileContentBox)}
onClick={() => onClickRequest(userId)}
style={{
display: "flex",
flexDirection: "row",
gap: `${SPACING_UNIT}px`,
alignItems: "center",
}}
>
<img
style={{ width: "32px", borderRadius: "50%" }}
src={profileImageUrl || ""}
/>
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
flex: "1",
minWidth: 0,
gap: `${SPACING_UNIT / 2}px`,
}}
>
<h4>{displayName}</h4>
<small>{isRequestSent ? "Pedido enviado" : "Pedido recebido"}</small>
</div>
{isRequestSent ? (
<button
style={{ color: vars.color.body }}
onClick={() => onClickCancelRequest(userId)}
>
<XCircleIcon size={28} className={styles.cancelRequestButton} />
</button>
) : (
<>
<button
className={styles.acceptRequestButton}
onClick={() => onClickAcceptRequest(userId)}
>
<CheckCircleIcon size={28} />
</button>
<button
className={styles.cancelRequestButton}
onClick={() => onClickRefuseRequest(userId)}
>
<XCircleIcon size={28} />
</button>
</>
)}
</button>
);
};

View file

@ -245,3 +245,30 @@ export const profileBackground = style({
top: "0",
borderRadius: "4px",
});
export const friendRequestItem = style({
color: vars.color.body,
":hover": {
backgroundColor: "rgba(255, 255, 255, 0.15)",
},
});
export const acceptRequestButton = style({
cursor: "pointer",
color: vars.color.body,
width: "28px",
height: "28px",
":hover": {
color: vars.color.success,
},
});
export const cancelRequestButton = style({
cursor: "pointer",
color: vars.color.body,
width: "28px",
height: "28px",
":hover": {
color: vars.color.danger,
},
});

View file

@ -277,7 +277,11 @@ export interface UserFriend {
export interface PendingFriendRequest {
AId: string;
ADisplayName: string;
AProfileImageUrl: string | null;
BId: string;
BDisplayName: string;
BProfileImageUrl: string | null;
}
export interface UserProfile {