- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
<template>
<div class="root">
<!-- TopNavBar Component -->
<TopNav />
<!-- Only show masthead-offer if we have a message to show -->
<section class="masthead-offer" v-if="mastheadOfferMessage">
{{ mastheadOfferMessage }}
</section>
<!-- Masthead Component-->
<div class="masthead desktop"
v-if="!this.isMobile"
:style="{
'background-image': `url(https://www.rosettastone.com/lp/US/masthead/sbsr/${this.modelName}.jpg)`
}">
</div>
<div class="masthead mobile"
v-else
:style="{
'background-image': `url(https://www.rosettastone.com/lp/US/masthead/mobile/${this.modelName}.jpg)`
}">
</div>
<!-- Holds lang select for desktop and mobile. and Desktop's languages list. -->
<section class="languages-wrap">
<div class="content">
<div>I want to learn</div>
<div>
<SelectLanguage v-bind={onLangChange} :selectedLang='selectedLang' />
</div>
</div>
</section>
<section class="products-container">
<div class="content">
<div class="products">
<!-- Loop through our products | ProductBox Component -->
<ProductBox v-for="(product, key) in products"
:msrp='product.msrp'
:price='product.price'
:level='product.lvl'
:name='product.name'
:cartlink='product.cart'
:key=key
/>
</div>
<!-- Guarantee Component -->
<div class="guarantee-wrapper">
<Guarantee />
</div>
</div> <!-- /content -->
</section>
<section class="highlights content">
<h3>Get the proven program and start speaking</h3>
<div>
<div class="bullets">
<div>
<p>
The flexibility to learn a new language <b>on your schedule, with any device, from anywhere in the world</b>. You'll get full access to all of our latest features and can <b>start learning immediately</b> - no lengthy downloads or installations required.
</p>
<ul>
<li>
<b>Immediate access to all levels</b> of the world's best language learning program
</li>
<li>
<b>Access on any device</b>, including our award winning mobile app
</li>
<li>
<b>The most advanced speech technology</b>
with our only product that updates as new features are released
</li>
<li>
<b>Download lessons</b> to your mobile device to continue learning offline
</li>
</ul>
</div>
</div>
<!-- product image -->
<div class="product-img"></div>
</div>
</section>
<section class="trusted">
<div class="content">
<h3>Trusted for <b>25 years</b> by top companies and agencies</h3>
<div class="logos">
<img alt="NASA" src="/lp/static/img/nasa-logo.svg">
<img alt="calvinklein" src="/lp/static/img/calvinklein-logo.png">
<img alt="fender" src="/lp/static/img/fender-logo.png">
<img alt="tripadvisor" src="/lp/static/img/tripadvisor-logo.png">
<img alt="tommyhilfiger" src="/lp/static/img/tommy-logo.png">
</div>
</div>
</section>
<section class="macworld">
<div class="content">
<h3>Macworld</h3>
<p>
"With its excellent user interface, clear instructions, wide variety of games and challenges...
<br>
<b>Rosetta Stone has got it going on</b>
</p>
</div>
</section>
<section class="footer">
<div class="content">
<div class="socialicons">
<a target="_blank" class="facebook" href="http://www.facebook.com/RosettaStone">
<img src="/lp/static/img/icon-fb.png" alt="facebook">
</a>
<a target="_blank" class="twitter" href="http://twitter.com/rosettastone">
<img src="/lp/static/img/icon-twitter.png" alt="twitter">
</a>
<a target="_blank" class="youtube" href="http://www.youtube.com/user/rosettastone">
<img src="/lp/static/img/icon-youtube.png" alt="youtube">
</a>
</div>
<p>
* Free shipping on products shipped within the U.S. only. Offer limited to purchases made directly from Rosetta Stone and cannot be combined with any other offer. Offer valid <span id="expirationdate">{{ this.expirationdate }}</span> at 03:59am EST while quantities last. Online services must be activated within 6 months of purchase or are subject to forfeiture.
</p>
<p>
If you elect to pay via an available Easy Payment plan option, the full payment price will be charged in the applicable number of installments. The first payment (plus any applicable shipping and tax on the total purchase price), will be charged to the payment account you selected on the Order Page on the Purchase Date. Thereafter, your account will be charged each month for the remaining number of payments of the plan you selected, with 0% APR and no interest charged from Rosetta Stone.
</p>
<p>
* Installment Payment Plan options are made available on select product purchases only and require a valid billing address. Additional restrictions may apply.
</p>
<p>
† 3 months online access included with purchase for one user for CD-ROM and Download products.
</p>
<p>
The thirty-day (30-day) money back guarantee is limited to software purchases made directly from Rosetta Stone, and does not apply to any supplemental purchases, including additional online access, subscription renewals, and headsets. <a href="http://www.rosettastone.com/global/return" target="_blank">See Full Details</a>
</p>
<p>© 1999 - 2018 Rosetta Stone Ltd. All Rights Reserved. </p>
<p><a href="//rosettastone.com/terms" target="_blank">Terms and Conditions</a></p>
<p><a href="//rosettastone.com/agreements" target="_blank">Agreements</a></p>
<p><a href="//rosettastone.com/privacy" target="_blank">Privacy Policy</a>.</p>
</div>
</section>
</div>
</template>
<script>
// Import our Components
import TopNav from '~/components/TopNav.vue'
import SelectLanguage from '~/components/SelectLanguage.vue'
import ProductBox from '~/components/ProductBox.vue'
import Guarantee from '~/components/Guarantee.vue'
import axios from 'axios'
export default {
/* Components this page uses. They are imported above */
components: {
TopNav,
SelectLanguage,
ProductBox,
Guarantee
},
/*
* Sets head information for this page.
* Metadata, scripts, css, title, etc, can
* all be set and fetched here
*/
head ()
{
return {
title: 'Rosetta Stone - Learn a New Language',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Rosetta Stone' }
],
/*
link: [
{ rel: 'subresource', href:`https://www.rosettastone.com/lp/US/masthead/sbsr/${this.modelName}.jpg` },
{ rel: 'subresource', href:`https://www.rosettastone.com/lp/US/masthead/mobile/${this.modelName}.jpg` }
],
*/
script: [
{ src: `//rosettastone.com/lp/static/data/us/models/${this.modelName}.js`, body: true },
{ src: '/lp/static/js/dtm.js', body: true },
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.slim.min.js', body: true},
{
src: '//assets.adobedtm.com/289d54d757557d351111069aa8acc743e67b15e6/satelliteLib-7aef1085f7c59294e8610e2f691a22c48a200841.js',
body: true
},
{ src: '/lp/static/js/clock.js', body: true },
{ src: '/lp/static/js/crescendo.js', body: true }
]
}
},
/*
* This function is called on the server. (ie, when Nuxt Generate is ran)
* We use this function to set some of the client's state data while on the server.
* For isntance, we set the state 'modelName' so that the
* head() function above knows which model.js to download.
* We set as much of the page's state here as we can.
*
* Remember that this is NOT ran on the client, so using things
* like `window.foo` won't work.
*
* The only reason we have the RSI() function here is so we can
* generate products on the server side, and client will be rendered
* with the products (no flicker / delayed view). It fills the
* `productList` state data
*/
async asyncData ({ params, route })
{
// TODO this. Parser needs to put the json files in ftp
//var json = await axios.get('https://www.rosettastone.com/lp/globals/models-json/sitewide.json')
var json = await axios.get(`https://www.rosettastone.com/lp/static/data/us/products-json/sitewide.json`)
function RSI(e) {
function n(e) {
if (typeof e != "object") return [];
var n = [],
r = t.slice(),
i = [],
s;
for (var o in e) e.hasOwnProperty(o) && i.push([o, e[o]]);
var u;
if (!i.length) return [];
while (s = r.pop()) {
u = !0;
for (var a = 0, f = i.length; a < f; a++) {
var l = i[a][0],
c = i[a][1];
if (!s[l] || s[l] !== c) u = !1, a = f
}
u && n.push(s)
}
return n
}
var t = json.data
return e ? n(e) : t
}
// Server will render products with 'esp'
let products = RSI({cat: 'esp', media: 'subscription'})
// Set page's state data here
return {
modelName: route.params.page,
productList: products
}
},
/*
* Page state data.
* These get set in the "server" when `nuxt generate` is ran,
* and for this reason, we cannot use window.RSI here to fill these,
* so we set them to null, and then the client will give them values
* in the `beforeMount` method, since that is ran on the client
* and we will have fetched our RSI model js file in the `head`.
* NOTE: these values can be set on beforeMount directly,
* there's no need to set values here to null and have beforeMount
* overwrite them.
* The only values we need here are variables we use in
* `computed()`
*/
data()
{
return {
// Will hold RSI model
//model : null,
// Holds name RSI.rsi value (sitewide, sale, etc). Set on the server with $route
modelName: null,
// Our current 3-letter selected lang code (esp, ita, etc)
// Set via click, dropdown change, url param, etc
selectedLang: this.$route.query.lang || 'esp',
// Full name of the selectedLang (French, Italian, etc)
languageName: null,
// List of products to show. Each time a language is changed, this
// gets populated and the product view gets updated (new cart urls, etc)
productList: [],
// Products we don't want to show
// TODO is is possible to change this via console, from window? so if onemonth=true is in url,
// we change the state from outside app
filter: [ '1', '8', '18', '3F3', '6F6' ],
// If there's a special offer message, this will hold it.
mastheadOfferMessage: null,
// Holds RSI.expirationDate
expirationdate: null,
// Needed for the sole purpose of hiding/showing masthead components.
isMobile: null
}
},
/*
* Called on client side.
* We use this to fill State data above
* before mount, since the /lp/globals/models/<model>.js
* has been loaded into the browser's window object.
* This essentially is our state data.
*/
beforeMount()
{
this.productList = RSI({cat: this.selectedLang, media: 'subscription'})
this.languageName = RSI({cat: this.selectedLang})[0].language
this.expirationdate = RSI.expirationDate
this.isMobile = window.innerWidth <= 540 ? true : false
if (this.$route.query.onemonth )
{
this.filter = this.filter.map(e => e+'' == '1' ? `3` : e)
}
// This exposes state data to window. Maybe needed when using TnT, etc
window.data = this
},
/* Any method called by the template view (ie, event handling) */
methods: {
// Usually called from inside a select-language component
onLangChange(langCode)
{
this.selectedLang = langCode
this.languageName = RSI({cat: langCode})[0].language
this.productList = RSI({cat: langCode, media: 'subscription'})
console.log(this.productList)
},
},
computed: {
/*
* Everytime state's productList gets updated with a new value,
* this computed property will automatically be updated too.
* We have this computed property so we don't have to
* filter/map/sort theproductsList each time we update it.
* Use this in the template view instead of productList
*/
products ()
{
return this.productList
.filter(p => this.filter.indexOf(p.lvl) == -1 )
// p.name = p.lvl ?
//.map(p => { p.name = p.name.replace(/-.*/, '') ; return p })
.map(p => {p.name = p.lvl; return p})
.sort( (a, b) => a.lvl < b.lvl ? -1 : 1)
}
},
}
</script>
<style lang='stylus'>
@require '~assets/css/variables'
body
margin 0
padding 0
//font-family gotham-book, arial
font-family gothamlight
.content
max-width 1150px
margin 0 auto
padding 0 1em
.masthead-offer
background $yellow
text-align center
padding 1.3em 0
font-size 1.3em
.masthead
background-size 100% 100%
padding 25% 0% 5% 0
line-height 1
box-shadow 0 4px 10px -6px inset
box-sizing border-box
&.desktop
@media $small
display none
&.mobile
display none
@media $small
display block
height 190px
padding 8% 0% 5% 0%
.languages-wrap
background #f1f1f1
padding-top 2em
.content
display flex
flex-direction row
justify-content center
& > div:first-of-type
align-self center
font-size 1.8em
padding-right 1em
@media $small
flex-direction column
& > div:first-of-type
font-size 1.2em
font-weight 100
padding 0 0 20px 0
.products-container
padding 3em 0
background #f1f1f1
p:first-of-type
margin 4em 0
.products
display flex
flex-wrap wrap
justify-content space-between
@media $medium
justify-content space-around
@media $small
// Reverse product order in mobile
list = 1..15
for n in list
.product:nth-child({n})
order list[-(n)]
.highlights
padding 3em
h3
margin 0 0 2 0
font-size 180%
& > div
display flex
.bullets
flex-basis 50%
p
margin-bottom 3em
line-height 26px
ul
padding 0
margin 0
list-style none
li
margin-bottom 1em
background url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjNweCIgaGVpZ2h0PSIxNnB4IiB2aWV3Qm94PSIwIDAgMjMgMTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUwLjIgKDU1MDQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5jaGVjazM1PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkxwLWxheW91dC12YWx1ZS1wcm9wLXByb21vIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYuMDAwMDAwLCAtNDI3LjAwMDAwMCkiIGZpbGw9IiMzRjkzRDMiIGZpbGwtcnVsZT0ibm9uemVybyI+CiAgICAgICAgICAgIDxnIGlkPSJjaGVjazM1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNi4wMDAwMDAsIDQyNy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0yMi43MjMxMjY2LDIuNDg2ODk2NTUgTDguNTc2Mzc5NzUsMTUuODkxMzEwMyBDOC40NTE3NzIxNSwxNi4wMDkzNzkzIDguMjUwMDEyNjYsMTYuMDA5Mzc5MyA4LjEyNTY5NjIsMTUuODkxMzEwMyBMMC4wOTMxNjQ1NTcsOC4yOCBDLTAuMDMxMTUxODk4Nyw4LjE2MjQ4Mjc2IC0wLjAzMTE1MTg5ODcsNy45NzEzMTAzNCAwLjA5MzE2NDU1Nyw3Ljg1MzI0MTM4IEwyLjA0NDk2MjAzLDYuMDAzODYyMDcgQzIuMTY5NTY5NjIsNS44ODYwNjg5NyAyLjM3MTMyOTExLDUuODg2MDY4OTcgMi40OTU2NDU1Nyw2LjAwMzg2MjA3IEw4LjM1MTMyOTExLDExLjU1MiBMMjAuMzIwOTM2NywwLjIxMDQ4Mjc1OSBDMjAuNDQ1ODM1NCwwLjA5MjY4OTY1NTIgMjAuNjQ3MDEyNywwLjA5MjY4OTY1NTIgMjAuNzcxNjIwMywwLjIxMDQ4Mjc1OSBMMjIuNzIzMTI2NiwyLjA1OTg2MjA3IEMyMi44NDc3MzQyLDIuMTc3NjU1MTcgMjIuODQ3NzM0MiwyLjM2ODU1MTcyIDIyLjcyMzEyNjYsMi40ODY4OTY1NSBaIiBpZD0iU2hhcGUiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+') no-repeat 0 12px
padding 10px 0 0 30px
.product-img
flex-basis 50%
background url(/lp/static/img/online-lockup.png) no-repeat;
background-size contain
margin-left 5em
@media $medium
& > div
flex-direction column
.bullets
order 1
.product-img
order 0
height 290px
margin 2em 0
background-position center
.trusted
background #f1f1f1
padding 5em 0
box-sizing border-box
box-shadow 0 2px 3px rgba(0,0,0,.3)
& > div
text-align center
h3
font-size 1.6em
font-weight lighter
margin-bottom 2em
.logos
display flex
align-items center
justify-content space-between
img:nth-of-type(1)
height 95px
img:nth-of-type(2)
height 30px
width 20%
img:nth-of-type(3)
height 35px
img:nth-of-type(4)
width 12%
img:nth-of-type(5)
width 12%
.reviews
overflow hidden
margin 4em 0
.macworld
margin 0
background #269acd
color #fff
text-align center
padding 1em
.content
line-height 25px
background url(/lp/static/img/macworld-review.svg) no-repeat center
background-size contain
h3
color #fff
margin-bottom 10px
font-size 160%
margin 0
font-weight 100
p
margin-bottom 0
.footer
background $lightblack
color #fff
font-size 80%
padding 4em 0
line-height 20px
.socialicons
text-align center
margin-bottom 2em
a
display inline-block
margin-right 20px
a
color $yellow
</style>