Skip to content

Commit

Permalink
[FEQ] Display name, balance and limits (#12916)
Browse files Browse the repository at this point in the history
* chore: removed responsive root

* chore: reverted old changes

* chore: backup

* chore: backup

* chore: test build

* feat: added my profile name, content

* chore: re-added deriv/utils to p2p-v2

* chore: backup

* chore: resolved code reviews

* chore: backup

* chore: developed responsive view for profile stats

* feat: added responsive screen for my-profile

* chore: added documentation for useadvertiserstats

* refactor: added deriv-com/ui for p2p-v2, used text component

* chore: removed package-lock in p2p-v2

* chore: removed package-lock in p2p-v2

* chore: reverted test changes on useauthorize

* chore: updated deriv-ui, resolved code reviews
  • Loading branch information
adrienne-deriv authored Jan 23, 2024
1 parent 267fb5d commit 2aac4cf
Show file tree
Hide file tree
Showing 45 changed files with 756 additions and 19 deletions.
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const useAdvertiserInfo = (id?: string) => {
is_listed,
is_online,
show_name,
created_time,
} = advertiser_info;

return {
Expand All @@ -43,8 +42,6 @@ const useAdvertiserInfo = (id?: string) => {
is_online: Boolean(is_online),
/** When true, the advertiser's real name will be displayed on to other users on adverts and orders. */
show_name: Boolean(show_name),
/** The epoch time that the client became an advertiser. */
created_time: new Date(created_time),
};
}, [data?.p2p_advertiser_info]);

Expand Down
2 changes: 2 additions & 0 deletions packages/p2p-v2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"start": "rimraf dist && npm run test && npm run serve"
},
"dependencies": {
"@deriv-com/ui": "0.0.1-beta.5",
"@deriv/api": "^1.0.0",
"@deriv/integration": "^1.0.0",
"@deriv/react-joyride": "^2.6.2",
Expand All @@ -24,6 +25,7 @@
"react-dom": "^17.0.2",
"react-i18next": "^11.11.0",
"react-router-dom": "^5.2.0",
"react-simple-star-rating": "4.0.4",
"usehooks-ts": "^2.7.0"
},
"devDependencies": {
Expand Down
12 changes: 12 additions & 0 deletions packages/p2p-v2/src/components/AdvertiserName/AdvertiserName.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.p2p-v2-advertiser-name {
display: grid;
grid-gap: 1.6rem;
grid-template-columns: min-content auto max-content;

&__details {
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.4rem;
}
}
37 changes: 37 additions & 0 deletions packages/p2p-v2/src/components/AdvertiserName/AdvertiserName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { Avatar } from '../Avatar';
import { useAdvertiserStats, useDevice } from '../../hooks';
import AdvertiserNameStats from './AdvertiserNameStats';
import AdvertiserNameBadges from './AdvertiserNameBadges';
import AdvertiserNameToggle from './AdvertiserNameToggle';
import { Text } from '@deriv-com/ui/dist/components/Text';
import './AdvertiserName.scss';

const AdvertiserName = () => {
const { data: advertiserStats, isLoading } = useAdvertiserStats();
const { isDesktop } = useDevice();

if (isLoading || !advertiserStats) return <h1>Loading...</h1>;

return (
<div className='p2p-v2-advertiser-name'>
<Avatar name={advertiserStats.name || ''} />
<div className='p2p-v2-advertiser-name__details'>
<Text size='md' weight='bold'>
{advertiserStats.name}{' '}
{advertiserStats.show_name && (
<Text color='less-prominent' size='sm'>
({advertiserStats.fullName})
</Text>
)}
</Text>
<AdvertiserNameStats />
<AdvertiserNameBadges />
</div>
{isDesktop && <AdvertiserNameToggle />}
</div>
);
};
AdvertiserName.displayName = 'AdvertiserName';

export default AdvertiserName;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.p2p-v2-advertiser-name-badges {
display: flex;
gap: 0.4rem;
padding: 0.4rem 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import { useAdvertiserStats } from '../../hooks';
import { Badge } from '../Badge';
import './AdvertiserNameBadges.scss';

/**
* This component is used to show an advertiser's badge, for instance:
* +100 Trades, ID verified, Address not verified, etc
*
* Use cases are usually in My Profile page and Advertiser page used under the advertiser's name
*/
const AdvertiserNameBadges = () => {
const { data: advertiserStats, isLoading } = useAdvertiserStats();

if (isLoading || !advertiserStats) return <h1>Loading...</h1>;

const { isAddressVerified, isIdentityVerified, totalOrders } = advertiserStats;

return (
<div className='p2p-v2-advertiser-name-badges'>
{totalOrders >= 100 && <Badge label='100+' status='trades' variant='warning' />}
<Badge
label='ID'
status={isIdentityVerified ? 'verified' : 'not verified'}
variant={isIdentityVerified ? 'success' : 'general'}
/>
<Badge
label='Address'
status={isAddressVerified ? 'verified' : 'not verified'}
variant={isAddressVerified ? 'success' : 'general'}
/>
</div>
);
};
AdvertiserNameBadges.displayName = 'AdvertiserNameBadges';

export default AdvertiserNameBadges;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.p2p-v2-advertiser-name-stats {
display: flex;
align-items: center;

@include mobile {
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 2rem;
}

& div {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 0 0.8rem;
border-left: 1px solid #f2f3f4;

@include mobile {
border-left: none;
padding: 0;
}

&:first-child {
padding-left: 0;
padding-right: 0.8rem;
border-left: none;
}
}

&__rating {
display: flex;
gap: 0.5rem;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import { useAdvertiserStats, useDevice } from '../../hooks';
import { StarRating } from '../StarRating';
import ThumbUpIcon from '../../public/ic-thumb-up.svg';
import BlockedUserOutlineIcon from '../../public/ic-user-blocked-outline.svg';
import { Text } from '@deriv-com/ui/dist/components/Text';
import './AdvertiserNameStats.scss';

/**
* This component is to show an advertiser's stats, in UI its commonly used under an advertiser's name
* Example:
* Joined 2d | Not rated yet | x x x x x (5 ratings)
*
* Use cases are to show this in My Profile and Advertiser page
*/
const AdvertiserNameStats = () => {
const { data: advertiserStats, isLoading } = useAdvertiserStats();
const { isMobile } = useDevice();

// TODO: Use Skeleton loader here
if (isLoading || !advertiserStats) return <h1>Loading...</h1>;

const { blocked_by_count, daysSinceJoined, rating_average, rating_count, recommended_average } = advertiserStats;

return (
<div className='p2p-v2-advertiser-name-stats'>
<div>
<Text color='less-prominent' size='sm'>
Joined {daysSinceJoined}d
</Text>
</div>
{!rating_average && (
<div>
<Text color='less-prominent' size='sm'>
Not rated yet
</Text>
</div>
)}
{rating_average && (
<>
<div>
<div className='p2p-v2-advertiser-name-stats__rating'>
{isMobile && (
<Text color='less-prominent' size='sm'>
({rating_average})
</Text>
)}
<StarRating ratingValue={rating_average} />
<Text color='less-prominent' size='sm'>
({rating_count} ratings)
</Text>
</div>
</div>
<div>
<ThumbUpIcon />
<Text color='less-prominent' size='sm'>
{recommended_average || 0}%
</Text>
</div>
</>
)}
<div>
<BlockedUserOutlineIcon />
<Text color='less-prominent' size='sm'>
{blocked_by_count}
</Text>
</div>
</div>
);
};
AdvertiserNameStats.displayName = 'AdvertiserNameStats';

export default AdvertiserNameStats;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.p2p-v2-advertiser-name-toggle {
display: flex;
gap: 0.8rem;

@include mobile {
justify-content: space-between;
}

&__label {
display: flex;
flex-direction: column;

&-real-name {
font-size: 1rem;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { memo, useEffect, useState } from 'react';
import { p2p } from '@deriv/api';
import { Text } from '@deriv-com/ui/dist/components/Text';
import { useAdvertiserStats } from '../../hooks';
import { ToggleSwitch } from '../ToggleSwitch';
import './AdvertiserNameToggle.scss';

type TAdvertiserNameToggle = {
onToggle?: (shouldShowRealName: boolean) => void;
};
const AdvertiserNameToggle = memo(({ onToggle }: TAdvertiserNameToggle) => {
const { data: advertiserInfo } = useAdvertiserStats();
const [shouldShowRealName, setShouldShowRealName] = useState(false);
const { mutate: advertiserUpdate } = p2p.advertiser.useUpdate();

useEffect(() => {
setShouldShowRealName(advertiserInfo?.show_name || false);
}, [advertiserInfo?.show_name]);

const onToggleShowRealName = () => {
advertiserUpdate({
show_name: !shouldShowRealName ? 1 : 0,
});
setShouldShowRealName(!shouldShowRealName);
onToggle?.(!shouldShowRealName);
};

return (
<div className='p2p-v2-advertiser-name-toggle'>
<div className='p2p-v2-advertiser-name-toggle__label'>
<Text lineHeight='lg' size='sm'>
Show my real name
</Text>
<Text className='p2p-v2-advertiser-name-toggle__label-real-name' color='less-prominent' lineHeight='xs'>
{advertiserInfo?.fullName}
</Text>
</div>
<ToggleSwitch onChange={onToggleShowRealName} value={shouldShowRealName} />
</div>
);
});
AdvertiserNameToggle.displayName = 'AdvertiserNameToggle';

export default AdvertiserNameToggle;
2 changes: 2 additions & 0 deletions packages/p2p-v2/src/components/AdvertiserName/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AdvertiserName } from './AdvertiserName';
export { default as AdvertiserNameToggle } from './AdvertiserNameToggle';
19 changes: 19 additions & 0 deletions packages/p2p-v2/src/components/Avatar/Avatar.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.p2p-v2-avatar {
border-radius: 5rem;
width: 6.4rem;
height: 6.4rem;
background-color: #ff444f;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
color: #ffffff;
line-height: 3rem;

@include mobile {
width: 4.2rem;
height: 4.2rem;
font-size: 1.6rem;
line-height: 1.8rem;
}
}
14 changes: 14 additions & 0 deletions packages/p2p-v2/src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React, { memo } from 'react';
import './Avatar.scss';

type TAvatarProps = {
name: string;
};

export const getShortNickname = (nickname: string): string => nickname?.substring(0, 2).toUpperCase();

const Avatar = ({ name }: TAvatarProps) => {
return <div className='p2p-v2-avatar'>{getShortNickname(name)}</div>;
};

export default memo(Avatar);
1 change: 1 addition & 0 deletions packages/p2p-v2/src/components/Avatar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Avatar } from './Avatar';
Loading

0 comments on commit 2aac4cf

Please sign in to comment.