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

Commit

Permalink
Added announcement subscribing button on homepage #343
Browse files Browse the repository at this point in the history
Signed-off-by: RaenonX <[email protected]>
  • Loading branch information
RaenonX committed Jan 23, 2022
1 parent 90b564b commit 5f5e440
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/api-def
2 changes: 1 addition & 1 deletion src/components/elements/common/button/subscribe/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type SubscribeButtonProps = {
state?: never,
} | {
defaultSubscribed?: never,
state?: [SubscribeButtonState, (newState: SubscribeButtonState) => void],
state: [SubscribeButtonState, (newState: SubscribeButtonState) => void],
});

export const SubscribeButton = ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';

import {PostType} from '../../../../../../../../api-def/api/post/types';
import {PostType} from '../../../../../../../../api-def/api';
import {TimeAgo} from '../../../../../../../../utils/timeago';
import {SubscribeButton} from '../../../../../../../elements/common/button/subscribe/main';
import {RowNoGutter} from '../../../../../../../elements/common/grid/row';
Expand Down
44 changes: 39 additions & 5 deletions src/components/pages/home/main.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';

import {screen, waitFor} from '@testing-library/react';
import {screen, waitFor, within} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {ObjectId} from 'mongodb';

import {mockData} from '../../../../test/data/mock/homepage';
import {renderReact} from '../../../../test/render/main';
Expand All @@ -13,18 +15,26 @@ import {Home} from './main';

describe('Homepage', () => {
let fnFetchHomepageLanding: jest.SpyInstance;
let fnRemoveSubscription: jest.SpyInstance;

beforeEach(() => {
fnFetchHomepageLanding = jest.spyOn(ApiRequestSender, 'getHomepageLanding').mockResolvedValue({
success: true,
code: ApiResponseCode.SUCCESS,
data: mockData,
userSubscribed: {
[PostType.MISC]: true,
[PostType.ANALYSIS]: true,
[PostType.QUEST]: false,
subscribed: {
post: {
[PostType.MISC]: true,
[PostType.ANALYSIS]: true,
[PostType.QUEST]: false,
},
announcement: true,
},
});
fnRemoveSubscription = jest.spyOn(ApiRequestSender, 'removeSubscription').mockResolvedValue({
code: ApiResponseCode.SUCCESS,
success: true,
});
});

it('shows ads', async () => {
Expand Down Expand Up @@ -92,4 +102,28 @@ describe('Homepage', () => {
mockData.posts[PostType.MISC].forEach((post) => expect(screen.getByText(post.title)).toBeInTheDocument());
mockData.posts[PostType.ANALYSIS].forEach((post) => expect(screen.getByText(post.title)).toBeInTheDocument());
});

it('loads announcement subscription correctly', async () => {
renderReact(() => <Home/>);

await waitFor(() => expect(fnFetchHomepageLanding).toHaveBeenCalled());

const tips = screen.getByText(translationEN.home.message.onSiteAnnouncementEnabled)
.nextElementSibling as HTMLElement;
expect(within(tips).getByText('', {selector: 'i.bi-bell'})).toBeInTheDocument();
});

it('updates announcement subscription', async () => {
const id = new ObjectId().toHexString();
renderReact(() => <Home/>, {user: {id}});

await waitFor(() => expect(fnFetchHomepageLanding).toHaveBeenCalled());

const tips = screen.getByText(translationEN.home.message.onSiteAnnouncementEnabled)
.nextElementSibling as HTMLElement;
const subButton = within(tips).getByText('', {selector: 'i.bi-bell'});
userEvent.click(subButton);

expect(fnRemoveSubscription).toHaveBeenCalledWith(id, {type: 'const', name: 'ANNOUNCEMENT'});
});
});
2 changes: 1 addition & 1 deletion src/components/pages/home/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Home = () => {

return (
<>
<SiteFeatures/>
<SiteFeatures response={homepageData.data}/>
<AdsToolBottom/>
<hr/>
{
Expand Down
35 changes: 31 additions & 4 deletions src/components/pages/home/sections/features/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,33 @@ import React from 'react';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';

import {FailedResponse, HomepageLandingResponse, isFailedResponse} from '../../../../../api-def/api';
import {GeneralPath} from '../../../../../api-def/paths';
import {featureBtnColors} from '../../../../../const/colors';
import {useI18n} from '../../../../../i18n/hook';
import {SubscribeButton} from '../../../../elements/common/button/subscribe/main';
import {SubscribeButtonState} from '../../../../elements/common/button/subscribe/type';
import {RowRegular} from '../../../../elements/common/grid/row';
import mainStyles from '../../main.module.css';
import {FeatureButton} from './button';


export const SiteFeatures = () => {
type Props = {
response: HomepageLandingResponse | FailedResponse | undefined,
};

export const SiteFeatures = ({response}: Props) => {
const {t} = useI18n();

const state = React.useState<SubscribeButtonState>({subscribed: false, updating: false});
const [buttonState, setButtonState] = state;

React.useEffect(() => {
if (response && !isFailedResponse(response)) {
setButtonState({...buttonState, subscribed: response.subscribed.announcement});
}
}, [response]);

return (
<>
<h1 className={mainStyles['section-title']}>
Expand Down Expand Up @@ -43,9 +59,20 @@ export const SiteFeatures = () => {
variant={featureBtnColors.thanks}
/>
</RowRegular>
<Row className="text-center mb-3">
<Col>
{t((t) => t.home.message.features)}
<Row className="mb-3">
<Col className="d-flex align-items-center justify-content-center">
<span>
{
buttonState.subscribed ?
t((t) => t.home.message.onSiteAnnouncementEnabled) :
t((t) => t.home.message.onSiteAnnouncementDisabled)
}
</span>&nbsp;
<SubscribeButton
subscriptionKey={{type: 'const', name: 'ANNOUNCEMENT'}}
state={state}
disabled={!response || isFailedResponse(response)}
/>
</Col>
</Row>
</>
Expand Down
8 changes: 4 additions & 4 deletions src/components/pages/home/sections/updatesPosts/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const RecentUpdatedPosts = ({response}: Props) => {

const {unitInfoMap} = useUnitInfo();

const {data, userSubscribed} = response;
const {data, subscribed} = response;

return (
<>
Expand All @@ -47,7 +47,7 @@ export const RecentUpdatedPosts = ({response}: Props) => {
<UnitIconClickable unit={unitInfoToClickableProps(unitInfo, lang)} className={styles['unit-icon']}/>
);
}}
defaultSubscribed={userSubscribed[PostType.ANALYSIS]}
defaultSubscribed={subscribed.post[PostType.ANALYSIS]}
subscriptionKey={{type: 'const', name: 'ALL_ANALYSIS'}}
/>
</Col>
Expand All @@ -58,7 +58,7 @@ export const RecentUpdatedPosts = ({response}: Props) => {
title={t((t) => t.enum.postType[PostType.QUEST])}
titlePath={GeneralPath.QUEST_LIST}
entries={data.posts[PostType.QUEST]}
defaultSubscribed={userSubscribed[PostType.QUEST]}
defaultSubscribed={subscribed.post[PostType.QUEST]}
subscriptionKey={{type: 'const', name: 'ALL_QUEST'}}
/>
</Col>
Expand All @@ -67,7 +67,7 @@ export const RecentUpdatedPosts = ({response}: Props) => {
title={t((t) => t.enum.postType[PostType.MISC])}
titlePath={GeneralPath.MISC_LIST}
entries={data.posts[PostType.MISC]}
defaultSubscribed={userSubscribed[PostType.MISC]}
defaultSubscribed={subscribed.post[PostType.MISC]}
subscriptionKey={{type: 'const', name: 'ALL_MISC'}}
/>
</Col>
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/cht/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,8 @@ export const translation: TranslationStruct = {
recentlyUpdated: '文章更新',
},
message: {
features: '歡迎瀏覽導引列以了解更多網站功能。',
onSiteAnnouncementDisabled: '開啟網站公告 Email 通知以接收最新相關資訊。',
onSiteAnnouncementEnabled: '已開啟網站公告 Email 通知。',
noPost: '無可用文章更新資訊。',
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,8 @@ export type TranslationStruct = {
recentlyUpdated: string,
},
message: {
features: string,
onSiteAnnouncementDisabled: string,
onSiteAnnouncementEnabled: string,
noPost: string,
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/en/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,8 @@ export const translation: TranslationStruct = {
recentlyUpdated: 'Posts',
},
message: {
features: 'Check the navigation bar for more features.',
onSiteAnnouncementDisabled: 'Subscribe to website announcement to receive related information by email.',
onSiteAnnouncementEnabled: 'Website announcement email enabled.',
noPost: 'No available posts.',
},
},
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/translations/jp/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,8 @@ export const translation: TranslationStruct = {
recentlyUpdated: 'TBA',
},
message: {
features: 'TBA',
onSiteAnnouncementDisabled: 'TBA',
onSiteAnnouncementEnabled: 'TBA',
noPost: 'TBA',
},
},
Expand Down

0 comments on commit 5f5e440

Please sign in to comment.