Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
feat: add friend notification
Browse files Browse the repository at this point in the history
  • Loading branch information
pupixipup committed Feb 24, 2024
1 parent 4db1416 commit b5e9f4c
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 18 deletions.
20 changes: 13 additions & 7 deletions client/src/app/(main)/[username]/profile/ui/friends/friends.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ArrowRightIcon } from '@/shared/assets';
import { useState } from 'react';
import layoutStyles from '../../layout.module.scss';
import { FriendsModal } from './friends-modal';
import { IUserBase } from '@teameights/types';

export const Friends = () => {
const { username } = useParams();
Expand All @@ -26,14 +27,19 @@ export const Friends = () => {
</Typography>
);
if (friendshipList.length) {
const friendsList = friendshipList
.map(friendship => {
const friendsList = friendshipList.reduce<IUserBase[]>((accumulator, friendship) => {
if (friendship.status === 'accepted') {
const { receiver, creator } = friendship;
if (receiver.id !== user?.id) return receiver;
return creator;
})
.filter((friend, i, arr) => arr.findIndex(item => item.id === friend.id) === i);
// filter out duplicates, since there can be two similar friendships with different creators
const friend = receiver.id !== user?.id ? receiver : creator;

const existingFriendIndex = accumulator.findIndex(item => item?.id === friend.id);
// filter out duplicates, since there can be two similar friendships with different creators
if (existingFriendIndex === -1) {
accumulator.push(friend);
}
}
return accumulator;
}, []);
const noun = friendsList.length === 1 ? 'friend' : 'friends';
friendsContainer = (
<Flex direction='column'>
Expand Down
29 changes: 18 additions & 11 deletions client/src/features/friend-button/friend-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import { useHandleFriendshipRequest } from '@/entities/session/api/useHandleFrie
interface FriendButtonProps {
myId?: number;
userId: number;
short?: boolean;
size?: 'm' | 'l' | 's';
}

export const FriendButton = ({ myId, userId }: FriendButtonProps) => {
function getText(text: string, short: boolean) {
if (short) return text;
return text + ' friend';
}

export const FriendButton = ({ myId, userId, short = false, size = 'm' }: FriendButtonProps) => {
const { mutate: addFriend } = useAddFriend(myId, userId);
const { mutate: removeFriend } = useRemoveFriend(userId);
const { mutate: declineFriend } = useHandleFriendshipRequest(myId, userId, 'rejected');
Expand All @@ -28,10 +35,10 @@ export const FriendButton = ({ myId, userId }: FriendButtonProps) => {
friendship.status !== 'rejected'
);

if (!ourFriendshipIndex || ourFriendshipIndex === -1) {
if (ourFriendshipIndex === undefined || ourFriendshipIndex === -1) {
return (
<Button onClick={() => addFriend()} size={'m'}>
Add friend
<Button onClick={() => addFriend()} size={size}>
{getText('Add', short)}
<UserPlusIcon />
</Button>
);
Expand All @@ -45,22 +52,22 @@ export const FriendButton = ({ myId, userId }: FriendButtonProps) => {
switch (friendshipStatus) {
case 'accepted':
return (
<Button onClick={() => removeFriend()} size={'m'} typeBtn='danger'>
Remove friend
<Button onClick={() => removeFriend()} size={size} typeBtn='danger'>
{getText('Remove', short)}
</Button>
);
case 'pending':
return ourFriendship.creator.id !== myId ? (
<>
<Button onClick={() => acceptFriend()} size={'m'} typeBtn='primary'>
Accept friend
<Button onClick={() => acceptFriend()} size={size} typeBtn='primary'>
{getText('Accept', short)}
</Button>
<Button onClick={() => declineFriend()} size={'m'} typeBtn='danger'>
Reject friend
<Button onClick={() => declineFriend()} size={size} typeBtn='danger'>
{getText('Reject', short)}
</Button>
</>
) : (
<Button size='m' typeBtn='secondary'>
<Button size={size} typeBtn='secondary'>
Pending
</Button>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';

import { Flex } from '@/shared/ui';
import { LightningIcon } from '@/shared/assets';
import { getElapsedTime } from '@/shared/lib';

import styles from './notification-item.module.scss';
import { IFriendNotification } from '@teameights/types';
import { FriendButton } from '@/features/friend-button';
import { useGetFriends } from '@/entities/session';

interface SystemNotificationProps {
notification: IFriendNotification;
}

/**
* SidebarFriendNotification component renders system notification content.
*
* @component
* @param {Object} props - The properties object.
* @param {SystemNotification} props.notification - The system notification object.
*
* @example
* <SidebarFriendNotification
* notification={systemNotificationObj}
* />
*/
export const SidebarFriendNotification: React.FC<SystemNotificationProps> = props => {
const { notification } = props;

const myId = notification.receiver.id;
const userId = notification.data.creator.id;
const { data: friendships } = useGetFriends(userId);

const isPending = friendships?.data.some(
friendship =>
(friendship.creator.id === myId || friendship.receiver.id === myId) &&
friendship.status === 'pending'
);

return (
<>
<Flex gap='12px'>
<div className={`${styles.messagePicture} ${styles.small}`}>
{!notification.read && <div className={styles.messageCircle} />}
<LightningIcon />
</div>
<Flex align='start' gap='12px' direction='column'>
<p className={styles.messageText}>
{notification.data.creator.username} sent you friend request!
</p>
{isPending && (
<Flex gap='8px'>
<FriendButton size='s' short={true} userId={userId} myId={myId} />
</Flex>
)}
</Flex>
</Flex>
<p className={styles.sendingTime}>{getElapsedTime(notification.createdAt)}</p>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@
opacity: 0.8;
}
}

.notification_button {
width: 85px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { SidebarSystemNotification } from './system-notification';

import styles from './notification-item.module.scss';
import { NotificationType } from '@teameights/types';
import { SidebarFriendNotification } from './friend-notification';

export interface NotificationProps {
/**
Expand Down Expand Up @@ -46,6 +47,8 @@ export const SidebarNotificationsItem: React.FC<NotificationProps> = props => {
switch (notification.type) {
case 'system':
return <SidebarSystemNotification notification={notification} />;
case 'friend_request':
return <SidebarFriendNotification notification={notification} />;
// case 'team_invite':
// return (
// <SidebarTeamInvatitionNotification
Expand Down

0 comments on commit b5e9f4c

Please sign in to comment.