Skip to content

Commit

Permalink
feat(profile): Show one, all, or none featured notices on contributor…
Browse files Browse the repository at this point in the history
… profile
  • Loading branch information
lutangar committed Nov 10, 2020
1 parent 110a06f commit 73aceae
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 45 deletions.
15 changes: 10 additions & 5 deletions src/app/lmem/contributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ interface Picture {

export type ContributorId = number;

export interface PinnedNotice {
sort?: number;
matchingUrl: string;
noticeId: number;
noticeUrl: string;
}

interface Contribution {
example: {
matchingUrl: string;
noticeId: number;
noticeUrl: string;
};
example: PinnedNotice; // @deprecated use `pinnedNotices` instead
starred: PinnedNotice; // @deprecated use `pinnedNotices` instead
pinnedNotices: PinnedNotice[];
}

export interface BaseContributor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import styled from 'styled-components';
import { ProfileNoticeListItem } from './ProfileNoticeListItem';

const FeaturedNotice = styled(ProfileNoticeListItem).attrs({ featured: true })`
margin-bottom: 40px;
img {
margin-bottom: 10px;
box-shadow: 4px 4px 18px 0 rgba(0, 0, 0, 0.3);
Expand Down
53 changes: 53 additions & 0 deletions src/app/profiles/App/Pages/Profiles/Profile/FeaturedNotices.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import styled from 'styled-components';
import FeaturedNotice from './FeaturedNotice';
import { LoadingRotator } from 'components/atoms';
import { LoadingBig } from 'components/atoms/icons';
import { NoticeWithContributor } from 'app/lmem/notice';
import { StatefulContributor } from 'app/lmem/contributor';

export interface FeaturedNoticesProps {
loading?: boolean;
notices: NoticeWithContributor[];
seeNoticeInContext: (notice: NoticeWithContributor) => () => void;
contributor?: StatefulContributor;
className?: string;
}

const FeatureNoticesContainer = styled.section`
margin-bottom: 40px;
`;

const FeaturedNotices = ({
loading,
notices,
seeNoticeInContext,
className
}: FeaturedNoticesProps) => {
if (typeof loading === 'undefined') {
return null;
}

return (
<FeatureNoticesContainer className={className}>
{loading ? (
<LoadingRotator>
<LoadingBig />
</LoadingRotator>
) : (
<>
{notices.map(notice => (
<FeaturedNotice
key={notice.id}
loading={false}
notice={notice}
seeInContext={seeNoticeInContext(notice)}
/>
))}
</>
)}
</FeatureNoticesContainer>
);
};

export default FeaturedNotices;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { Title2 } from 'components/atoms';
import { StatefulContributor } from 'app/lmem/contributor';

export interface FeaturedNoticesTitleProps {
plural: boolean;
contributor?: StatefulContributor;
className?: string;
}

const FeaturedNoticesTitle = ({
plural,
contributor,
className
}: FeaturedNoticesTitleProps) => (
<Title2 className={className}>
{`L${plural ? 'es' : 'a'} contribution${plural ? 's' : ''} phare${
plural ? 's' : ''
} ${contributor && `de ${contributor.name}`}`}
</Title2>
);

export default FeaturedNoticesTitle;
66 changes: 62 additions & 4 deletions src/app/profiles/App/Pages/Profiles/Profile/Profile.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ storiesOf('Profile/Profile', module)
))
.add('Normal', () => (
<Profile
featuredNotice={generateStatefulNotice()}
featuredNotices={[generateStatefulNotice(), generateStatefulNotice()]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
Expand All @@ -43,7 +43,11 @@ storiesOf('Profile/Profile', module)
))
.add('loading', () => (
<Profile
featuredNotice={generateStatefulNotice()}
featuredNotices={[
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice()
]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
Expand All @@ -66,7 +70,11 @@ storiesOf('Profile/Profile', module)
))
.add('contributorsLoading', () => (
<Profile
featuredNotice={generateStatefulNotice()}
featuredNotices={[
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice()
]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
Expand All @@ -89,7 +97,11 @@ storiesOf('Profile/Profile', module)
))
.add('noticesLoading', () => (
<Profile
featuredNotice={generateStatefulNotice()}
featuredNotices={[
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice()
]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
Expand All @@ -109,4 +121,50 @@ storiesOf('Profile/Profile', module)
connected={false}
addToBrowser={action('addToBrowser')}
/>
))
.add('no featured notices', () => (
<Profile
featuredNotices={[]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice()
]}
noticesLoading={false}
subscribe={action('subscribe')}
unsubscribe={action('unsubscribe')}
fetchMoreNotices={action('fetchMoreNotices')}
fetchedAll={false}
contributor={generateStatefulContributor()}
contributors={[
generateStatefulContributor(),
generateStatefulContributor()
]}
connected={false}
addToBrowser={action('addToBrowser')}
/>
))
.add('1 featured notices', () => (
<Profile
featuredNotices={[generateStatefulNotice()]}
notices={[
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice(),
generateStatefulNotice()
]}
noticesLoading={false}
subscribe={action('subscribe')}
unsubscribe={action('unsubscribe')}
fetchMoreNotices={action('fetchMoreNotices')}
fetchedAll={false}
contributor={generateStatefulContributor()}
contributors={[
generateStatefulContributor(),
generateStatefulContributor()
]}
connected={false}
addToBrowser={action('addToBrowser')}
/>
));
24 changes: 14 additions & 10 deletions src/app/profiles/App/Pages/Profiles/Profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
TwoColumns
} from 'components/atoms';
import SimilarProfiles from '../../../SimilarProfiles';
import FeaturedNotice from './FeaturedNotice';
import ProfileIntro from './ProfileIntro';
import ProfileNoticeList from './ProfileNoticeList';
import CenterContainer from 'components/atoms/CenterContainer';
Expand All @@ -23,6 +22,8 @@ import {
AddToBrowserMessageBox,
PrivacyMessageBox
} from 'components/molecules/SidebarBox';
import FeaturedNotices from './FeaturedNotices';
import FeaturedNoticesTitle from './FeaturedNoticesTitle';

export const MainCol = styled.div`
${CenterContainer} {
Expand Down Expand Up @@ -111,7 +112,7 @@ export interface ProfileProps {
contributor?: StatefulContributor;
noticesLoading?: boolean;
notices: NoticeWithContributor[];
featuredNotice?: NoticeWithContributor;
featuredNotices: NoticeWithContributor[];
subscribe: (contributorId: ContributorId) => void;
unsubscribe: (contributorId: ContributorId) => void;
fetchMoreNotices: () => void | undefined;
Expand All @@ -126,7 +127,7 @@ export const Profile = ({
subscribe,
unsubscribe,
noticesLoading,
featuredNotice,
featuredNotices,
notices,
connected,
addToBrowser,
Expand Down Expand Up @@ -194,15 +195,18 @@ export const Profile = ({
unsubscribe={handleUnsubscribe(contributor)}
usernameAs={'h1'}
/>
<Title2>
La contribution phare {contributor && `de ${contributor.name}`}
</Title2>
<FeaturedNotice

{featuredNotices.length > 0 && (
<FeaturedNoticesTitle
contributor={contributor}
plural={featuredNotices.length > 1}
/>
)}
<FeaturedNotices
loading={noticesLoading}
notice={featuredNotice}
seeInContext={handleSeeNoticeInContext(featuredNotice)}
notices={featuredNotices}
seeNoticeInContext={handleSeeNoticeInContext}
/>

<Title2>Ses dernières contributions</Title2>
<ProfileNoticeList
loading={noticesLoading}
Expand Down
19 changes: 9 additions & 10 deletions src/app/profiles/App/Pages/Profiles/Profile/ProfileNoticeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,15 @@ export const ProfileNoticeListContent = ({
{((notices.length === 0 && !loading) || fetchedAll) && (
<div>Pas d&apos;autres contributions</div>
)}
{notices &&
notices.map(notice => (
<ProfileNoticeListItem
loading={false}
notice={notice}
seeInContext={seeNoticeInContext(notice)}
key={notice.id}
/>
))}
{notices && notices.length && !loading && !fetchedAll && (
{notices.map(notice => (
<ProfileNoticeListItem
loading={false}
notice={notice}
seeInContext={seeNoticeInContext(notice)}
key={notice.id}
/>
))}
{notices.length > 0 && !loading && !fetchedAll && (
<CenterContainer>
<Link onClick={fetchMoreNotices}>Voir plus</Link>
</CenterContainer>
Expand Down
8 changes: 4 additions & 4 deletions src/app/profiles/App/Pages/Profiles/Profile/withConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { subscribe, unsubscribe } from 'app/actions/subscription';
import {
areContributorNoticesAllFetched,
getContributorFromRouteParam,
getContributorNoticesButFeaturedOne,
getFeaturedNotice,
getContributorNoticesButFeaturedOnes,
getFeaturedNotices,
getStatefulContributors
} from 'app/profiles/store/selectors';
import { areNoticesLoading } from 'app/profiles/store/selectors/notices';
Expand All @@ -27,9 +27,9 @@ const mapStateToProps = (
loading: areContributorsLoading(state),
contributor: getContributorFromRouteParam(state, props),
contributors: getStatefulContributors(state),
featuredNotice: getFeaturedNotice(state, props),
featuredNotices: getFeaturedNotices(state, props),
noticesLoading: areNoticesLoading(state),
notices: getContributorNoticesButFeaturedOne(state, props),
notices: getContributorNoticesButFeaturedOnes(state, props),
fetchedAll: (contributorId: ContributorId) =>
areContributorNoticesAllFetched(state, contributorId),
connected: isConnected(state),
Expand Down
23 changes: 13 additions & 10 deletions src/app/profiles/store/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,12 @@ export const getContributorFromRouteParam = createSelector(
(contributors, id) => findItemById<Contributor>(Number(id))(contributors)
);

export const getFeaturedNoticeId = createSelector(
export const getFeaturedNoticesIds = createSelector(
[getContributorFromRouteParam],
contributor => contributor?.contribution?.example?.noticeId
contributor =>
(contributor?.contribution?.pinnedNotices || []).map(
({ noticeId }) => noticeId
)
);

export const enhanceNotice = (contributors: Contributor[]) => (
Expand Down Expand Up @@ -104,16 +107,16 @@ export const getNoticesForContributorId = createSelector(
export const getContributorById = (id: number) =>
createSelector([getContributors], findItemById(id));

export const getFeaturedNotice = createSelector(
[getFeaturedNoticeId, getNotices],
(featuredNoticeId, notices) =>
notices.find(({ id }) => id === featuredNoticeId)
export const getFeaturedNotices = createSelector(
[getFeaturedNoticesIds, getNotices],
(featuredNoticesIds, notices) =>
notices.filter(({ id }) => featuredNoticesIds.includes(id))
);

export const getContributorNoticesButFeaturedOne = createSelector(
[getFeaturedNoticeId, getContributorNotices],
(featuredNoticeId, notices) =>
notices.filter(({ id }) => id !== featuredNoticeId)
export const getContributorNoticesButFeaturedOnes = createSelector(
[getFeaturedNoticesIds, getContributorNotices],
(featuredNoticesIds, notices) =>
notices.filter(({ id }) => !featuredNoticesIds.includes(id))
);

export const areContributorNoticesAllFetched = createSelector(
Expand Down

0 comments on commit 73aceae

Please sign in to comment.