Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
mark86092 committed Sep 7, 2023
2 parents 21c908c + b6d18d9 commit f3f35ad
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 106 deletions.
8 changes: 8 additions & 0 deletions src/apis/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
checkoutSubscriptionWithPrimeMutation,
paymentRecord,
myCurrentSubscription as myCurrentSubscriptionQuery,
mySubscriptions as mySubscriptionsQuery,
} from 'graphql/payment';

const getSubscriptionPlans = () =>
Expand Down Expand Up @@ -54,9 +55,16 @@ const getMyCurrentSubscription = token => () =>
token,
}).then(({ myCurrentSubscription }) => myCurrentSubscription);

const getMySubscriptions = token => () =>
graphqlClient({
query: mySubscriptionsQuery,
token,
}).then(({ mySubscriptions }) => mySubscriptions);

export default {
checkoutSubscriptionWithPrime,
getSubscriptionPlans,
getPaymentRecord,
getMyCurrentSubscription,
getMySubscriptions,
};
2 changes: 1 addition & 1 deletion src/components/App/Header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ const Header = () => {
popoverContent={
<ul className={styles.popoverItem}>
<li>
<Link to="/me/subscriptions">我的方案</Link>
<Link to="/me/subscriptions/current">我的方案</Link>
</li>
<li>
<Link to="/me">管理我的資料</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '../../constants/companyJobTitle';
import { generateBreadCrumbData } from './utils';

import TabLinkGroup from './TabLinkGroup';
import TabLinkGroup from '../common/TabLinkGroup';
import styles from './CompanyAndJobTitleWrapper.module.css';

const CompanyAndJobTitleWrapper = ({
Expand Down
48 changes: 0 additions & 48 deletions src/components/Me/SubscriptionPageTab.js

This file was deleted.

28 changes: 0 additions & 28 deletions src/components/Me/SubscriptionPageTab.module.css

This file was deleted.

36 changes: 26 additions & 10 deletions src/components/Me/SubscriptionWrapper.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
import React from 'react';

import { Section, Wrapper } from 'common/base';
import Heading from 'common/base/Heading';
import TabLinkGroup from 'common/TabLinkGroup';

import AuthMask from './AuthMask';

import styles from './SubscriptionWrapper.module.css';

const SubscriptionWrapper = ({ children }) => {
return (
<AuthMask title="登入以查看我的方案">
<div className={styles.container}>
<Heading as="h1" style={{ marginBottom: '48px' }}>
const options = [
{
label: '我的方案',
to: '/me/subscriptions/current',
},
{
label: '方案紀錄',
to: '/me/subscriptions',
},
];

const SubscriptionWrapper = ({ children }) => (
<Section paddingTop paddingBottom>
<Wrapper size="l">
<AuthMask title="登入以查看我的方案">
<Heading as="h1" marginBottom>
我的方案
</Heading>
<div style={{ display: 'inline-block' }}>{children}</div>
</div>
</AuthMask>
);
};
<TabLinkGroup className={styles.tabs} options={options} />
<div>
<div style={{ display: 'inline-block' }}>{children}</div>
</div>
</AuthMask>
</Wrapper>
</Section>
);

export default SubscriptionWrapper;
14 changes: 2 additions & 12 deletions src/components/Me/SubscriptionWrapper.module.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
@value above-medium, above-mobile from "common/variables.module.css";

.container {
padding: 20px 10px 0 10px;

@media (min-width: above-mobile) {
padding: 40px 100px 0 100px;
}

@media (min-width: above-medium) {
padding: 60px 340px 0 340px;
}
.tabs {
margin-bottom: 24px;
}
103 changes: 103 additions & 0 deletions src/components/Me/SubscriptionsPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useEffect, useState } from 'react';
import cn from 'classnames';
import { format } from 'date-fns';
import SubscriptionWrapper from './SubscriptionWrapper';
import {
getError,
getFetched,
getUnfetched,
isFetched,
isFetching,
toFetching,
} from 'utils/fetchBox';
import Loader from 'common/Loader';
import Table from 'common/table/Table';
import { subscriptionStatus, isFailed } from './subscriptionUtils';
import styles from './SubscriptionsPage.module.css';
import { useToken } from 'hooks/auth';
import apis from '../../apis';

const formatCreatedAt = value => format(new Date(value), 'yyyy/MM/dd');
const formatTitle = ({ subscriptionPlan: { title, description } }) =>
`${title} - ${description}`;
const formatDuration = ({ startedAt, expiredAt }) => (
<span>
{`${format(new Date(startedAt), 'yyyy-MM-dd hh:mm a')} ~`}
<br />
{format(new Date(expiredAt), 'yyyy-MM-dd hh:mm a')}
</span>
);
const formatAmount = value => value && `$${value}`;
const formatStatus = value => (
<span className={cn({ [styles.failed]: isFailed(value) })}>
{subscriptionStatus[value]}
</span>
);

const Subscriptions = () => {
const [mySubscriptions, setMySubscriptions] = useState(getUnfetched());
const token = useToken();

useEffect(() => {
setMySubscriptions(toFetching(mySubscriptions));

const fetcher = apis.payment.getMySubscriptions(token);

fetcher()
.then(subscriptions => {
setMySubscriptions(getFetched(subscriptions));
})
.catch(error => {
console.error(error);
setMySubscriptions(getError(error));
});
}, []); // eslint-disable-line react-hooks/exhaustive-deps

if (!mySubscriptions) return null;

if (isFetching(mySubscriptions)) return <Loader />;

if (!isFetched(mySubscriptions)) return null;

const { data } = mySubscriptions;

return (
<Table className={styles.subscriptions} data={data} primaryKey="id">
<Table.Column
className={styles.m}
title="日期"
dataField="createdAt"
dataFormatter={formatCreatedAt}
/>
<Table.Column
className={styles.m}
title="訂單編號"
dataField="paymentRecord.publicId"
/>
<Table.Column className={styles.l} title="項目" dataField={formatTitle} />
<Table.Column
className={styles.l}
title="有效期間"
dataField={formatDuration}
/>
<Table.Column
className={styles.m}
title="金額"
dataField="paymentRecord.amount"
dataFormatter={formatAmount}
/>
<Table.Column
className={styles.m}
title="狀態"
dataField="status"
dataFormatter={formatStatus}
/>
</Table>
);
};

export default () => (
<SubscriptionWrapper>
<Subscriptions />
</SubscriptionWrapper>
);
17 changes: 17 additions & 0 deletions src/components/Me/SubscriptionsPage.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.subscriptions {
td {
word-wrap: break-word;
}

.m {
width: 10%;
}

.l {
width: 20%;
}
}

.failed {
color: #ed5555;
}
8 changes: 8 additions & 0 deletions src/components/Me/subscriptionUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const subscriptionStatus = {
INIT: '待確認',
OK: '成功',
FAILED: '失敗',
SUSPENDED: '停權',
};

export const isFailed = status => status === 'FAILED' || status === 'SUSPENDED';
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';
import cn from 'classnames';

import P from 'common/base/P';

import styles from './TabLinkGroup.module.css';
import styles from './styles.module.css';

const encodeFirstIsActive = to => (_, location) => {
const { pathname } = location;
return encodeURI(pathname) === to;
};

const TabLinkGroup = ({ options, style }) => (
<div className={styles.group} style={style}>
const TabLinkGroup = ({ className, options, style }) => (
<div className={cn(styles.group, className)} style={style}>
{options.map(({ label, to }) => (
<NavLink
className={styles.element}
Expand Down
5 changes: 3 additions & 2 deletions src/components/common/table/Column.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import PropTypes from 'prop-types';
import cn from 'classnames';
import styles from './Table.module.css';

const Column = ({ children, className, alignRight }) => (
const Column = ({ children, title, className, alignRight }) => (
<th className={cn(className, { [styles.alignRight]: alignRight })}>
{children}
{children || title}
</th>
);

Column.propTypes = {
children: PropTypes.node,
title: PropTypes.string,
className: PropTypes.string,
alignRight: PropTypes.bool,
};
Expand Down
20 changes: 20 additions & 0 deletions src/graphql/payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,23 @@ query {
}
}
`;

export const mySubscriptions = `
query {
mySubscriptions {
id
startedAt
expiredAt
createdAt
status
paymentRecord {
publicId
amount
}
subscriptionPlan {
title
description
}
}
}
`;
Loading

0 comments on commit f3f35ad

Please sign in to comment.