Commit 573260a8 by Jason Zhou

chore: sync with bobcat

parent ece3f800
......@@ -11,7 +11,6 @@
"fe/js/EcommerceManager.es6",
"fe/js/editor.es6",
"fe/js/Landing.es6",
"fe/js/MainDashboard.es6",
"fe/js/page.client.es6",
"fe/js/PortfolioManager.es6",
"fe/js/stores/font_store.es6",
......
......@@ -57,6 +57,7 @@ Promise.all([p1])
const ReactDOM = require('react-dom')
const SupportWidget = require('js/components/support_widget/SupportWidget')
const PurchaseBridge = require('../../nextgen/domain/PurchaseBridge')
.default
const SupportWidgetWithComponentKit = ComponentKitContext(SupportWidget)
const PublishManager = require('nextgen/subApps/publishManager')
......
......@@ -287,7 +287,7 @@ export default {
const { coupon } = _getCart()
const amount = coupon.option.amount
return (discountItem.orderItem.price * amount) / 100
return discountItem.orderItem.price * amount / 100
} else {
return 0
}
......@@ -311,7 +311,7 @@ export default {
case 'percentage':
number = this.isInCondition('productId')
? this.getDiscountForProductCondition()
: (this.getTotalItemPriceNum() * coupon.option.amount) / 100
: this.getTotalItemPriceNum() * coupon.option.amount / 100
if (this.getDecimalNum() === 0) {
number = Math.round(number)
......@@ -432,7 +432,7 @@ export default {
return taxesNum
}
taxesNum = ((itemPrice - discountForTax) * taxesRate) / (1 + taxesRate)
taxesNum = (itemPrice - discountForTax) * taxesRate / (1 + taxesRate)
if (this.getDecimalNum() === 0) {
taxesNum = Math.round(taxesNum)
}
......@@ -447,14 +447,16 @@ export default {
} else if (this.userHasCouponWithType('percentage', coupon)) {
if (this.isInCondition('productId')) {
const item = this.getDiscountItem()
description = __(
'EcommerceCoupon|%{amount} off for %{productCount} %{productName} ',
{
productCount: options ? options.productCount : 1,
productName: options ? options.productName : item.product.name,
amount: `${coupon.option.amount}%`,
},
)
if (item) {
description = __(
'EcommerceCoupon|%{amount} off for %{productCount} %{productName} ',
{
productCount: options ? options.productCount : 1,
productName: options ? options.productName : item.product.name,
amount: `${coupon.option.amount}%`,
},
)
}
} else {
description = __('EcommerceCoupon|%{amount} Off', {
amount: `${coupon.option.amount}%`,
......@@ -860,10 +862,11 @@ export default {
if (!item) {
return false
}
return (
path(['payload', 'item', 'parent_id'])(category) &&
pathEq(['payload', 'item', 'level'], 2)(category)
)
return category.parent_id > -1 && category.level === 2
// return (
// path(['payload', 'item', 'parent_id'])(category) &&
// pathEq(['payload', 'item', 'level'], 2)(category)
// )
},
sortedCategory(categories, orderList) {
orderList = orderList || {}
......
......@@ -189,6 +189,14 @@ class DomainsTab extends React.Component {
}
_onConnectDomainAfterRegister(newDomain) {
// free user won't connect domain
if (CurrentUserStore.isFreeMembership()) {
this.getDefaultBinding().set('showPurchaseSuccessMsg', true)
this._onBackToTab()
return
}
//
EditorActions.addDomainToPool(newDomain)
newDomain = `www.${newDomain}`
......@@ -612,36 +620,76 @@ class DomainsTab extends React.Component {
const v2DomainConnection = PageMetaStore.getV2DomainConnection()
const showConnectedMessage =
v2DomainConnection && v2DomainConnection.get('domain_id')
const forceShowKB =
const hasNoDomainId =
v2DomainConnection && !v2DomainConnection.get('domain_id')
const isSiteOfResellerClient = PageMetaStore.isSiteOfResellerClient()
const canBuyAllDomains = ConfStore.getCanBuyAllDomains()
let registerDomainContainer
if (!isSxl) {
if (domainPurchaseStatus === 'free') {
registerDomainContainer = (
<div className="register-domain">
{tct(
__(
"Only premium users can register a new domain through our system. If you [link: purchase a yearly subscription plan] to Strikingly, we'll give you a domain for free!",
),
{
root: <div className="field-hint" />,
link: <a href={
UserMetaStore.isZbjUser()
? 'javascript: alert("八戒云站暂不支持升级,请添加新的套餐。")'
: '/s/pricing?ref=free_domain'
} />,
},
)}
<div
className="s-btn big basic-blue"
onClick={this._onRegisterNewDomain}>
{__('Check Availability')}
// rollout for new domain project v1
if (!canBuyAllDomains) {
if (domainPurchaseStatus === 'free') {
registerDomainContainer = (
<div className="register-domain">
{tct(
__(
"If you [link: purchase a yearly subscription plan] to Strikingly, we'll give you a domain for free for the first year!",
),
{
root: <div className="field-hint" />,
link: (
<a
href={
UserMetaStore.isZbjUser()
? 'javascript: alert("八戒云站暂不支持升级,请添加新的套餐。")'
: '/s/pricing?ref=free_domain'
}
/>
),
},
)}
<div
className="s-btn big basic-blue"
onClick={this._onRegisterNewDomain}>
{__('Check Availability')}
</div>
</div>
</div>
)
)
} else if (
!justConnectedAfterRegister &&
v2DomainSetting.entitledToFreeDomain
) {
registerDomainContainer = (
<div className="register-domain">
<div className="field-hint">
{__(
`You're on a yearly plan and can register a new domain for free!`,
)}
</div>
<div
className="s-btn big basic-blue"
onClick={this._onRegisterNewDomain}>
{__('Claim My Free Domain!')}
</div>
</div>
)
} else {
registerDomainContainer = (
<div className="register-domain">
<div className="field-hint">
{__(`Don't own a domain yet? Grab one here for $24.95/year.`)}
</div>
<div
className="s-btn big basic-blue"
onClick={this._onRegisterNewDomain}>
{__('Register New Domain')}
</div>
</div>
)
}
} else if (
!justConnectedAfterRegister &&
CurrentUserStore.hasFreeDomain() &&
v2DomainSetting.entitledToFreeDomain
) {
registerDomainContainer = (
......@@ -662,7 +710,7 @@ class DomainsTab extends React.Component {
registerDomainContainer = (
<div className="register-domain">
<div className="field-hint">
{__(`Don't own a domain yet? Grab one here for $24.95/year.`)}
{__(`Don't own a domain yet? Grab one here.`)}
</div>
<div
className="s-btn big basic-blue"
......@@ -715,75 +763,77 @@ class DomainsTab extends React.Component {
)
}
const domainSettingsRs = this._renderDomainSettingsBox(forceShowKB)
const domainSettingsRs = this._renderDomainSettingsBox(hasNoDomainId)
const MoreartyInput = Morearty.DOM.input
return (
<div
key="first-step"
className="page-settings-content s-dialog-content domains-tab">
{!isSxl && (
<div>
{showPurchaseSuccessMsg && (
<ReactTransitionGroup>
<JQSlide component={DOM.div} className="s-box green small fist">
<i className="fa fa-check" />
{tct(
__(
'Domain|[placeholderStrong: You just got a new domain!]',
),
{
root: <span />,
placeholderStrong: <strong />,
},
)}
&nbsp;
{!CurrentUserStore.isFreeMembership() &&
__("Domain|And we've already connected it to your site.")}
{__(
'Domain|Remember, you must check your email to validate your domain.',
)}
&nbsp;
<a
href={v2DomainSetting ? '/s#/v2_domains/' : '/s#/domains'}
target="_blank">
{__('Domain|View your new domain in domain dashboard.')}
</a>
<div
className="close-btn"
onClick={this._removePurchaseSuccessMsg}>
×
</div>
</JQSlide>
</ReactTransitionGroup>
)}
{!isSiteOfResellerClient &&
(canBuyAllDomains ||
(!canBuyAllDomains && !CurrentUserStore.isFreeMembership())) &&
(showRegisterBtn ? (
<div className="form-field">
<div className="field-title">
{__('Register A New Domain')}
</div>
{registerDomainContainer}
</div>
) : (
<a
onClick={this._onClickshowRegisterBtn.bind(this)}
href="javascript: void(0);">
{__('Register New Domain')}
</a>
))}
<div className="hr" />
</div>
)}
{
<PremiumFeature
featureName="custom_domain"
overlayStyle="fieldOverlay"
title={__(
'Domain|Register for or connect to a custom domain for this site.',
)}
title={__('Domain|Connect to a custom domain for this site.')}
hint={__(
'Upgrade your account to either Limited or Pro to access this feature!',
)}
source="cd">
{!isSxl && (
<div>
{showPurchaseSuccessMsg && (
<ReactTransitionGroup>
<JQSlide
component={DOM.div}
className="s-box green small fist">
<i className="fa fa-check" />
{tct(
__(
"Domain|[placeholderStrong: You just got a new domain!] And we've already connected it to your site. Remember, you must check your email to validate your domain.",
),
{
root: <span />,
placeholderStrong: <strong />,
},
)}
&nbsp;
<a
href={
v2DomainSetting ? '/s/v2_domains/' : '/s#/domains'
}
target="_blank">
{__('Domain|View your new domain in domain dashboard.')}
</a>
<div
className="close-btn"
onClick={this._removePurchaseSuccessMsg}>
×
</div>
</JQSlide>
</ReactTransitionGroup>
)}
{!isSiteOfResellerClient &&
(showRegisterBtn ? (
<div className="form-field">
<div className="field-title">
{__('Register A New Domain')}
</div>
{registerDomainContainer}
</div>
) : (
<a
onClick={this._onClickshowRegisterBtn.bind(this)}
href="javascript: void(0);">
{__('Register New Domain')}
</a>
))}
<div className="hr" />
</div>
)}
<div className="form-field custom-domain-field">
<div className="field-title">
{__('Custom Domain/Subdomain')}
......@@ -812,13 +862,27 @@ class DomainsTab extends React.Component {
value={currentDomain}
onChange={this._onChangeCustomDomain}
/>
<div className="s-btn" onClick={this._onSaveCustomDomain}>
<div
className="s-btn"
onClick={this._onSaveCustomDomain}
data-track-id="Update Custom Domain Button">
{__('Update')}
{['updating', 'checking'].includes(customDomainStatus) ? (
<i className="fa fa-spinner fa-pulse right-icon" />
) : null}
{customDomainSaved ? <i className="fa fa-check" /> : null}
</div>
{ConfStore.getCanSeeDomainTransferTab() &&
!isSxl &&
hasNoDomainId &&
customDomainStatus !== 'updating' && (
<a
target="_blank"
href="/s#/v2_domains/transfer"
data-track-id="Click Transfer Domain Button">
{__('Transfer your domain to us!')}
</a>
)}
{isSxl &&
currentDomain && (
<i
......
......@@ -15,6 +15,11 @@ import * as editorStoreCreator from 'js/reducers/editorStoreCreator'
import ComponentKitContext from 'js/utils/ComponentKitContext'
import wrapErrorBoundary from 'js/components/ErrorBoundary'
import 'js/reactInit.es6'
import { initTrackEditor } from 'js/utils/track'
initTrackEditor() // analytics track init
// These two are direct reads so promises can be fired quicker
const supportedVerticals = ['personal']
const themeName = $S.stores.pageMeta.theme.name
......
......@@ -190,6 +190,7 @@
"console-polyfill": "^0.2.1",
"core-decorators": "^0.20.0",
"create-react-class": "^15.6.0",
"croppie": "^2.6.2",
"deasync": "^0.1.4",
"deepmerge": "^2.0.1",
"emotion": "^7.3.2",
......@@ -214,7 +215,7 @@
"hypernova-morearty": "git://github.com/strikingly/hypernova-morearty",
"hypernova-react": "^2.0.0",
"ie-version": "^0.1.0",
"immer": "^1.7.1",
"immer": "^1.5.0",
"immutable": "github:strikingly/immutable-js#6fecef1e909bfe8eba4908c3f5aa4f8e126ce163",
"in-viewport": "^3.4.1",
"invariant": "^2.2.1",
......
......@@ -287,7 +287,7 @@ export default {
const { coupon } = _getCart()
const amount = coupon.option.amount
return (discountItem.orderItem.price * amount) / 100
return discountItem.orderItem.price * amount / 100
} else {
return 0
}
......@@ -311,7 +311,7 @@ export default {
case 'percentage':
number = this.isInCondition('productId')
? this.getDiscountForProductCondition()
: (this.getTotalItemPriceNum() * coupon.option.amount) / 100
: this.getTotalItemPriceNum() * coupon.option.amount / 100
if (this.getDecimalNum() === 0) {
number = Math.round(number)
......@@ -432,7 +432,7 @@ export default {
return taxesNum
}
taxesNum = ((itemPrice - discountForTax) * taxesRate) / (1 + taxesRate)
taxesNum = (itemPrice - discountForTax) * taxesRate / (1 + taxesRate)
if (this.getDecimalNum() === 0) {
taxesNum = Math.round(taxesNum)
}
......@@ -447,14 +447,16 @@ export default {
} else if (this.userHasCouponWithType('percentage', coupon)) {
if (this.isInCondition('productId')) {
const item = this.getDiscountItem()
description = __(
'EcommerceCoupon|%{amount} off for %{productCount} %{productName} ',
{
productCount: options ? options.productCount : 1,
productName: options ? options.productName : item.product.name,
amount: `${coupon.option.amount}%`,
},
)
if (item) {
description = __(
'EcommerceCoupon|%{amount} off for %{productCount} %{productName} ',
{
productCount: options ? options.productCount : 1,
productName: options ? options.productName : item.product.name,
amount: `${coupon.option.amount}%`,
},
)
}
} else {
description = __('EcommerceCoupon|%{amount} Off', {
amount: `${coupon.option.amount}%`,
......@@ -860,10 +862,11 @@ export default {
if (!item) {
return false
}
return (
path(['payload', 'item', 'parent_id'])(category) &&
pathEq(['payload', 'item', 'level'], 2)(category)
)
return category.parent_id > -1 && category.level === 2
// return (
// path(['payload', 'item', 'parent_id'])(category) &&
// pathEq(['payload', 'item', 'level'], 2)(category)
// )
},
sortedCategory(categories, orderList) {
orderList = orderList || {}
......
require('./init')
import React from 'react'
import $ from 'jquery'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import { ErrorBoundary } from 'js/components/ErrorBoundary'
import * as i18nHelper from 'js/utils/helpers/i18nHelper'
import { Provider } from 'react-redux'
import ComponentKitContext from 'js/utils/ComponentKitContext'
import { createStore, applyMiddleware, compose } from 'redux'
import thunkMiddleware from 'redux-thunk'
import PaypalPopupDialog from 'js/components/dialogs/PaypalPopupDialog'
import {
Router,
Route,
IndexRedirect,
IndexRoute,
hashHistory,
} from 'react-router'
import { syncHistoryWithStore } from 'react-router-redux'
import reducers from 'nextgen/app/reducers'
import MiniprogramDashboard from 'nextgen/dashboard/miniprogram/components/dashboard'
import Domains from 'nextgen/app/scenes/Domains'
import Domain from 'nextgen/app/scenes/Domain'
import DomainPurchase from 'nextgen/app/scenes/DomainPurchase'
import { initTrack } from 'js/utils/track'
initTrack() // analytics track init
const middleware = [thunkMiddleware]
const composeEnhancers =
(localStorage &&
localStorage.getItem('__strk_developer__') &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
compose
const store = createStore(
reducers,
composeEnhancers(applyMiddleware(...middleware)),
)
// Create an enhanced history that syncs navigation events with the store
const history = syncHistoryWithStore(hashHistory, store, {
selectLocationState: state => state.get('router').toJS(),
})
function EmptyComponent() {
return <div />
}
function recordLatestViewedHash(nextState, replace) {
const highlightClass = {
miniprogram: '.my-miniprogram',
v2_domains: '.my-domains',
}[location.hash && location.hash.split('/')[1]]
$('.subnav-container .s-link')
.removeClass('current')
.filter(highlightClass)
.addClass('current')
if (localStorage && ['#/miniprogram'].indexOf(location.hash) !== -1) {
localStorage.setItem('dashboard_latest_viewed_hash', location.hash)
}
}
class DashboardRouter extends React.Component {
static childContextTypes() {
PropTypes.object
}
static getChildContext() {
return { location: this.props.location }
}
componentWillMount() {
$('.nav-menu .s-link')
.removeClass('current')
.filter('.my-sites')
.addClass('current')
}
render() {
return (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={EmptyComponent} />
<Route
path="/miniprogram"
component={MiniprogramDashboard}
onEnter={recordLatestViewedHash}
/>
<Route
path="/v2_domains"
component={Domains}
onEnter={recordLatestViewedHash}
/>
<Route
path="/v2_domains/purchase"
component={DomainPurchase}
onEnter={recordLatestViewedHash}
/>
<Route
path="/v2_domains/:domainId"
component={Domain}
onEnter={recordLatestViewedHash}
/>
</Router>
</Provider>
)
}
}
const p1 = require(`promise-loader?global!locales/${i18nHelper.getTranslationFile()}`)
Promise.all([p1()])
.then(([poFile]) => {
const I18n = require('js/utils/i18n')
I18n.init(poFile)
const DashboardRouterWithContext = ComponentKitContext(DashboardRouter)
$(() => {
ReactDOM.render(
<ErrorBoundary>
<AppContainer>
<Provider store={store}>
<DashboardRouterWithContext />
</Provider>
</AppContainer>
<PaypalPopupDialog />
</ErrorBoundary>,
document.getElementById('mainDashboard'),
)
})
})
.catch(e => {
console.error(e, e.stack)
})
if (module.hot) {
module.hot.accept(err => {
if (err) {
console.error(err)
}
})
}
......@@ -620,7 +620,7 @@ class DomainsTab extends React.Component {
const v2DomainConnection = PageMetaStore.getV2DomainConnection()
const showConnectedMessage =
v2DomainConnection && v2DomainConnection.get('domain_id')
const forceShowKB =
const hasNoDomainId =
v2DomainConnection && !v2DomainConnection.get('domain_id')
const isSiteOfResellerClient = PageMetaStore.isSiteOfResellerClient()
const canBuyAllDomains = ConfStore.getCanBuyAllDomains()
......@@ -763,7 +763,7 @@ class DomainsTab extends React.Component {
)
}
const domainSettingsRs = this._renderDomainSettingsBox(forceShowKB)
const domainSettingsRs = this._renderDomainSettingsBox(hasNoDomainId)
const MoreartyInput = Morearty.DOM.input
return (
......@@ -793,7 +793,7 @@ class DomainsTab extends React.Component {
)}
&nbsp;
<a
href={v2DomainSetting ? '/s/v2_domains/' : '/s#/domains'}
href={v2DomainSetting ? '/s#/v2_domains/' : '/s#/domains'}
target="_blank">
{__('Domain|View your new domain in domain dashboard.')}
</a>
......@@ -872,6 +872,17 @@ class DomainsTab extends React.Component {
) : null}
{customDomainSaved ? <i className="fa fa-check" /> : null}
</div>
{ConfStore.getCanSeeDomainTransferTab() &&
!isSxl &&
hasNoDomainId &&
customDomainStatus !== 'updating' && (
<a
target="_blank"
href="/s#/v2_domains/transfer"
data-track-id="Click Transfer Domain Button">
{__('Transfer your domain to us!')}
</a>
)}
{isSxl &&
currentDomain && (
<i
......
......@@ -16,9 +16,9 @@ import ComponentKitContext from 'js/utils/ComponentKitContext'
import wrapErrorBoundary from 'js/components/ErrorBoundary'
import 'js/reactInit.es6'
import { initTrack } from 'js/utils/track'
import { initTrackEditor } from 'js/utils/track'
initTrack() // analytics track init
initTrackEditor() // analytics track init
// These two are direct reads so promises can be fired quicker
const supportedVerticals = ['personal']
......
......@@ -62,8 +62,10 @@
"@types/immutable": "^3.8.7",
"@types/isomorphic-fetch": "^0.0.33",
"@types/jest": "^21.1.2",
"@types/jquery": "^3.3.9",
"@types/lodash": "^4.14.61",
"@types/normalizr": "^2.0.18",
"@types/prop-types": "^15.5.5",
"@types/ramda": "^0.25.36",
"@types/react": "16.0.40",
"@types/react-dom": "^16.0.4",
......@@ -191,6 +193,7 @@
"console-polyfill": "^0.2.1",
"core-decorators": "^0.20.0",
"create-react-class": "^15.6.0",
"croppie": "^2.6.2",
"deasync": "^0.1.4",
"deepmerge": "^2.0.1",
"emotion": "^7.3.2",
......
......@@ -398,6 +398,10 @@
version "21.1.10"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-21.1.10.tgz#dcacb5217ddf997a090cc822bba219b4b2fd7984"
"@types/jquery@^3.3.9":
version "3.3.9"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.9.tgz#91f2aaf5c1e91fd79598fc00ecb4504d78b51fd7"
"@types/lodash@^4.14.61":
version "4.14.106"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.106.tgz#6093e9a02aa567ddecfe9afadca89e53e5dce4dd"
......@@ -416,6 +420,12 @@
dependencies:
normalizr "*"
"@types/prop-types@^15.5.5":
version "15.5.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.5.tgz#17038dd322c2325f5da650a94d5f9974943625e3"
dependencies:
"@types/react" "*"
"@types/ramda@^0.25.36":
version "0.25.36"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.25.36.tgz#1ddaf3211c7cd7046fcaefe68c713469ccfc9504"
......@@ -458,8 +468,8 @@
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.40.tgz#caabc2296886f40b67f6fc80f0f3464476461df9"
"@types/redux-form@^6.3.6":
version "6.6.17"
resolved "https://registry.yarnpkg.com/@types/redux-form/-/redux-form-6.6.17.tgz#e929df69844734c77d41950affcfa5d1ac1485d9"
version "6.6.21"
resolved "https://registry.yarnpkg.com/@types/redux-form/-/redux-form-6.6.21.tgz#e1bcb156ae78987d74feec196da99d3c45703c0c"
dependencies:
"@types/react" "*"
redux "^3.6.0"
......@@ -4269,6 +4279,10 @@ create-react-class@15.x, create-react-class@^15.5.1, create-react-class@^15.5.2,
loose-envify "^1.3.1"
object-assign "^4.1.1"
croppie@^2.6.2:
version "2.6.2"
resolved "http://registry.npm.taobao.org/croppie/download/croppie-2.6.2.tgz#d605ceeffb4aea281f72a63c9a0a305db0a46e50"
cross-spawn@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.0.1.tgz#a3bbb302db2297cbea3c04edf36941f4613aa399"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment