plans.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /* eslint-disable
  2. camelcase,
  3. max-len
  4. */
  5. import App from '../base'
  6. App.factory('MultiCurrencyPricing', function() {
  7. const currencyCode = window.recomendedCurrency
  8. return {
  9. currencyCode,
  10. plans: {
  11. USD: {
  12. symbol: '$',
  13. student: {
  14. monthly: '$8',
  15. annual: '$80'
  16. },
  17. collaborator: {
  18. monthly: '$15',
  19. annual: '$180'
  20. },
  21. professional: {
  22. monthly: '$30',
  23. annual: '$360'
  24. }
  25. },
  26. EUR: {
  27. symbol: '€',
  28. student: {
  29. monthly: '€7',
  30. annual: '€70'
  31. },
  32. collaborator: {
  33. monthly: '€14',
  34. annual: '€168'
  35. },
  36. professional: {
  37. monthly: '€28',
  38. annual: '€336'
  39. }
  40. },
  41. GBP: {
  42. symbol: '£',
  43. student: {
  44. monthly: '£6',
  45. annual: '£60'
  46. },
  47. collaborator: {
  48. monthly: '£12',
  49. annual: '£144'
  50. },
  51. professional: {
  52. monthly: '£24',
  53. annual: '£288'
  54. }
  55. },
  56. SEK: {
  57. symbol: 'kr',
  58. student: {
  59. monthly: '60 kr',
  60. annual: '600 kr'
  61. },
  62. collaborator: {
  63. monthly: '110 kr',
  64. annual: '1320 kr'
  65. },
  66. professional: {
  67. monthly: '220 kr',
  68. annual: '2640 kr'
  69. }
  70. },
  71. CAD: {
  72. symbol: '$',
  73. student: {
  74. monthly: '$9',
  75. annual: '$90'
  76. },
  77. collaborator: {
  78. monthly: '$17',
  79. annual: '$204'
  80. },
  81. professional: {
  82. monthly: '$34',
  83. annual: '$408'
  84. }
  85. },
  86. NOK: {
  87. symbol: 'kr',
  88. student: {
  89. monthly: '60 kr',
  90. annual: '600 kr'
  91. },
  92. collaborator: {
  93. monthly: '110 kr',
  94. annual: '1320 kr'
  95. },
  96. professional: {
  97. monthly: '220 kr',
  98. annual: '2640 kr'
  99. }
  100. },
  101. DKK: {
  102. symbol: 'kr',
  103. student: {
  104. monthly: '50 kr',
  105. annual: '500 kr'
  106. },
  107. collaborator: {
  108. monthly: '90 kr',
  109. annual: '1080 kr'
  110. },
  111. professional: {
  112. monthly: '180 kr',
  113. annual: '2160 kr'
  114. }
  115. },
  116. AUD: {
  117. symbol: '$',
  118. student: {
  119. monthly: '$10',
  120. annual: '$100'
  121. },
  122. collaborator: {
  123. monthly: '$18',
  124. annual: '$216'
  125. },
  126. professional: {
  127. monthly: '$35',
  128. annual: '$420'
  129. }
  130. },
  131. NZD: {
  132. symbol: '$',
  133. student: {
  134. monthly: '$10',
  135. annual: '$100'
  136. },
  137. collaborator: {
  138. monthly: '$18',
  139. annual: '$216'
  140. },
  141. professional: {
  142. monthly: '$35',
  143. annual: '$420'
  144. }
  145. },
  146. CHF: {
  147. symbol: 'Fr',
  148. student: {
  149. monthly: 'Fr 8',
  150. annual: 'Fr 80'
  151. },
  152. collaborator: {
  153. monthly: 'Fr 15',
  154. annual: 'Fr 180'
  155. },
  156. professional: {
  157. monthly: 'Fr 30',
  158. annual: 'Fr 360'
  159. }
  160. },
  161. SGD: {
  162. symbol: '$',
  163. student: {
  164. monthly: '$12',
  165. annual: '$120'
  166. },
  167. collaborator: {
  168. monthly: '$20',
  169. annual: '$240'
  170. },
  171. professional: {
  172. monthly: '$40',
  173. annual: '$480'
  174. }
  175. }
  176. }
  177. }
  178. })
  179. App.controller('PlansController', function(
  180. $scope,
  181. $modal,
  182. eventTracking,
  183. MultiCurrencyPricing,
  184. $http,
  185. $filter,
  186. ipCookie,
  187. $location
  188. ) {
  189. let switchEvent
  190. $scope.showPlans = true
  191. $scope.plans = MultiCurrencyPricing.plans
  192. $scope.currencyCode = MultiCurrencyPricing.currencyCode
  193. $scope.trial_len = 7
  194. $scope.planQueryString = '_free_trial_7_days'
  195. $scope.ui = { view: 'monthly' }
  196. $scope.changeCurreny = function(e, newCurrency) {
  197. e.preventDefault()
  198. $scope.currencyCode = newCurrency
  199. }
  200. // because ternary logic in angular bindings is hard
  201. $scope.getCollaboratorPlanCode = function() {
  202. const { view } = $scope.ui
  203. if (view === 'annual') {
  204. return 'collaborator-annual'
  205. } else {
  206. return `collaborator${$scope.planQueryString}`
  207. }
  208. }
  209. $scope.signUpNowClicked = function(plan, location) {
  210. if ($scope.ui.view === 'annual') {
  211. plan = `${plan}_annual`
  212. }
  213. plan = eventLabel(plan, location)
  214. eventTracking.sendMB('plans-page-start-trial')
  215. eventTracking.send('subscription-funnel', 'sign_up_now_button', plan)
  216. }
  217. $scope.switchToMonthly = function(e, location) {
  218. const uiView = 'monthly'
  219. switchEvent(e, uiView + '-prices', location)
  220. $scope.ui.view = uiView
  221. }
  222. $scope.switchToStudent = function(e, location) {
  223. const uiView = 'student'
  224. switchEvent(e, uiView + '-prices', location)
  225. $scope.ui.view = uiView
  226. }
  227. $scope.switchToAnnual = function(e, location) {
  228. const uiView = 'annual'
  229. switchEvent(e, uiView + '-prices', location)
  230. $scope.ui.view = uiView
  231. }
  232. $scope.openGroupPlanModal = function() {
  233. const path = `${window.location.pathname}${window.location.search}`
  234. history.replaceState(null, document.title, path + '#groups')
  235. $modal
  236. .open({
  237. templateUrl: 'groupPlanModalPurchaseTemplate',
  238. controller: 'GroupPlansModalPurchaseController'
  239. })
  240. .result.finally(() =>
  241. history.replaceState(null, document.title, window.location.pathname)
  242. )
  243. eventTracking.send(
  244. 'subscription-funnel',
  245. 'plans-page',
  246. 'group-inquiry-potential'
  247. )
  248. }
  249. if ($location.hash() === 'groups') {
  250. $scope.openGroupPlanModal()
  251. }
  252. var eventLabel = (label, location) => label
  253. switchEvent = function(e, label, location) {
  254. e.preventDefault()
  255. const gaLabel = eventLabel(label, location)
  256. eventTracking.send('subscription-funnel', 'plans-page', gaLabel)
  257. }
  258. })
  259. App.controller('GroupPlansModalPurchaseController', function(
  260. $scope,
  261. $modal,
  262. $location
  263. ) {
  264. $scope.options = {
  265. plan_codes: [
  266. {
  267. display: 'Collaborator',
  268. code: 'collaborator'
  269. },
  270. {
  271. display: 'Professional',
  272. code: 'professional'
  273. }
  274. ],
  275. currencies: [
  276. {
  277. display: 'USD ($)',
  278. code: 'USD'
  279. },
  280. {
  281. display: 'GBP (£)',
  282. code: 'GBP'
  283. },
  284. {
  285. display: 'EUR (€)',
  286. code: 'EUR'
  287. }
  288. ],
  289. currencySymbols: {
  290. USD: '$',
  291. EUR: '€',
  292. GBP: '£'
  293. },
  294. sizes: [2, 3, 4, 5, 10, 20, 50],
  295. usages: [
  296. {
  297. display: 'Enterprise',
  298. code: 'enterprise'
  299. },
  300. {
  301. display: 'Educational',
  302. code: 'educational'
  303. }
  304. ]
  305. }
  306. $scope.prices = window.groupPlans
  307. let currency = 'USD'
  308. if (['USD', 'GBP', 'EUR'].includes(window.recomendedCurrency)) {
  309. currency = window.recomendedCurrency
  310. }
  311. // default selected
  312. $scope.selected = {
  313. plan_code: 'collaborator',
  314. currency,
  315. size: '10',
  316. usage: 'educational'
  317. }
  318. // selected via query
  319. if ($location.search()) {
  320. // usage
  321. if ($location.search().usage) {
  322. $scope.options.usages.forEach(usage => {
  323. if (usage.code === $location.search().usage) {
  324. $scope.selected.usage = usage.code
  325. }
  326. })
  327. }
  328. // plan
  329. if ($location.search().plan) {
  330. $scope.options.plan_codes.forEach(plan => {
  331. if (plan.code === $location.search().plan) {
  332. $scope.selected.plan_code = plan.code
  333. }
  334. })
  335. }
  336. // number
  337. if ($location.search().number) {
  338. // $location.search().number is a string,
  339. // but $scope.options.sizes are numbers
  340. // and $scope.selected.size is a string
  341. const groupCount = parseInt($location.search().number, 10)
  342. if ($scope.options.sizes.indexOf(groupCount) !== -1) {
  343. $scope.selected.size = $location.search().number
  344. }
  345. }
  346. // currency
  347. if ($location.search().currency) {
  348. $scope.options.currencies.forEach(currency => {
  349. if (currency.code === $location.search().currency) {
  350. $scope.selected.currency = currency.code
  351. }
  352. })
  353. }
  354. }
  355. $scope.recalculatePrice = function() {
  356. let { usage, plan_code, currency, size } = $scope.selected
  357. const price = $scope.prices[usage][plan_code][currency][size]
  358. const currencySymbol = $scope.options.currencySymbols[currency]
  359. $scope.displayPrice = `${currencySymbol}${price}`
  360. }
  361. $scope.$watch('selected', $scope.recalculatePrice, true)
  362. $scope.recalculatePrice()
  363. $scope.purchase = function() {
  364. let { plan_code, size, usage, currency } = $scope.selected
  365. plan_code = `group_${plan_code}_${size}_${usage}`
  366. window.location = `/user/subscription/new?planCode=${plan_code}&currency=${currency}&itm_campaign=groups`
  367. }
  368. })