diff --git a/package.json b/package.json index d295398e78..8c2efe1818 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matters-web", - "version": "4.9.0", + "version": "4.10.0", "description": "codebase of Matters' website", "sideEffects": false, "author": "Matters ", diff --git a/public/static/icons/24px/donate-bg.svg b/public/static/icons/24px/donate-bg.svg new file mode 100644 index 0000000000..8c28c9e2b1 --- /dev/null +++ b/public/static/icons/24px/donate-bg.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/static/images/analytics-no-supporter.svg b/public/static/images/analytics-no-supporter.svg new file mode 100644 index 0000000000..4a571f91f3 --- /dev/null +++ b/public/static/images/analytics-no-supporter.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/static/images/supporter-list-rocket.svg b/public/static/images/supporter-list-rocket.svg new file mode 100644 index 0000000000..c4ebdb0eb6 --- /dev/null +++ b/public/static/images/supporter-list-rocket.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/common/enums/externalLinks.ts b/src/common/enums/externalLinks.ts index 5e42f1832b..dbe94418d3 100644 --- a/src/common/enums/externalLinks.ts +++ b/src/common/enums/externalLinks.ts @@ -21,17 +21,17 @@ export const EXTERNAL_LINKS = { export const GUIDE_LINKS = { readerToolbox: { zh_hant: - 'https://matters.news/@hi176/255829-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreibgaprnoj2yqeaiaox6tzl74id3yrxyynodthfby6m4fzqqzrmiym', + 'https://matters.news/@hi176/346529-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreift2ghatmsamqenncl4eqsrrkoprh77sdxg2rgfeilefucqrunvdy', zh_hans: - 'https://matters.news/zh-Hans/@hi176/255829-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreibgaprnoj2yqeaiaox6tzl74id3yrxyynodthfby6m4fzqqzrmiym', - en: 'https://matters.news/en/@hi176/255829-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreibgaprnoj2yqeaiaox6tzl74id3yrxyynodthfby6m4fzqqzrmiym', + 'https://matters.news/zh-Hans/@hi176/346529-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreift2ghatmsamqenncl4eqsrrkoprh77sdxg2rgfeilefucqrunvdy', + en: 'https://matters.news/en/@hi176/346529-matters-%E8%AE%80%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreift2ghatmsamqenncl4eqsrrkoprh77sdxg2rgfeilefucqrunvdy', }, authorToolbox: { zh_hant: - 'https://matters.news/@hi176/255830-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreierks3n7n7aohc7to26wn7vgohspcxprxlakvdjt4g4ex74qqxuci', + 'https://matters.news/@hi176/346490-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreifhtkoweov2l7ltjwitklidmb23qqnflny2hw7ahc6rcttklvtxai', zh_hans: - 'https://matters.news/zh-Hans/@hi176/255830-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreierks3n7n7aohc7to26wn7vgohspcxprxlakvdjt4g4ex74qqxuci', - en: 'https://matters.news/en/@hi176/255830-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-03-%E6%9B%B4%E6%96%B0-bafyreierks3n7n7aohc7to26wn7vgohspcxprxlakvdjt4g4ex74qqxuci', + 'https://matters.news/zh-Hans/@hi176/346490-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreifhtkoweov2l7ltjwitklidmb23qqnflny2hw7ahc6rcttklvtxai', + en: 'https://matters.news/en/@hi176/346490-matters-%E4%BD%9C%E8%80%85%E5%B7%A5%E5%85%B7%E7%AE%B1-%E6%96%B0%E6%89%8B%E5%BF%85%E7%9C%8B-2022-11-%E6%9B%B4%E6%96%B0-bafyreifhtkoweov2l7ltjwitklidmb23qqnflny2hw7ahc6rcttklvtxai', }, connectWallet: { zh_hant: diff --git a/src/common/enums/route.ts b/src/common/enums/route.ts index 19efe20f3f..e76ac89482 100644 --- a/src/common/enums/route.ts +++ b/src/common/enums/route.ts @@ -39,6 +39,7 @@ type ROUTE_KEY = | 'ME_APPRECIATIONS_SENT' | 'ME_APPRECIATIONS_RECEIVED' | 'ME_NOTIFICATIONS' + | 'ME_ANALYTICS' | 'ME_WALLET' | 'ME_WALLET_TRANSACTIONS' | 'ME_SETTINGS' @@ -140,6 +141,7 @@ export const ROUTES: { { key: 'ME_NOTIFICATIONS', pathname: '/me/notifications' }, { key: 'ME_WALLET', pathname: '/me/wallet' }, { key: 'ME_WALLET_TRANSACTIONS', pathname: '/me/wallet/transactions' }, + { key: 'ME_ANALYTICS', pathname: '/me/analytics' }, // Settings { key: 'ME_SETTINGS', pathname: '/me/settings' }, diff --git a/src/common/enums/text.ts b/src/common/enums/text.ts index 8a6e4c01f3..db21e9dcd3 100644 --- a/src/common/enums/text.ts +++ b/src/common/enums/text.ts @@ -18,6 +18,7 @@ export const TEXT = { addToCircle: '加入圍爐', agree: '同意', agreeAndContinue: '同意並繼續', + all: '全部', allAuthors: '全部作者', allIcymi: '不要錯過', allTags: '全部標籤', @@ -174,6 +175,7 @@ export const TEXT = { IPFSEntrance: '分佈式入口', joinCivicLiker: '成為讚賞公民,每月贊助創作者', latest: '最新', + lately: '最近', latestArticles: '最新作品', latestResponses: '最新回應', license: '版權聲明', @@ -207,6 +209,7 @@ export const TEXT = { myFollowees: '我追蹤的', myProfile: '個人主頁', myWallet: '我的錢包', + myAnalytics: '數據後台', NAME_EXISTS: '該名稱已被其他使用者使用', NAME_INVALID: '名稱不正確', NETWORK_ERROR: '網路錯誤,請用力刷新', @@ -323,6 +326,10 @@ export const TEXT = { supportResponseDescription: '感謝支持,創作這條路不容易,有你的支持我將能夠蓄積更多能量創作。', supportResponseTitle: '試試輸入「#」以代稱支持者名稱', + supporterRankingList: '支持排行榜', + analyticsNoArticle: + '由於你尚未發布任何作品,這裡還沒有任何數據能與你分享哦!發布第一篇作品來介紹你自己,以此開啟你的創作之旅吧!', + analyticsNoSupporter: '尚無支持數據', TAG_EDITORS_REACH_LIMIT: '一個標籤最多僅可有 4 名協作者共同管理', TAG_NOT_FOUND: '標籤不存在', TOO_MANY_TAGS_FOR_ARTICLE: '標籤添加最多至 10 個', @@ -401,6 +408,7 @@ export const TEXT = { addToCircle: '加入围炉', agree: '同意', agreeAndContinue: '同意并继续', + all: '全部', allAuthors: '全部作者', allIcymi: '不要错过', allTags: '全部标签', @@ -557,6 +565,7 @@ export const TEXT = { IPFSEntrance: '分布式入口', joinCivicLiker: '成为赞赏公民,每月赞助创作者', latest: '最新', + lately: '最近', latestArticles: '最新作品', latestResponses: '最新回应', license: '版权声明', @@ -590,6 +599,7 @@ export const TEXT = { myFollowees: '我追踪的', myProfile: '个人主页', myWallet: '我的钱包', + myAnalytics: '数据后台', NAME_EXISTS: '该名称已被其他用户使用', NAME_INVALID: '名称不正确', NETWORK_ERROR: '网络不给力,请用力刷新', @@ -706,6 +716,10 @@ export const TEXT = { supportResponseDescription: '感謝支持,創作這條路不容易,有你的支持我將能夠蓄積更多能量創作。', supportResponseTitle: '试试输入「#」以代称支持者名称', + supporterRankingList: '支持排行榜', + analyticsNoArticle: + '由于你尚未发布任何作品,这裡还没有任何数据能与你分享哦!发布第一篇作品来介绍你自己,以此开启你的创作之旅吧!', + analyticsNoSupporter: '尚无支持数据', TAG_EDITORS_REACH_LIMIT: '一个标签最多仅可有 4 名协作者共同管理', TAG_NOT_FOUND: '标签不存在', TOO_MANY_TAGS_FOR_ARTICLE: '标签添加最多至 10 个', @@ -784,6 +798,7 @@ export const TEXT = { addToCircle: 'Add to Circle', agree: 'Agree', agreeAndContinue: 'Agree and continue', + all: 'All time', allAuthors: 'All Authors', allIcymi: `Matters' Choice`, allTags: 'Tags', @@ -957,6 +972,7 @@ export const TEXT = { IPFSEntrance: 'IPFS', joinCivicLiker: 'Become a Civil Liker and support creators! ', latest: 'Latest', + lately: 'Last', latestArticles: 'Latest Articles', latestResponses: 'Latest Responses', license: 'License', @@ -990,6 +1006,7 @@ export const TEXT = { myFollowees: 'Following', myProfile: 'Profile', myWallet: 'Wallet', + myAnalytics: 'Analytics', NAME_EXISTS: 'This name is already taken.', NAME_INVALID: 'Invalid name', NETWORK_ERROR: 'Please refresh the page and try again.', @@ -1113,6 +1130,10 @@ export const TEXT = { supportResponseDescription: 'Thanks for your support. The way isn’t always easy being a creator. With your generous support, I can accumulate more energy to go on.', supportResponseTitle: 'Try entering # to substitute the supporter.', + supporterRankingList: 'Top Supporters', + analyticsNoArticle: + 'You haven‘t published any articles yet, so there is no data available. Create one now to introduce yourself!', + analyticsNoSupporter: 'No data yet.', TAG_EDITORS_REACH_LIMIT: 'Maximum 4 editors allowed for each tag', TAG_NOT_FOUND: 'Tag not found', TOO_MANY_TAGS_FOR_ARTICLE: 'Add up to 10 tags', diff --git a/src/components/Forms/SelectAuthMethodForm/SourceHeader.tsx b/src/components/Forms/SelectAuthMethodForm/SourceHeader.tsx index cc75bfb1ad..1cf839e008 100644 --- a/src/components/Forms/SelectAuthMethodForm/SourceHeader.tsx +++ b/src/components/Forms/SelectAuthMethodForm/SourceHeader.tsx @@ -17,8 +17,8 @@ import styles from './styles.css' const AUTH_SOURCE_IMG = { [UNIVERSAL_AUTH_SOURCE.enter]: { image: IMAGE_AUTH_SOURCE_ENTER.src, - title: , - intro: ( + title: () => , + intro: () => ( ( ), - intro: ( + intro: () => ( <> ( ), - intro: ( + intro: () => ( <> ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( <> ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( ( ), - intro: ( + intro: () => ( { + const Titlte = AUTH_SOURCE_IMG[source].title + const Intro = AUTH_SOURCE_IMG[source].intro + return (

- {AUTH_SOURCE_IMG[source].title} +

-

{AUTH_SOURCE_IMG[source].intro}

+

+ +

diff --git a/src/components/Icon/IconDonateBg24.tsx b/src/components/Icon/IconDonateBg24.tsx new file mode 100644 index 0000000000..62b5b05678 --- /dev/null +++ b/src/components/Icon/IconDonateBg24.tsx @@ -0,0 +1,5 @@ +import { ReactComponent as Icon } from '@/public/static/icons/24px/donate-bg.svg' + +import { withIcon } from './withIcon' + +export const IconDonateBg24 = withIcon(Icon) diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx index 65ebc020b8..65394d8304 100644 --- a/src/components/Icon/index.tsx +++ b/src/components/Icon/index.tsx @@ -57,6 +57,7 @@ export * from './IconCopy16' export * from './IconDisallow16' export * from './IconDollarCircle16' export * from './IconDonate24' +export * from './IconDonateBg24' export * from './IconDot' export * from './IconDownVote16' export * from './IconDownVoted16' diff --git a/src/components/Layout/NavMenu/Top.tsx b/src/components/Layout/NavMenu/Top.tsx index a8d5f9a104..b3b22d8fee 100644 --- a/src/components/Layout/NavMenu/Top.tsx +++ b/src/components/Layout/NavMenu/Top.tsx @@ -2,6 +2,7 @@ import { useContext } from 'react' import { CardSpacing, + IconAnalytics24, IconBookmark24, IconCircle24, IconClap24, @@ -55,7 +56,6 @@ const NavMenuTop: React.FC = ({ isInSideDrawerNav }) => { - {circlePath && ( = ({ isInSideDrawerNav }) => { )} - } @@ -77,7 +76,6 @@ const NavMenuTop: React.FC = ({ isInSideDrawerNav }) => { - {(features.add_credit || features.payout) && ( = ({ isInSideDrawerNav }) => { )} - + + } + spacing="base" + size={menuItemSize} + > + + + } @@ -99,7 +105,6 @@ const NavMenuTop: React.FC = ({ isInSideDrawerNav }) => { - } @@ -109,7 +114,6 @@ const NavMenuTop: React.FC = ({ isInSideDrawerNav }) => { - } diff --git a/src/pages/me/analytics.tsx b/src/pages/me/analytics.tsx new file mode 100644 index 0000000000..22ad538d05 --- /dev/null +++ b/src/pages/me/analytics.tsx @@ -0,0 +1,11 @@ +import MyAnalytics from '~/views/Me/Analytics' + +import { Protected } from '~/components' + +const ProtectedMyAnalytics = () => ( + + + +) + +export default ProtectedMyAnalytics diff --git a/src/views/Me/Analytics/EmptyAnalytics/index.tsx b/src/views/Me/Analytics/EmptyAnalytics/index.tsx new file mode 100644 index 0000000000..76757cd9a3 --- /dev/null +++ b/src/views/Me/Analytics/EmptyAnalytics/index.tsx @@ -0,0 +1,96 @@ +import { useRouter } from 'next/router' +import { useContext } from 'react' + +import { + Button, + IconDonateBg24, + LanguageContext, + TextIcon, + Translate, + useMutation, +} from '~/components' +import CREATE_DRAFT from '~/components/GQL/mutations/createDraft' + +import { GUIDE_LINKS } from '~/common/enums' +import { toPath, translate } from '~/common/utils' + +import { ReactComponent as SupporterListRocket } from '@/public/static/images/supporter-list-rocket.svg' + +import styles from './styles.css' + +import { CreateDraft } from '~/components/GQL/mutations/__generated__/CreateDraft' + +const EmptyAnalytics = () => { + const router = useRouter() + const { lang } = useContext(LanguageContext) + + const [putDraft] = useMutation(CREATE_DRAFT, { + variables: { title: translate({ id: 'untitle', lang }) }, + }) + + return ( +
+
+ } + weight="md" + color="black" + size="md" + > + + +
+
+

+ +

+
+ +
+ +
+

+ + + + + +

+
+
+ + +
+ ) +} + +export default EmptyAnalytics diff --git a/src/views/Me/Analytics/EmptyAnalytics/styles.css b/src/views/Me/Analytics/EmptyAnalytics/styles.css new file mode 100644 index 0000000000..c893815fa7 --- /dev/null +++ b/src/views/Me/Analytics/EmptyAnalytics/styles.css @@ -0,0 +1,38 @@ +.container { + padding: var(--spacing-loose) var(--spacing-base); +} + +.content { + @mixin flex-center-start; + + flex-direction: column; + width: 100%; + padding-top: var(--spacing-loose); + + & p { + color: var(--color-grey-darker); + } +} + +.title { + @mixin: flex-start-space-between; + + flex-direction: row; +} + +.rocket { + width: 101px; + height: 89px; + margin: var(--spacing-loose) 0; + + @media (--sm-up) { + margin: var(--spacing-xx-loose) 0; + } +} + +.tips { + margin: var(--spacing-loose) 0 0; + font-size: var(--font-size-xs); + line-height: 1rem; + color: var(--color-grey); +} diff --git a/src/views/Me/Analytics/SelectPeriod/index.tsx b/src/views/Me/Analytics/SelectPeriod/index.tsx new file mode 100644 index 0000000000..0dd96aacd9 --- /dev/null +++ b/src/views/Me/Analytics/SelectPeriod/index.tsx @@ -0,0 +1,140 @@ +import { + Button, + DropdownDialog, + Menu, + TextIcon, + Translate, + withIcon, +} from '~/components' + +import { Z_INDEX } from '~/common/enums' + +import { ReactComponent as IconArrowDown } from '@/public/static/icons/8px/arrow-down.svg' + +type SelectProps = { + period: number + onChange: (period: number) => void +} + +const SelectPeriod: React.FC = ({ period, onChange }) => { + const options = [ + { + label: ( + <> + 7{' '} + + + ), + value: 7, + }, + { + label: ( + <> + 1{' '} + + + ), + value: 30, + }, + { + label: ( + <> + 3{' '} + + + ), + value: 90, + }, + { + label: ( + <> + + + ), + value: 0, + }, + ] + + const AnalyticsSelectContent = ({ dropdown }: { dropdown?: boolean }) => { + const isSevenDaysActive = period === options[0].value + const isOneMonthActive = period === options[1].value + const isThreeMonthsActive = period === options[2].value + const isAllActive = period === options[3].value + return ( + + onChange(options[0].value)}> + + {options[0].label} + + + onChange(options[1].value)}> + + {options[1].label} + + + onChange(options[2].value)}> + + {options[2].label} + + + onChange(options[3].value)}> + + {options[3].label} + + + + ) + } + return ( + , + placement: 'bottom-end', + zIndex: Z_INDEX.OVER_DIALOG, + }} + dialog={{ + content: , + title: '', + }} + > + {({ openDialog, ref }) => ( + + )} + + ) +} + +export default SelectPeriod diff --git a/src/views/Me/Analytics/SupporterDigestFeed/index.tsx b/src/views/Me/Analytics/SupporterDigestFeed/index.tsx new file mode 100644 index 0000000000..64166eac63 --- /dev/null +++ b/src/views/Me/Analytics/SupporterDigestFeed/index.tsx @@ -0,0 +1,51 @@ +import { Card, IconDonate24, TextIcon, UserDigest } from '~/components' + +import { toPath } from '~/common/utils' + +import styles from './styles.css' + +import { MeAnalytics_viewer_analytics_topDonators_edges_node } from '../__generated__/MeAnalytics' + +interface SupporterDigestFeedProps { + user: MeAnalytics_viewer_analytics_topDonators_edges_node + index: number + donationCount: number +} + +const SupporterDigestFeed = ({ + user, + index, + donationCount, +}: SupporterDigestFeedProps) => { + const userName = user.userName! + const path = toPath({ + page: 'userProfile', + userName, + }) + return ( + +
+ {index + 1} +
+ + +
+ } size="xs" color="grey-dark"> + {donationCount} + +
+
+
+ +
+ ) +} + +export default SupporterDigestFeed diff --git a/src/views/Me/Analytics/SupporterDigestFeed/styles.css b/src/views/Me/Analytics/SupporterDigestFeed/styles.css new file mode 100644 index 0000000000..2c727a0e6d --- /dev/null +++ b/src/views/Me/Analytics/SupporterDigestFeed/styles.css @@ -0,0 +1,43 @@ +.container { + display: flex; + padding: var(--spacing-base); +} + +.supporter { + @mixin flex-start-space-between; + + width: 100%; +} + +.content { + @mixin flex-center-all; + + line-height: 1.75; + & h4 { + margin-left: var(--spacing-x-tight); + } +} + +.number { + display: flex; + flex-shrink: 0; + padding-right: var(--spacing-tight); + font-size: var(--font-size-xm); + font-weight: var(--font-weight-semibold); + line-height: var(--line-height-base); + color: var(--color-matters-gold); +} + +.username { + @mixin line-clamp; + + font-size: var(font-size-md-s); + font-weight: var(--font-weight-medium); + line-height: var(--line-height-base); +} + +.count { + display: flex; + flex-shrink: 0; + justify-content: flex-end; +} diff --git a/src/views/Me/Analytics/index.tsx b/src/views/Me/Analytics/index.tsx new file mode 100644 index 0000000000..25a5905fa4 --- /dev/null +++ b/src/views/Me/Analytics/index.tsx @@ -0,0 +1,142 @@ +import { useQuery } from '@apollo/react-hooks' +import gql from 'graphql-tag' +import { useState } from 'react' + +import { + Head, + IconDonateBg24, + Layout, + List, + QueryError, + Spinner, + TextIcon, + Translate, +} from '~/components' +import { UserDigest } from '~/components/UserDigest' + +import { ReactComponent as AnalyticsNoSupporter } from '@/public/static/images/analytics-no-supporter.svg' + +import EmptyAnalytics from './EmptyAnalytics' +import SelectPeriod from './SelectPeriod' +import styles from './styles.css' +import SupporterDigestFeed from './SupporterDigestFeed/index' + +import { MeAnalytics } from './__generated__/MeAnalytics' + +const ME_ANALYTICS = gql` + query MeAnalytics($after: String, $filter: TopDonatorFilter) { + viewer { + id + articles(input: { first: 0, after: $after }) { + totalCount + } + analytics { + topDonators(input: { first: 10, after: $after, filter: $filter }) { + pageInfo { + startCursor + endCursor + hasNextPage + } + edges { + cursor + node { + ...UserDigestMiniUser + } + donationCount + } + } + } + } + } + ${UserDigest.Mini.fragments.user} +` +const BaseAnalytics = () => { + const [period, setPeriod] = useState(7) + + const [now] = useState(Date.now()) + + const rangeStart = + period === 0 + ? null + : new Date(now - period * 24 * 60 * 60 * 1000).toISOString() + const rangeEnd = rangeStart === null ? null : new Date(now).toISOString() + + const { data, loading, error } = useQuery(ME_ANALYTICS, { + variables: { + filter: { + inRangeStart: rangeStart, + inRangeEnd: rangeEnd, + }, + }, + }) + + if (loading) { + return + } + + if (error) { + return + } + + const edges = data?.viewer?.analytics.topDonators.edges + const articleCount = data?.viewer?.articles.totalCount || 0 + + if (articleCount === 0) { + return + } + + return ( +
+
+ } + weight="md" + color="black" + size="md" + > + + +
+ +
+
+ + {edges?.length === 0 && ( +
+
+ +
+

+ +

+
+ )} + + + {edges?.map(({ node, cursor, donationCount }, i) => ( + + + + ))} + + +
+ ) +} + +const MyAnalytics = () => ( + + } + right={} + /> + + + +) + +export default MyAnalytics diff --git a/src/views/Me/Analytics/styles.css b/src/views/Me/Analytics/styles.css new file mode 100644 index 0000000000..7338f754e5 --- /dev/null +++ b/src/views/Me/Analytics/styles.css @@ -0,0 +1,32 @@ +.container { + padding: var(--spacing-loose) 0; +} + +.title { + display: flex; + justify-content: space-between; + padding: 0 var(--spacing-base) 0; + margin-bottom: var(--spacing-tight); +} + +.no-supporter { + @mixin flex-center-start; + + flex-direction: column; + width: 100%; + margin: var(--spacing-loose) 0; + + & p { + margin-top: var(--spacing-x-tight); + color: var(--color-grey-darker); + } + + @media (--sm-up) { + margin: var(--spacing-xx-loose) 0; + } +} + +.no-supporter-img { + width: 85px; + height: 95px; +} diff --git a/src/views/Me/Wallet/styles.css b/src/views/Me/Wallet/styles.css index 6e9b204407..266b4142b9 100644 --- a/src/views/Me/Wallet/styles.css +++ b/src/views/Me/Wallet/styles.css @@ -6,7 +6,7 @@ margin-bottom: var(--spacing-loose); } - & :global(* + *) { + & :global(.assetsItem + .assetsItem) { position: relative; &::before {