mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 05:00:43 +10:00
Merge pull request #539 from sharetribe/profile-page-links
Make avatars into links to the user profile page
This commit is contained in:
commit
660b77f0a6
12 changed files with 192 additions and 120 deletions
|
|
@ -18,6 +18,10 @@
|
|||
/* Colors */
|
||||
background-image: linear-gradient(-180deg, #e16b56 0%, #c0392b 100%);
|
||||
color: var(--matterColorLight);
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,3 +171,13 @@ export const WithProfileImageUserLarge = {
|
|||
},
|
||||
group: 'avatar',
|
||||
};
|
||||
|
||||
export const WithoutProfileLink = {
|
||||
component: AvatarLarge,
|
||||
props: {
|
||||
user: userWithProfileImage,
|
||||
disableProfileLink: true,
|
||||
intl: fakeIntl,
|
||||
},
|
||||
group: 'avatar',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import { injectIntl, intlShape } from 'react-intl';
|
|||
import classNames from 'classnames';
|
||||
import * as propTypes from '../../util/propTypes';
|
||||
import { ensureUser, userDisplayName, userAbbreviatedName } from '../../util/data';
|
||||
import { ResponsiveImage, IconBannedUser } from '../../components/';
|
||||
import { ResponsiveImage, IconBannedUser, NamedLink } from '../../components/';
|
||||
|
||||
import css from './Avatar.css';
|
||||
|
||||
export const AvatarComponent = props => {
|
||||
const { rootClassName, className, user, intl } = props;
|
||||
const { rootClassName, className, user, disableProfileLink, intl } = props;
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const avatarUser = ensureUser(user);
|
||||
const isBannedUser = avatarUser.attributes.banned;
|
||||
|
|
@ -21,10 +21,36 @@ export const AvatarComponent = props => {
|
|||
|
||||
const displayName = userDisplayName(avatarUser, bannedUserDisplayName);
|
||||
const abbreviatedName = userAbbreviatedName(avatarUser, bannedUserAbbreviatedName);
|
||||
const rootProps = { className: classes, title: displayName };
|
||||
const linkProps = avatarUser.id
|
||||
? { name: 'ProfilePage', params: { id: avatarUser.id.uuid } }
|
||||
: { name: 'ProfileBasePage' };
|
||||
const hasProfileImage = avatarUser.profileImage && avatarUser.profileImage.id;
|
||||
const profileLinkEnabled = !disableProfileLink;
|
||||
|
||||
if (avatarUser.profileImage && avatarUser.profileImage.id) {
|
||||
if (isBannedUser) {
|
||||
return (
|
||||
<div className={classes} title={displayName}>
|
||||
<div {...rootProps}>
|
||||
<IconBannedUser className={css.bannedUserIcon} />
|
||||
</div>
|
||||
);
|
||||
} else if (hasProfileImage && profileLinkEnabled) {
|
||||
return (
|
||||
<NamedLink {...rootProps} {...linkProps}>
|
||||
<ResponsiveImage
|
||||
rootClassName={css.avatarImage}
|
||||
alt={displayName}
|
||||
image={avatarUser.profileImage}
|
||||
nameSet={[
|
||||
{ name: 'square-xlarge2x', size: '1x' },
|
||||
{ name: 'square-xlarge4x', size: '2x' },
|
||||
]}
|
||||
/>
|
||||
</NamedLink>
|
||||
);
|
||||
} else if (hasProfileImage) {
|
||||
return (
|
||||
<div {...rootProps}>
|
||||
<ResponsiveImage
|
||||
rootClassName={css.avatarImage}
|
||||
alt={displayName}
|
||||
|
|
@ -36,35 +62,39 @@ export const AvatarComponent = props => {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (isBannedUser) {
|
||||
} else if (profileLinkEnabled) {
|
||||
// Placeholder avatar (initials)
|
||||
return (
|
||||
<div className={classes} title={displayName}>
|
||||
<IconBannedUser className={css.bannedUserIcon} />
|
||||
</div>
|
||||
<NamedLink {...rootProps} {...linkProps}>
|
||||
<span className={css.initials}>{abbreviatedName}</span>
|
||||
</NamedLink>
|
||||
);
|
||||
} else {
|
||||
// Placeholder avatar (initials)
|
||||
return (
|
||||
<div className={classes} title={displayName}>
|
||||
<div {...rootProps}>
|
||||
<span className={css.initials}>{abbreviatedName}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const { string, oneOfType } = PropTypes;
|
||||
|
||||
AvatarComponent.defaultProps = {
|
||||
className: null,
|
||||
rootClassName: null,
|
||||
user: null,
|
||||
disableProfileLink: false,
|
||||
};
|
||||
|
||||
const { string, oneOfType, bool } = PropTypes;
|
||||
|
||||
AvatarComponent.propTypes = {
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
user: oneOfType([propTypes.user, propTypes.currentUser]),
|
||||
|
||||
disableProfileLink: bool,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ const TopbarDesktop = props => {
|
|||
const profileMenu = isAuthenticated ? (
|
||||
<Menu>
|
||||
<MenuLabel className={css.profileMenuLabel} isOpenClassName={css.profileMenuIsOpen}>
|
||||
<Avatar className={css.avatar} user={currentUser} />
|
||||
<Avatar className={css.avatar} user={currentUser} disableProfileLink />
|
||||
</MenuLabel>
|
||||
<MenuContent className={css.profileMenuContent}>
|
||||
<MenuItem key="ManageListingsPage">
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ export class CheckoutPageComponent extends Component {
|
|||
/>
|
||||
</div>
|
||||
<div className={classNames(css.avatarWrapper, css.avatarMobile)}>
|
||||
<AvatarMedium user={currentAuthor} />
|
||||
<AvatarMedium user={currentAuthor} disableProfileLink />
|
||||
</div>
|
||||
<div className={css.bookListingContainer}>
|
||||
<div className={css.heading}>
|
||||
|
|
@ -348,7 +348,7 @@ export class CheckoutPageComponent extends Component {
|
|||
/>
|
||||
</div>
|
||||
<div className={css.avatarWrapper}>
|
||||
<AvatarMedium user={currentAuthor} />
|
||||
<AvatarMedium user={currentAuthor} disableProfileLink />
|
||||
</div>
|
||||
<div className={css.detailsHeadings}>
|
||||
<h2 className={css.detailsTitle}>{listingTitle}</h2>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ exports[`CheckoutPage matches snapshot 1`] = `
|
|||
className=""
|
||||
>
|
||||
<AvatarMedium
|
||||
disableProfileLink={true}
|
||||
user={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
@ -132,6 +133,7 @@ exports[`CheckoutPage matches snapshot 1`] = `
|
|||
</div>
|
||||
<div>
|
||||
<AvatarMedium
|
||||
disableProfileLink={true}
|
||||
user={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.itemLink {
|
||||
flex: 1;
|
||||
|
||||
/* Layout */
|
||||
display: flex;
|
||||
|
||||
|
|
|
|||
|
|
@ -127,34 +127,38 @@ export const InboxItem = props => {
|
|||
});
|
||||
|
||||
return (
|
||||
<NamedLink
|
||||
className={linkClasses}
|
||||
name={isOrder ? 'OrderDetailsPage' : 'SaleDetailsPage'}
|
||||
params={{ id: tx.id.uuid }}
|
||||
>
|
||||
<div className={css.item}>
|
||||
<div className={css.itemAvatar}>
|
||||
<Avatar user={otherUser} />
|
||||
</div>
|
||||
<div className={css.rowNotificationDot}>{rowNotificationDot}</div>
|
||||
<div className={css.itemInfo}>
|
||||
<div className={classNames(css.itemUsername, stateData.nameClassName)}>
|
||||
{otherUserDisplayName}
|
||||
<NamedLink
|
||||
className={linkClasses}
|
||||
name={isOrder ? 'OrderDetailsPage' : 'SaleDetailsPage'}
|
||||
params={{ id: tx.id.uuid }}
|
||||
>
|
||||
<div className={css.rowNotificationDot}>{rowNotificationDot}</div>
|
||||
<div className={css.itemInfo}>
|
||||
<div className={classNames(css.itemUsername, stateData.nameClassName)}>
|
||||
{otherUserDisplayName}
|
||||
</div>
|
||||
<div className={classNames(css.bookingInfo, stateData.bookingClassName)}>
|
||||
{bookingStart.short} - {bookingEnd.short}
|
||||
<span className={css.itemPrice}>{price}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classNames(css.bookingInfo, stateData.bookingClassName)}>
|
||||
{bookingStart.short} - {bookingEnd.short}
|
||||
<span className={css.itemPrice}>{price}</span>
|
||||
<div className={css.itemState}>
|
||||
<div className={classNames(css.stateName, stateData.stateClassName)}>
|
||||
{stateData.state}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(css.lastTransitionedAt, stateData.lastTransitionedAtClassName)}
|
||||
title={lastTransitionedAt.long}
|
||||
>
|
||||
{lastTransitionedAt.short}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={css.itemState}>
|
||||
<div className={classNames(css.stateName, stateData.stateClassName)}>{stateData.state}</div>
|
||||
<div
|
||||
className={classNames(css.lastTransitionedAt, stateData.lastTransitionedAtClassName)}
|
||||
title={lastTransitionedAt.long}
|
||||
>
|
||||
{lastTransitionedAt.short}
|
||||
</div>
|
||||
</div>
|
||||
</NamedLink>
|
||||
</NamedLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -292,18 +292,17 @@ exports[`InboxPage matches snapshot 1`] = `
|
|||
`;
|
||||
|
||||
exports[`InboxPage matches snapshot 2`] = `
|
||||
<a
|
||||
className=""
|
||||
href="/order/order-1/details"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title={null}
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
<a
|
||||
className=""
|
||||
href="/u/provider-user-id"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title="provider-user-id display name"
|
||||
>
|
||||
<span
|
||||
|
|
@ -311,48 +310,56 @@ exports[`InboxPage matches snapshot 2`] = `
|
|||
>
|
||||
provider-user-id abbreviated name
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
/>
|
||||
<div
|
||||
className={undefined}
|
||||
<a
|
||||
className=""
|
||||
href="/order/order-1/details"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title={null}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
provider-user-id display name
|
||||
</div>
|
||||
className={undefined}
|
||||
/>
|
||||
<div
|
||||
className=""
|
||||
className={undefined}
|
||||
>
|
||||
2017-02-15
|
||||
-
|
||||
2017-02-16
|
||||
<span
|
||||
className={undefined}
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
10
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
InboxPage.stateRequested
|
||||
provider-user-id display name
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
2017-02-15
|
||||
-
|
||||
2017-02-16
|
||||
<span
|
||||
className={undefined}
|
||||
>
|
||||
10
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
title="2017-01-15 00:00"
|
||||
className={undefined}
|
||||
>
|
||||
2017-01-15
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
InboxPage.stateRequested
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
title="2017-01-15 00:00"
|
||||
>
|
||||
2017-01-15
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`InboxPage matches snapshot 3`] = `
|
||||
|
|
@ -647,18 +654,17 @@ exports[`InboxPage matches snapshot 3`] = `
|
|||
`;
|
||||
|
||||
exports[`InboxPage matches snapshot 4`] = `
|
||||
<a
|
||||
className=""
|
||||
href="/sale/sale-1/details"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title={null}
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
<a
|
||||
className=""
|
||||
href="/u/customer-user-id"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title="customer-user-id display name"
|
||||
>
|
||||
<span
|
||||
|
|
@ -666,50 +672,58 @@ exports[`InboxPage matches snapshot 4`] = `
|
|||
>
|
||||
customer-user-id abbreviated name
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
<a
|
||||
className=""
|
||||
href="/sale/sale-1/details"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
title={null}
|
||||
>
|
||||
<div
|
||||
className={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
customer-user-id display name
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
2017-02-15
|
||||
-
|
||||
2017-02-16
|
||||
<span
|
||||
<div
|
||||
className={undefined}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
9
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={undefined}
|
||||
>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
InboxPage.statePending
|
||||
customer-user-id display name
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
2017-02-15
|
||||
-
|
||||
2017-02-16
|
||||
<span
|
||||
className={undefined}
|
||||
>
|
||||
9
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
title="2017-01-15 00:00"
|
||||
className={undefined}
|
||||
>
|
||||
2017-01-15
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
InboxPage.statePending
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
title="2017-01-15 00:00"
|
||||
>
|
||||
2017-01-15
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export const ProfilePageComponent = props => {
|
|||
|
||||
const asideContent = (
|
||||
<div className={css.asideContent}>
|
||||
<AvatarLarge className={css.avatar} user={user} />
|
||||
<AvatarLarge className={css.avatar} user={user} disableProfileLink />
|
||||
<h1 className={css.mobileHeading}>
|
||||
{displayName ? (
|
||||
<FormattedMessage id="ProfilePage.mobileHeading" values={{ name: displayName }} />
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ exports[`ProfilePage matches snapshot 1`] = `
|
|||
>
|
||||
<div>
|
||||
<AvatarLarge
|
||||
disableProfileLink={true}
|
||||
user={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ class ProfileSettingsFormComponent extends Component {
|
|||
});
|
||||
const avatarComponent =
|
||||
!fileUploadInProgress && profileImage.imageId ? (
|
||||
<Avatar className={avatarClasses} user={transientUser} />
|
||||
<Avatar className={avatarClasses} user={transientUser} disableProfileLink />
|
||||
) : null;
|
||||
|
||||
const chooseAvatarLabel =
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue