diff --git a/dist/font/riccione/xlight.otf b/dist/font/riccione/xlight.otf new file mode 100644 index 0000000000..d676d3d7c7 Binary files /dev/null and b/dist/font/riccione/xlight.otf differ diff --git a/src/img/icon/payment/hyperlink.svg b/src/img/icon/payment/hyperlink.svg new file mode 100644 index 0000000000..8ebe691346 --- /dev/null +++ b/src/img/icon/payment/hyperlink.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/img/icon/payment/slide0.svg b/src/img/icon/payment/slide0.svg new file mode 100644 index 0000000000..92d3bc81eb --- /dev/null +++ b/src/img/icon/payment/slide0.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/icon/payment/tier1.svg b/src/img/icon/payment/tier1.svg new file mode 100644 index 0000000000..23c8bd015c --- /dev/null +++ b/src/img/icon/payment/tier1.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/img/icon/payment/tier2.svg b/src/img/icon/payment/tier2.svg new file mode 100644 index 0000000000..4113bfa36a --- /dev/null +++ b/src/img/icon/payment/tier2.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/img/icon/payment/tier3.svg b/src/img/icon/payment/tier3.svg new file mode 100644 index 0000000000..babe67a8a1 --- /dev/null +++ b/src/img/icon/payment/tier3.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/json/text.json b/src/json/text.json index 45b98f16e1..23f0bc6873 100644 --- a/src/json/text.json +++ b/src/json/text.json @@ -773,11 +773,27 @@ "popupSettingsSpaceRemoveButton": "Move to Bin", "popupSettingsPaymentTitle": "Membership", - "popupSettingsPaymentIndexText": "Global name for your identity, increased sync volume, expanded sharing options, and other benefits for out paid plans. See details on Anytype.io", + "popupSettingsPaymentIndexTitle": "Let’s build together", + "popupSettingsPaymentIndexText": "Joining Anytype network means contributing to its story", - "popupSettingsPaymentItemTitle1": "Friend", - "popupSettingsPaymentItemTitle2": "Supporter", - "popupSettingsPaymentItemTitle3": "Funding Patron", + "popupSettingsPaymentIndexSlide0Title": "Co-create with us", + "popupSettingsPaymentIndexSlide0Text": "Stay closely connected with our team and community. Join calls with the team, influence Anytype's evolution, and have your say on features.", + + "popupSettingsPaymentItemTitle1": "Explorer", + "popupSettingsPaymentItemDescription1": "Dive into the network and enjoy the thrill of one-on-one collaboration", + "popupSettingsPaymentItemTitle2": "Builder", + "popupSettingsPaymentItemDescription2": "Unlock the magic of multi-party collaboration and enjoy top-notch support\n\n", + "popupSettingsPaymentItemTitle3": "Co-creator", + "popupSettingsPaymentItemDescription3": "Support our adventure and unlock exclusive access and perks", + + "popupSettingsPaymentItemJustEmail": "Just e-mail", + "popupSettingsPaymentItemPerYear": "per year", + "popupSettingsPaymentItemPerYears": "per %s years", + "popupSettingsPaymentItemLearnMore": "Learn more", + + "popupSettingsPaymentIndexMembershipLevelsDetails": "Membership levels details", + "popupSettingsPaymentIndexPrivacyPolicy": "Privacy policy", + "popupSettingsPaymentIndexTermsAndConditions": "Terms and conditions", "popupSettingsPaymentItemText1": "Your Anytype Identity has a global name in the Anytype system, you can store additional data and have more shared spaces.", "popupSettingsPaymentItemText2": "Your Anytype Identity has a global name in the Anytype system, you can store additional data and have more shared spaces.", diff --git a/src/scss/font.scss b/src/scss/font.scss index 127d78d072..a1ca328160 100644 --- a/src/scss/font.scss +++ b/src/scss/font.scss @@ -46,4 +46,9 @@ @font-face { font-family: 'Inter'; font-style: italic; font-weight: 700; src: url('~font/inter/bolditalic.woff2') format('woff2'); -} \ No newline at end of file +} + +@font-face { + font-family: 'RiccioneXLight'; font-style: normal; font-weight: 400; + src: url('~font/riccione/xlight.otf') format('opentype'); +} diff --git a/src/scss/popup/settings.scss b/src/scss/popup/settings.scss index 6f74da4452..2a1c222573 100644 --- a/src/scss/popup/settings.scss +++ b/src/scss/popup/settings.scss @@ -684,11 +684,64 @@ .actionItems { margin: 32px 0px 24px 0px; } } - .side.right.tabPaymentIndex { display: flex; flex-direction: column; } + .side.right.tabPaymentIndex { display: flex; flex-direction: column; padding: 48px 32px !important; } .side.right.tabPaymentIndex { - .items { display: flex; flex-direction: column; justify-content: space-evenly; gap: 16px; height: 100%; } - .items { - .item { background: red; height: 100%; } + .membershipTitle { font-family: 'RiccioneXLight', 'Inter'; text-align: center; font-size: 48px; line-height: 48px; font-weight: 300; letter-spacing: -0.518px; margin-bottom: 0px; } + .description { text-align: center; } + + .slider { margin-bottom: 32px; } + .slider { + .feed { display: flex; position: relative; transition: left 400ms $easeInQuint; flex-wrap: nowrap; gap: 0px 16px; margin-bottom: 10px; } + .slide { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; text-align: center; padding-bottom: 24px; width: 100%; height: 288px; border-radius: 12px; flex-shrink: 0; } + .slide { + .title { @include text-header3; margin-bottom: 4px; } + .title, + .label { width: 360px; } + + .illustration { margin-bottom: 18px; display: inline-block; } + .illustration.slide0 { width: 320px; height: 112px; background: url('~img/icon/payment/slide0.svg'); } + } + + .slide.slide0 { background: linear-gradient(180deg, #CFF5CE 0%, #F2F2F2 49.5%); } + .slide.slide1 { background: linear-gradient(180deg, #C5EDFE 0%, #F2F2F2 49.5%); } + .slide.slide2 { background: linear-gradient(180deg, #FEF1C5 0%, #F2F2F2 49.5%); } + + .bullits { display: flex; flex-wrap: nowrap; gap: 0px 10px; justify-content: center; } + .bullits { + .bullit { width: 6px; height: 6px; border-radius: 50%; background-color: var(--color-control-inactive); } + .bullit:hover { background-color: var(--color-control-active); } + .bullit.active { background-color: var(--color-control-accent) !important; box-shadow: 0 0 0 1px var(--color-control-accent); } + } + } + + .tiers { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 16px; margin-bottom: 48px; } + .tiers { + .tier { display: flex; flex-direction: column; justify-content: space-between; height: 296px; flex-shrink: 0; text-align: left; border-radius: 16px; padding: 16px 16px 20px; } + .tier { + .icon { width: 64px; height: 64px; background-size: 64px 64px; margin-bottom: 10px; } + .icon.tier1 { background: url('~img/icon/payment/tier1.svg'); } + .icon.tier2 { background: url('~img/icon/payment/tier2.svg'); width: 60px; height: 60px; margin: 2px 0px 12px; background-size: 60px 60px; } + .icon.tier3 { background: url('~img/icon/payment/tier3.svg'); } + + .title { @include text-paragraph; margin-bottom: 4px; } + .label { @include text-small; } + + .priceWrapper { margin-bottom: 10px; @include text-small; } + .priceWrapper { + .price { @include text-paragraph; font-weight: 600; display: inline-block; padding-right: 4px; } + } + + .button { width: 100%; } + } + + .tier.tier1 { background: linear-gradient(180deg, #D7FAFF 0%, #F3F3F3 25.64%); } + .tier.tier2 { background: linear-gradient(180deg, #EAECFE 0%, #F3F3F3 25.64%); } + .tier.tier3 { background: linear-gradient(180deg, #FFEBEB 0%, #F3F3F3 25.64%); } + } + + .actionItems { margin-bottom: 0 !important; } + .actionItems { + .icon { width: 16px; height: 16px; background: url('~img/icon/payment/hyperlink.svg'); } } } } diff --git a/src/ts/app.tsx b/src/ts/app.tsx index 979b14e40e..85564d3122 100644 --- a/src/ts/app.tsx +++ b/src/ts/app.tsx @@ -232,6 +232,10 @@ class App extends React.Component { componentDidMount () { this.init(); + + window.setTimeout(() => { + popupStore.open('settings', { data: { page: 'paymentIndex' }}) + }, 1000); }; init () { diff --git a/src/ts/component/popup/page/settings/payment/index.tsx b/src/ts/component/popup/page/settings/payment/index.tsx index 04447212dc..f56f397d26 100644 --- a/src/ts/component/popup/page/settings/payment/index.tsx +++ b/src/ts/component/popup/page/settings/payment/index.tsx @@ -1,27 +1,135 @@ import * as React from 'react'; -import { Title, Label } from 'Component'; -import { I, translate } from 'Lib'; +import { Title, Label, Button, Icon } from 'Component'; +import { I, translate, UtilCommon } from 'Lib'; import { observer } from 'mobx-react'; +import $ from 'jquery'; const PopupSettingsPagePaymentIndex = observer(class PopupSettingsPagePaymentIndex extends React.Component { + state = { + currentSlide: 0 + }; + node: any = null; + slideWidth: number = 0; + render () { const { onPage } = this.props; + const { currentSlide } = this.state; + const style = { left: -this.slideWidth * currentSlide }; + + const slides = [ + { title: translate('popupSettingsPaymentIndexSlide0Title'), text: translate('popupSettingsPaymentIndexSlide0Text') }, + { title: translate('popupSettingsPaymentIndexSlide0Title'), text: translate('popupSettingsPaymentIndexSlide0Text') }, + { title: translate('popupSettingsPaymentIndexSlide0Title'), text: translate('popupSettingsPaymentIndexSlide0Text') }, + ]; + const tiers = [ + { idx: 1 }, + { idx: 2, price: 99, period: 1 }, + { idx: 3, price: 399, period: 5 }, + ]; + + const SlideItem = (slide) => ( +
+
+
+ + <Label text={slide.text} /> + </div> + </div> + ); + + const TierItem = (item: any) => { + let price = ''; + let period = ''; + + if (!item.price) { + price = translate('popupSettingsPaymentItemJustEmail'); + } else { + price = `$${item.price}`; + }; + + if (item.period) { + if (item.period == 1) { + period = translate('popupSettingsPaymentItemPerYear') + } else { + period = UtilCommon.sprintf(translate('popupSettingsPaymentItemPerYears'), item.period); + }; + }; + + return ( + <div className={[ 'tier', `tier${item.idx}` ].join(' ')}> + <div className="top"> + <div className={[ 'icon', `tier${item.idx}` ].join(' ')} /> + <Title text={translate(`popupSettingsPaymentItemTitle${item.idx}`)} /> + <Label text={translate(`popupSettingsPaymentItemDescription${item.idx}`)} /> + </div> + <div className="bottom"> + <div className="priceWrapper"> + <span className="price">{price}</span>{period} + </div> + <Button text={translate('popupSettingsPaymentItemLearnMore')} /> + </div> + </div> + ); + }; return ( - <React.Fragment> - <Title text={translate('popupSettingsPaymentTitle')} /> + <div ref={node => this.node = node}> + <div className="membershipTitle">{translate('popupSettingsPaymentIndexTitle')}</div> <Label className="description" text={translate('popupSettingsPaymentIndexText')} /> - <div className="items"> - <div className="item" onClick={() => onPage('paymentItem', { itemId: 1 })} /> - <div className="item" /> - <div className="item" /> + <div className="slider"> + <div style={style} className="feed"> + {slides.map((slide, idx) => ( + <SlideItem key={idx} idx={idx} {...slide} /> + ))} + </div> + <div className="bullits"> + {slides.map((slide, idx) => { + const cn = [ 'bullit', currentSlide == idx ? 'active' : '' ]; + + return <div className={cn.join(' ')} onClick={() => this.setState({ currentSlide: idx })} key={idx} />; + })} + </div> </div> - </React.Fragment> + + <div className="tiers"> + {tiers.map((tier, idx) => ( + <TierItem key={idx} {...tier} /> + ))} + </div> + + <div className="actionItems"> + <div className="item"> + <Label text={translate('popupSettingsPaymentIndexMembershipLevelsDetails')} /> + <Icon /> + </div> + <div className="item"> + <Label text={translate('popupSettingsPaymentIndexPrivacyPolicy')} /> + <Icon /> + </div> + <div className="item"> + <Label text={translate('popupSettingsPaymentIndexTermsAndConditions')} /> + <Icon /> + </div> + </div> + </div> ); }; + componentDidMount () { + this.slideWidth = $(this.node).width() + 16; + + $(window).on('resize.membership', () => { + console.log('WIDTH: ', $(this.node).width() + 16) + this.slideWidth = $(this.node).width() + 16; + }); + }; + + componentWillUnmount () { + $(window).off('resize.membership'); + }; + }); -export default PopupSettingsPagePaymentIndex; \ No newline at end of file +export default PopupSettingsPagePaymentIndex;