Merge branch 'master-redesign' into master-redesign-templates-and-blog

Conflicts:
	public/coffee/app/main.coffee
This commit is contained in:
Henry Oswald 2014-07-08 11:14:56 +01:00
commit 6dc9d32104
27 changed files with 1902 additions and 787 deletions

View file

@ -123,6 +123,8 @@ module.exports = ProjectController =
TagsHandler.getAllTags user_id, cb
projects: (cb)->
Project.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref', cb
subscription: (cb)->
SubscriptionLocator.getUsersSubscription user_id, cb
}, (err, results)->
if err?
logger.err err:err, "error getting data for project list page"
@ -138,6 +140,7 @@ module.exports = ProjectController =
priority_title: true
projects: projects
tags: tags
hasSubscription: !!results.subscription
}
if Settings?.algolia?.institutions?.app_id? and Settings?.algolia?.institutions?.api_key?

View file

@ -15,17 +15,15 @@ module.exports = SubscriptionController =
plansPage: (req, res, next) ->
plans = SubscriptionViewModelBuilder.buildViewModel()
if !req.session.user?
for plan in plans
plan.href = "/register?redir=#{plan.href}"
baseUrl = "/register?redir="
else
baseUrl = ""
viewName = "subscriptions/plans"
if req.query.variant?
viewName += "-#{req.query.variant}"
logger.log viewName:viewName, "showing plans page"
res.render viewName,
title: "Plans and Pricing"
plans: plans
gaExperimentCode: gaExperimentCode
baseUrl: baseUrl
#get to show the recurly.js page
paymentPage: (req, res, next) ->
@ -168,22 +166,3 @@ module.exports = SubscriptionController =
return next(error) if error?
req.body = body
next()
gaExperimentCode = '''
<!-- Google Analytics Content Experiment code -->
<script>function utmx_section(){}function utmx(){}(function(){var
k='51652689-2',d=document,l=d.location,c=d.cookie;
if(l.search.indexOf('utm_expid='+k)>0)return;
function f(n){if(c){var i=c.indexOf(n+'=');if(i>-1){var j=c.
indexOf(';',i);return escape(c.substring(i+n.length+1,j<0?c.
length:j))}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;d.write(
'<sc'+'ript src="'+'http'+(l.protocol=='https:'?'s://ssl':
'://www')+'.google-analytics.com/ga_exp.js?'+'utmxkey='+k+
'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='+new Date().
valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+
'" type="text/javascript" charset="utf-8"><\/sc'+'ript>')})();
</script><script>utmx('url','A/B');</script>
<!-- End of Google Analytics Content Experiment code -->
'''

View file

@ -9,7 +9,7 @@ block content
h1 About us
h2 Meet the team behind your favourite online LaTeX editor.
p.team-profile
span.img-container
span.img-container.img-circle
img(src='/img/about/henry_oswald.jpg')
strong Henry Oswald
| built an experimental LaTeX editor in 2011 which later became ShareLaTeX. He is a trained software engineer who lives in London.
@ -18,7 +18,7 @@ block content
a(href='https://twitter.com/henryoswald') Follow me on Twitter
| .
p.team-profile
span.img-container
span.img-container.img-circle
img(src='/img/about/james_allen.jpg')
strong James Allen
| started working with Henry early in 2012 and finished his PhD in theoretical physics early in 2013. James began working on

View file

@ -3,9 +3,6 @@ html(itemscope, itemtype='http://schema.org/Product')
block vars
head
- if (typeof(gaExperimentCode) !== "undefined" && gaExperimentCode)
#{gaExperimentCode}
- if (typeof(priority_title) !== "undefined" && priority_title)
title= title + ' - Online LaTeX Editor ShareLaTeX'
- else

View file

@ -26,17 +26,17 @@ block content
ul.dropdown-menu(role="menu")
li
a(
href="#",
href,
ng-click="openCreateProjectModal()"
) Blank Project
li
a(
href="#",
href,
ng-click="openCreateProjectModal('example')"
) Example Project
li
a(
href="#",
href,
ng-click="openUploadProjectModal()"
) Upload Project
li.divider
@ -55,7 +55,8 @@ block content
a.menu-indent(href="/templates/bibliographies") Bibliographies
li
a.menu-indent(href="/templates") View All »
.row-spaced
.row-spaced(ng-if="projects.length > 0", ng-cloak)
ul.list-unstyled.folders-menu(
ng-controller="TagListController"
)
@ -67,7 +68,7 @@ block content
a(href, ng-click="filterProjects('shared')") Shared projects
li(ng-class="{active: (filter == 'archived')}")
a(href, ng-click="filterProjects('archived')") Deleted projects
li
li(ng-if="tags.length > 0")
h2 Folders
li(
ng-repeat="tag in tags | filter:nonEmpty",
@ -85,68 +86,40 @@ block content
| {{tag.name}}
span.subdued ({{tag.project_ids.length}})
-if (settings.enableSubscriptions)
.row-spaced
a(href="/user/bonus").btn.btn-info Upgrade Account
.row-spaced(ng-if="projects.length == 0", ng-cloak)
.first-project
div
i.fa.fa-arrow-up.fa-2x
div
strong Create your first project!
- if (showUserDetailsArea)
.row-spaced#userProfileInformation(ng-cloak)
div(ng-controller="UpdateForm").userProfileInformationArea
div(ng-hide="hidePersonalInfoSection").alert.alert-info
div(ng-show="percentComplete >= 100")
h4 100% complete, well done!
div(ng-hide="percentComplete >= 100")
h4 Your profile is
strong {{percentComplete}}%
| complete
.row-spaced#userProfileInformation(ng-if="projects.length > 0", ng-cloak)
div(ng-controller="UserProfileController")
hr(ng-show="percentComplete < 100")
.text-centered.user-profile(ng-show="percentComplete < 100")
.progress
.progress-bar.progress-bar-info(ng-style="{'width' : (percentComplete+'%')}")
button#completeUserProfileInformation.btn.btn-primary(
ng-hide="formVisable",
ng-click="showForm()"
) Complete now
p.small
| Your profile is
strong {{percentComplete}}%
| complete
div(ng-show="formVisable")
form(enctype='multipart/form-data', method='post')
.form-group
input.form-control(
type='text',
name='first_name',
ng-model="userInfoForm.first_name",
ng-blur="sendUpdate()",
placeholder="First Name",
select-when="formVisable"
)
.form-group
input.form-control(
type='text',
name='last_name',
ng-model="userInfoForm.last_name",
ng-blur="sendUpdate()",
placeholder='Last Name'
)
.form-group#institution_auto_complete
autocomplete(
ng-model="userInfoForm.institution",
data="institutions",
ng-blur="sendUpdate()",
on-type="updateInstitutionsList",
attr-placeholder="Institution",
attr-inputclass="form-control"
)
.form-group
input.form-control(
type='text',
name='role',
ng-model="userInfoForm.role",
placeholder='Role',
ng-blur="sendUpdate()",
list="_roles"
)
datalist#_roles
option(ng-repeat='role in roles') {{role}}
button#completeUserProfileInformation.btn.btn-info(
ng-hide="formVisable",
ng-click="openUserProfileModal()"
) Complete
-if (settings.enableSubscriptions && !hasSubscription)
.row-spaced(ng-if="projects.length > 0", ng-cloak).text-centered
hr
p.small You are using the free version of ShareLaTeX.
p
a(href="/user/subscription/plans").btn.btn-primary Upgrade
p.small
| or unlock some free bonus features by
a(href="/user/bonus") sharing ShareLaTeX.
.col-md-10
.container-fluid
@ -258,52 +231,59 @@ block content
.row.row-spaced
.col-md-12
.card.card-thin
- if (projects.length > 0)
ul.list-unstyled.project-list(select-all-list, ng-cloak)
li.container-fluid
.row
.col-md-6
input.select-all(
select-all,
type="checkbox"
)
span.title TITLE
.col-md-2
span.owner OWNER
.col-md-4
span.last-modified LAST MODIFIED
li.project_entry.container-fluid(
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
ng-controller="ProjectListItemController"
)
.row
.col-md-6
input.select-item(
select-individual,
type="checkbox",
ng-model="project.selected"
)
span.title
a.projectName(href="/project/{{project.id}}") {{project.name}}
span
span.label.label-default(ng-repeat='tag in project.tags')
| {{tag.name}}
.col-md-2
span.owner {{ownerName()}}
.col-md-4
span.last-modified.isoDate {{project.lastUpdated | formatDate}}
- else
.row
.span12
.welcome
h1
i.fa.fa-arrow-left
| Welcome! Follow the arrow to get started
p New to LaTeX? Start by having a look at our
a(href="/templates") templates
| or
a(href="/learn") help guides
| .
ul.list-unstyled.project-list.structured-list(
select-all-list,
ng-if="projects.length > 0",
ng-cloak
)
li.container-fluid
.row
.col-md-6
input.select-all(
select-all,
type="checkbox"
)
| TITLE
.col-md-2
| OWNER
.col-md-4
| LAST MODIFIED
li.project_entry.container-fluid(
ng-repeat="project in visibleProjects | orderBy:'lastUpdated':true",
ng-controller="ProjectListItemController"
)
.row
.col-md-6
input.select-item(
select-individual,
type="checkbox",
ng-model="project.selected"
)
span.title
a.projectName(href="/project/{{project.id}}") {{project.name}}
span
span.label.label-default(ng-repeat='tag in project.tags')
| {{tag.name}}
.col-md-2
span.owner {{ownerName()}}
.col-md-4
span.last-modified.isoDate {{project.lastUpdated | formatDate}}
li(
ng-if="visibleProjects.length == 0",
ng-cloak
)
.row
.col-md-12.text-centered
small No projects
div.welcome.text-centered(ng-if="projects.length == 0", ng-cloak)
h2 Welcome to ShareLaTeX!
p New to LaTeX? Start by having a look at our
a(href="/templates") templates
| or
a(href="/learn") help guides
| ,
br
| or create your first project on the left.
script(type='text/ng-template', id='newTagModalTemplate')
.modal-header
@ -436,3 +416,51 @@ block content
span Upload a zipped project
.modal-footer
button.btn.btn-default(ng-click="cancel()") Cancel
script(type="text/ng-template", id="userProfileModalTemplate")
.modal-header
h3 Your Profile
.modal-body
form(enctype='multipart/form-data', method='post')
.form-group
label(for="first_name") First Name
input.form-control(
type='text',
name='first_name',
ng-model="userInfoForm.first_name",
ng-blur="sendUpdate()",
placeholder="First Name",
select-when="formVisable"
)
.form-group
label(for="last_name") Last Name
input.form-control(
type='text',
name='last_name',
ng-model="userInfoForm.last_name",
ng-blur="sendUpdate()",
placeholder='Last Name'
)
.form-group#institution_auto_complete
label(for="institution") Institution
autocomplete(
ng-model="userInfoForm.institution",
name="institution",
data="institutions",
ng-blur="sendUpdate()",
on-type="updateInstitutionsList",
attr-placeholder="Institution",
attr-inputclass="form-control"
)
.form-group
label(for="role") Role
input.form-control(
type='text',
name='role',
ng-model="userInfoForm.role",
placeholder='Role',
ng-blur="sendUpdate()",
typeahead="role for role in roles | filter:$viewValue"
)
.modal-footer
button.btn.btn-info(ng-click="done()") Done

View file

@ -1,104 +1,106 @@
extends ../layout
block content
.container.bonus.box
.row
.span8.offset2
.page-header
h1 Recommend ShareLaTeX. Get free stuff.
.content.content-alt
.container.bonus
.row
.col-md-8.col-md-offset-2
.card
.container-fluid
.row
.col-md-12
.page-header
h1 Help us spread the word about ShareLaTeX.
.row
.span6.offset3
h2 Help us spread the word about ShareLaTeX.
.row
.col-md-10.col-md-offset-1
h2 Share ShareLaTeX with your friends and colleagues and unlock the rewards below
.row
.span4.offset4.bonus-banner
.bonus-top
.row
.col-md-8.col-md-offset-2.bonus-banner
.bonus-top
.row
.span4.offset4.bonus-banner
.title
a(href='https://twitter.com/share?text=is%20trying%20out%20the%20online%20LaTeX%20Editor%20ShareLaTeX&url=#{encodeURIComponent(buildReferalUrl("t"))}&counturl=https://www.sharelatex.com', target="_blank").twitter Tweet
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='https://twitter.com/share?text=is%20trying%20out%20the%20online%20LaTeX%20Editor%20ShareLaTeX&url=#{encodeURIComponent(buildReferalUrl("t"))}&counturl=https://www.sharelatex.com', target="_blank").twitter Tweet
.row
.span4.offset4.bonus-banner
.title
a(href='#', onclick='postToFeed(); return false;').facebook Post on Facebook
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='#', onclick='postToFeed(); return false;').facebook Post on Facebook
.row
.span4.offset4.bonus-banner
.title
a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl("gp"))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus Share us on Google+
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href="https://plus.google.com/share?url=#{encodeURIComponent(buildReferalUrl('gp'))}", onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;").google-plus Share us on Google+
.row
.span4.offset4.bonus-banner
.title
a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email Email us to your friends
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='mailto:?subject=Online LaTeX editor you may like &body=Hey, I have been using the online LaTeX editor ShareLaTeX recently and thought you might like to check it out. #{encodeURIComponent(buildReferalUrl("e"))}', title='Share by Email').email Email us to your friends
.row
.span4.offset4.bonus-banner
.title
a(href='#link-modal', data-toggle="modal").link Link to us from your website
.row
.col-md-8.col-md-offset-2.bonus-banner
.title
a(href='#link-modal', data-toggle="modal").link Link to us from your website
.row
.span4.offset4.bonus-banner
h2.direct-link Direct Link
.well #{buildReferalUrl("d")}
.row
.col-md-10.col-md-offset-1.bonus-banner
h2.direct-link Direct Link
pre.text-centered #{buildReferalUrl("d")}
.row.ab-bonus
.span6.offset3
p.thanks When someone starts using ShareLaTeX after your recommendation we'll give you some <strong>free stuff</strong> to say thanks! Check your progress below.
.row.ab-bonus
.span6.offset3(style="position: relative; height: 30px; margin-top: 20px;")
- for (var i = 0; i <= 10; i++) {
- if (refered_user_count == i)
.number(style="left: #{i}0%").active #{i}
- else
.number(style="left: #{i}0%") #{i}
- }
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner
p.thanks When someone starts using ShareLaTeX after your recommendation we'll give you some <strong>free stuff</strong> to say thanks! Check your progress below.
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 30px; margin-top: 20px;")
- for (var i = 0; i <= 10; i++) {
- if (refered_user_count == i)
.number(style="left: #{i}0%").active #{i}
- else
.number(style="left: #{i}0%") #{i}
- }
.row.ab-bonus
.span6.offset3
.progress(style="height: 25px")
- if (refered_user_count == 0)
div(style="text-align: center; padding: 4px;") Spread the word and fill this bar up
.bar(style="width: #{refered_user_count}0%")
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner
.progress
- if (refered_user_count == 0)
div(style="text-align: center; padding: 4px;") Spread the word and fill this bar up
.progress-bar.progress-bar-info(style="width: #{refered_user_count}0%")
.row.ab-bonus
.span6.offset3(style="position: relative; height: 70px;")
.perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") One free collaborator
.perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") Three free collaborators
.perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") Free Dropbox and History
.perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") Free Professional account
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner(style="position: relative; height: 70px;")
.perk(style="left: 10%;", class = refered_user_count >= 1 ? "active" : "") One free collaborator
.perk(style="left: 30%;", class = refered_user_count >= 3 ? "active" : "") Three free collaborators
.perk(style="left: 60%;", class = refered_user_count >= 6 ? "active" : "") Free Dropbox and History
.perk(style="left: 90%;", class = refered_user_count >= 9 ? "active" : "") Free Professional account
.row.ab-bonus
.span6.offset3
- if (refered_user_count == 0)
p.thanks You've not introduced anyone to ShareLaTeX yet. Get sharing!
- else if (refered_user_count == 1)
p.thanks You've introduced <strong>#{refered_user_count}</strong> person to ShareLaTeX. Good job, but can you get some more?
- else
p.thanks You've introduced <strong>#{refered_user_count}</strong> people to ShareLaTeX. Good job!
.row.ab-bonus
.col-md-10.col-md-offset-1.bonus-banner
- if (refered_user_count == 0)
p.thanks You've not introduced anyone to ShareLaTeX yet. Get sharing!
- else if (refered_user_count == 1)
p.thanks You've introduced <strong>#{refered_user_count}</strong> person to ShareLaTeX. Good job, but can you get some more?
- else
p.thanks You've introduced <strong>#{refered_user_count}</strong> people to ShareLaTeX. Good job!
#link-modal.modal.hide
.modal-header
h3 Link to ShareLaTeX
.modal-body
p You can link to ShareLaTeX with the following HTML:
p
textarea(readonly=true)
<a href="#{buildReferalUrl("d")}">Online LaTeX Editor ShareLaTeX</a>
p Thanks!
.modal-footer
button.btn(data-dismiss="modal") Close
include ../general/social-footer
include ../general/small-footer
#link-modal.modal.hide
.modal-header
h3 Link to ShareLaTeX
.modal-body
p You can link to ShareLaTeX with the following HTML:
p
textarea(readonly=true)
<a href="#{buildReferalUrl("d")}">Online LaTeX Editor ShareLaTeX</a>
p Thanks!
.modal-footer
button.btn(data-dismiss="modal") Close
script(type='text/javascript', src='//platform.twitter.com/widgets.js')
script(src='https://connect.facebook.net/en_US/all.js')
script(type='text/javascript')
script(type='text/javascript').
FB.init({appId: "148710621956179", status: true, cookie: true});
function postToFeed() {
@ -121,7 +123,7 @@ block content
FB.ui(obj, callback);
}
script(type="text/javascript")
script(type="text/javascript").
$(function() {
$(".twitter").click(function() {
ga('send', 'event', 'referal-button', 'clicked', "twitter")

View file

@ -7,12 +7,6 @@ mixin printPlan(plan)
tr
td
strong #{plan.name}
td
ul
-for benefit in plan.featureDescription
li #{benefit.text} &nbsp;
if benefit.comingSoon
span.label.label-info coming soon
td
-if (plan.annual)
| $#{plan.price / 100} / year
@ -20,67 +14,71 @@ mixin printPlan(plan)
| $#{plan.price / 100} / month
td
-if (subscription.state == "free-trial")
a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-primary Subscribe to this plan
a(href="/user/subscription/new?planCode=#{plan.planCode}").btn.btn-success Subscribe to this plan
-else if (plan.planCode == subscription.planCode)
button.btn.disabled Your plan
-else
form(action="/user/subscription/update",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
input(type="hidden",name="plan_code",value="#{plan.planCode}")
input(type="submit",value="Change to this plan").btn.btn-primary
input(type="submit",value="Change to this plan").btn.btn-success
mixin printPlans(plans)
-each plan in plans
mixin printPlan(plan)
block content
include ../general/sidebar
.content.content-alt
.container
.row
.col-md-8.col-md-offset-2
.card
.page-header
h1 Your Subscription
case subscription.state
when "free-trial"
p You are currently using a free trial which expires on <strong>#{subscription.expiresAt}</strong>.
p Choose a plan below to subscribe to.
when "active"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
a(href, ng-click="changePlan = true") Change Plan.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>
p.pull-right
.content-with-navigation-sidebar
.box
.row-fluid
.span12
.page-header
h1 Your Subscription
p: case subscription.state
when "free-trial"
p You are currently using a free trial which expires on <strong>#{subscription.expiresAt}</strong>.
p Choose a plan below to subscribe to.
when "active"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>
form(action="/user/subscription/cancel",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
input(type="submit",value="Cancel your subscription").btn.btn-danger#cancelSubscription
p: a(href="/user/subscription/billing-details/edit").btn.btn-primary Update your billing details
when "canceled"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
p Your subscription has been canceled and will terminate on <strong>#{subscription.nextPaymentDueAt}</strong>. No further payments will be taken.
form(action="/user/subscription/reactivate",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
input(type="submit",value="Reactivate your subscription").btn.btn-success
when "expired"
p Your subscription has expired.
a(href="/user/subscription/plans") Create New Subscription
default
p There is a problem with your subscription. Please contact us for more information.
p: form(action="/user/subscription/cancel",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
a(href="/user/subscription/billing-details/edit").btn.btn-info Update your billing details
| &nbsp;
input(type="submit", value="Cancel your subscription").btn.btn-primary#cancelSubscription
when "canceled"
p You are currently subscribed to the <strong>#{subscription.name}</strong> plan.
p Your subscription has been canceled and will terminate on <strong>#{subscription.nextPaymentDueAt}</strong>. No further payments will be taken.
p: form(action="/user/subscription/reactivate",method="post")
input(type="hidden", name="_csrf", value=csrfToken)
input(type="submit",value="Reactivate your subscription").btn.btn-success
when "expired"
p Your subscription has expired.
a(href="/user/subscription/plans") Create New Subscription
default
p There is a problem with your subscription. Please contact us for more information.
-if(subscription.groupPlan)
a(href="/subscription/group").btn.btn-success Manage Group
hr
h2 Change plan
p: table.table
tr
th Name
th Features
th Price
th
mixin printPlans(plans.studentAccounts)
mixin printPlans(plans.individualMonthlyPlans)
mixin printPlans(plans.individualAnnualPlans)
-if(subscription.groupPlan)
a(href="/subscription/group").btn.btn-success Manage Group
div(ng-show="changePlan", ng-cloak)
hr
h2 Change plan
p: table.table
tr
th Name
th Price
th
mixin printPlans(plans.studentAccounts)
mixin printPlans(plans.individualMonthlyPlans)
mixin printPlans(plans.individualAnnualPlans)
script(type="text/javascript")
script(type="text/javascript").
$('#cancelSubscription').on("click", function() {
ga('send', 'event', 'subscription-funnel', 'cancelation')
})

View file

@ -4,11 +4,18 @@ block content
- locals.supressDefaultJs = true
script(data-main=jsPath+'main.js', src=jsPath+'libs/require.js', baseurl=jsPath)
script(src=jsPath+'libs/recurly.min.js')
link(rel='stylesheet', href='/recurly/recurly.css')
#billingDetailsForm.box Loading billing details form...
.content.content-alt
.container
.row
.col-md-6.col-md-offset-3
.card
.page-header
h1.text-centered Update Your Billing Details
#billingDetailsForm Loading billing details form...
script(type="text/javascript")
script(type="text/javascript").
Recurly.config(!{recurlyConfig})
Recurly.buildBillingInfoUpdateForm({
target : "#billingDetailsForm",
@ -17,6 +24,5 @@ block content
accountCode : "#{user.id}"
});
include ../general/small-footer

View file

@ -1,52 +1,84 @@
extends ../layout
block content
.container.box
.row
.span12
.page-header
h2 Group Admin
.content.content-alt
.container
.row
.col-md-10.col-md-offset-1
.card(ng-controller="GroupMembersController")
.page-header
.pull-right(ng-cloak)
small(ng-show="selectedUsers.length == 0") You have added <strong>{{ users.length }}</strong> of <strong>{{ groupSize }}</strong> available members
a.btn.btn-danger(
href,
ng-show="selectedUsers.length > 0"
ng-click="removeMembers()"
) Remove from group
h1 Group Account
div You are allowed up to
strong #{subscription.membersLimit}
| members in this group
.row-spaced-small
ul.list-unstyled.structured-list(
select-all-list,
ng-cloak
)
li.container-fluid
.row
.col-md-5
input.select-all(
select-all,
type="checkbox"
)
span.email EMAIL
.col-md-5
span.name NAME
.col-md-2
span.registered REGISTERED
li.container-fluid(
ng-repeat="user in users | orderBy:'email':true",
ng-controller="GroupMemberListItemController"
)
.row
.col-md-5
input.select-item(
select-individual,
type="checkbox",
ng-model="user.selected"
)
span.email {{ user.email }}
.col-md-5
span.name {{ user.first_name }} {{ user.last_name }}
.col-md-2
span.registered
i.fa.fa-check.text-success(ng-show="!user.holdingAccount")
i.fa.fa-times(ng-show="user.holdingAccount")
li(
ng-if="users.length == 0",
ng-cloak
)
.row
.col-md-12.text-centered
small No members
table.table-striped.table.table-striped
thead
tr
th
input(type="checkbox").select-all
th email
th Name
th Registered
div(ng-if="users.length < groupSize", ng-cloak)
hr
p
.small Add more members
form.form
.row
.col-xs-6
input.form-control(
name="email",
type="text",
placeholder="jane@example.com, joe@example.com",
ng-model="inputs.emails",
on-enter="addMembers()"
)
.col-xs-6
button.btn.btn-primary(ng-click="addMembers()") Add
tbody#userList
-each user in users
tr
td
input(type="checkbox").select-one
td #{user.email}
td #{user.first_name} #{user.last_name}
td #{!user.holdingAccount}
td
input(type="hidden", name="user_id", value=user._id).user_id {{user._id}}
div
button.btn.btn-danger#deleteUsers Delete Selected
div &nbsp;
div
form.well.form-inline#addUserToGroup
div
input(name="_csrf", type="hidden", value=csrfToken)
input(name="email", type="email", placeholder="someone@email.com")#newEmail.email.input-large &nbsp;
button.btn.btn-primary.addUser Add
div &nbsp;
div Add multiple emails seperated with commas or space.
- locals.supressDefaultJs = true
script(data-main='/js/SubscriptionGroupsManager.js', src='/js/libs/require.js')
script(type="text/javascript").
window.users = !{JSON.stringify(users)};
window.groupSize = #{subscription.membersLimit};

View file

@ -4,15 +4,21 @@ block content
- locals.supressDefaultJs = true
script(data-main=jsPath+'main.js', src=jsPath+'libs/require.js', baseurl=jsPath)
script(src=jsPath+'libs/recurly.min.js')
link(rel='stylesheet', href='/recurly/recurly.css')
#subscribeForm.box Loading subscription form...
.content.content-alt
.container
.row
.col-md-6.col-md-offset-3
.card
.page-header
h1.text-centered New Subscription
#subscribeForm Loading subscription form...
script(type="text/javascript")
ga('send', 'event', 'pageview', 'payment_form', "#{plan_code}")
script(type="text/javascript")
script(type="text/javascript").
Recurly.config(!{recurlyConfig})
var recurlySubscriptionFormConfig = !{subscriptionFormOptions}
recurlySubscriptionFormConfig.successHandler = function(){
@ -22,5 +28,3 @@ block content
Recurly.buildSubscriptionForm(recurlySubscriptionFormConfig);
include ../general/small-footer

View file

@ -1,168 +0,0 @@
extends ../layout
mixin liSection(feature)
| #{feature.text}
-if(feature.comingSoon)
span.label.label-info coming soon
-if(feature.beta)
span.label.label-warning beta
mixin plan(plan, cssClass, monthly)
.pricing-table
ul(class=cssClass)
li.pricing-header-row-1
.package-title
h2.no-bold #{plan.name}
li.pricing-header-row-2
.package-price
if plan.price == 0
h1.free Free forever
else
h1.no-bold
| $#{plan.price/100}
if monthly
span.cents /month
else
span.cents /year
- var odd = false
- if(plan.planCode != "personal")
li.pricing-content-row-even
mixin liSection({text:"30 day free trial"})
-each feature in plan.featureDescription
- odd = !odd
- if(odd)
li.pricing-content-row-odd
mixin liSection(feature)
- else
li.pricing-content-row-even
mixin liSection(feature)
- if(plan.planCode == "personal")
li.pricing-content-row-even
mixin liSection({text:""})
li.pricing-footer
- var href = '/user/subscription/new?planCode='+plan.planCode
- planIsPersonal = plan.planCode.indexOf("personal") != -1
- userNotLoggedIn = session && !session.user
-if(planIsPersonal)
- href = "/register"
-else if(userNotLoggedIn)
- href = "/register?redir="+href
a.btn.btn-success(href='#{href}').sign_up_now
| Sign Up Now!
block content
.container
.row
.span12.span-box
.page-header
h1 Choose your plan
blockquote.quote.pull-right
p
| This is one of the most useful resources I have ever found on the Internet.
br
| Fantastic execution and thoughtful attention to detail make this product shine!
small Benjamin Shepherd, Waterloo University
.row
.span12
.offset3
ul.nav.nav-pills.pricing-pills
li.active
a(href="#", data-target=".monthly-pricing", data-toggle="tab") Monthly
li
a(href="#", data-target=".annual-pricing", data-toggle="tab") Annual
li
a(href="#", data-target=".student-pricing", data-toggle="tab") Half price student plans
.row
.span12
.page-header
h2 Individual Plans
.pricing-steelblue.pricing-row
.tab-content
.tab-pane.active.monthly-pricing
.row
.span6.offset3.tagline.freeTrialBlurb
h1 Start your risk free <strong>30 day</strong> trial
.row
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['collaborator_free_trial'], "big", true)
.span4
mixin plan(plans.allPlans['professional_free_trial'], "", true)
.tab-pane.annual-pricing
.row
.span6.offset3.tagline.freeTrialBlurb
h1 Start your risk free <strong>30 day</strong> trial
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['collaborator-annual_free_trial'], "big", false)
.span4
mixin plan(plans.allPlans['prof-ann_free_trial'], "", false)
.tab-pane.student-pricing
.row
.span6.offset3.tagline.freeTrialBlurb
h1 Start your risk free <strong>30 day</strong> trial
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['student_free_trial'], "big", true)
.span4
mixin plan(plans.allPlans['stud-ann_free_trial'], "", false)
.pricing-steelblue.pricing-row
.tab-content
.tab-pane.active.monthly-pricing
.page-header
h2 Group Plans
.row
.span12.tagline
p Improve the workflow of your research group by unlocking ShareLaTeX's premium features for everyone on your team
.row
.span4
mixin plan(plans.groupMonthlyPlans[0], "", true)
.span4
mixin plan(plans.groupMonthlyPlans[1], "big", true)
.span4
mixin plan(plans.groupMonthlyPlans[2], "", true)
.tab-pane.annual-pricing
.page-header
h2 Group Plans
.row
.span12.tagline
p Improve the workflow of your research group by unlocking ShareLaTeX's premium features for everyone on your team
.row
.span4
mixin plan(plans.groupAnnualPlans[0], "", false)
.span4
mixin plan(plans.groupAnnualPlans[1], "big", false)
.span4
mixin plan(plans.groupAnnualPlans[2], "", false)
.tab-pane.student-pricing
.row
.span6.offset3
.alert.alert-info(style="color: #333")
h3 Want to use ShareLaTeX for free?
p Tell your university or department about our
a(href="/university") site licenses
| and use of all our
| features for free as a student or member of staff.
include ../general/small-footer
link(rel='stylesheet', href='/brand/plans.css?fingerprint='+fingerprint('/brand/plans.css'))

View file

@ -1,166 +1,210 @@
extends ../layout
mixin liSection(feature)
| #{feature.text}
-if(feature.comingSoon)
span.label.label-info coming soon
-if(feature.beta)
span.label.label-warning beta
mixin plan(plan, cssClass, monthly)
.pricing-table
ul(class=cssClass)
li.pricing-header-row-1
.package-title
h2.no-bold #{plan.name}
li.pricing-header-row-2
.package-price
if plan.price == 0
h1.free Free forever
else
h1.no-bold
| $#{plan.price/100}
if monthly
span.cents /month
else
span.cents /year
- var odd = true
-each feature in plan.featureDescription
- odd = !odd
- if(odd)
li.pricing-content-row-odd
mixin liSection(feature)
- else
li.pricing-content-row-even
mixin liSection(feature)
li.pricing-footer
- var href = '/user/subscription/new?planCode='+plan.planCode
- planIsPersonal = plan.planCode.indexOf("personal") != -1
- userNotLoggedIn = session && !session.user
-if(planIsPersonal)
- href = "/register"
-else if(userNotLoggedIn)
- href = "/register?redir="+href
a.btn.btn-success(href='#{href}', ga_PlanType=plan.planCode).sign_up_now
| Sign Up Now!
block content
.container
.row
.span12.span-box
.page-header
h1 Choose your plan
blockquote.quote.pull-right
p
| This is one of the most useful resources I have ever found on the Internet.
br
| Fantastic execution and thoughtful attention to detail make this product shine!
small Benjamin Shepherd, Waterloo University
.content-alt
.content.plans(ng-controller="PlansController")
.container
.row
.col-md-12
.page-header.centered.plans-header.text-centered
h1 Start Your 30-Day Free Trial Today
.row
.span12
.offset3
ul.nav.nav-pills.pricing-pills
li.active
a(href="#", data-target=".monthly-pricing", data-toggle="tab") Monthly
li
a(href="#", data-target=".annual-pricing", data-toggle="tab") Annual
li
a(href="#", data-target=".student-pricing", data-toggle="tab") Half price student plans
.col-md-12
p.text-centered ShareLaTeX is the world's easiest to use LaTeX editor. You'll stay up to date with your collaborators, keep track of all changes to your work, and use our LaTeX environment from anywhere in the world.
.row(ng-cloak)
.col-md-12
ul.nav.nav-pills
li(ng-class="{'active': ui.view == 'monthly'}")
a(
href,
ng-click="ui.view = 'monthly'"
) Monthly
li(ng-class="{'active': ui.view == 'annual'}")
a(
href
ng-click="ui.view = 'annual'"
) Annual
li(ng-class="{'active': ui.view == 'student'}")
a(
href,
ng-click="ui.view = 'student'"
) Half Price Student Plans
.row(ng-cloak)
.col-md-12
.card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
.card
.card-header
h2 Personal
.circle Free
ul.list-unstyled
li Only one extra collaborator per<br/> project
li &nbsp;
li
br
a.btn.btn-primary(href="/register") Sign up now!
.card.highlighted
.card-header
h2 Collaborator
.circle
span(ng-if="ui.view == 'monthly'")
| $15
span.small / mo
span(ng-if="ui.view == 'annual'")
| $180
span.small / yr
ul.list-unstyled
li 10 extra collaborators per project
li Full document history
li Sync to Dropbox
li
br
a.btn.btn-primary(
ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '_annual' || ''}}"
) Sign up now!
.card
.card-header
h2 Professional
.circle
span(ng-if="ui.view == 'monthly'")
| $30
span.small / mo
span(ng-if="ui.view == 'annual'")
| $360
span.small / yr
ul.list-unstyled
li Unlimited collaborators per project
li Full document history
li Sync to Dropbox
li
br
a.btn.btn-primary(
ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '_annual' || ''}}"
) Sign up now!
.card-group.text-centered(ng-if="ui.view == 'student'")
.card
.card-header
h2 Personal
.circle Free
ul.list-unstyled
li Only one extra collaborator per<br/> project
li &nbsp;
li
br
a.btn.btn-primary(href="/register") Sign up now!
.card.highlighted
.card-header
h2 Student
.circle
span
| $8
span.small / mo
ul.list-unstyled
li 6 extra collaborators per project
li Full document history
li Sync to Dropbox
li
br
a.btn.btn-primary(
ng-href="#{baseUrl}/user/subscription/new?planCode=student"
) Sign up now!
.card
.card-header
h2 Student (Annual)
.circle
span
| $80
span.small / yr
ul.list-unstyled
li 6 extra collaborators per project
li Full document history
li Sync to Dropbox
li
br
a.btn.btn-primary(
ng-href="#{baseUrl}/user/subscription/new?planCode=student_annual"
) Sign up now!
.row(ng-cloak)
p.text-centered Choose the plan that works for you with our 30-day money-back guarantee. Cancel at any time.
.row
.span12
.page-header
h2 Individual Plans
.pricing-steelblue.pricing-row
.tab-content
.tab-pane.active.monthly-pricing
.row
.span12.tagline
p An online LaTeX editor for collaborating on the <strong>same LaTeX project and editing together in real-time</strong>. Youll never go out of sync with your collaborators again, or lose track of any changes.
.row
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['collaborator'], "big", true)
.span4
mixin plan(plans.allPlans['professional'], "", true)
.tab-pane.annual-pricing
.row
.span12.tagline
p Collaborate on the <strong>same LaTeX project and edit together in real-time</strong>. Youll never go out of sync with your collaborators again, or lose track of any changes.
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['collaborator-annual'], "big", false)
.span4
mixin plan(plans.allPlans['professional-annual'], "", false)
.tab-pane.student-pricing
.row
.span8.offset2.tagline
p Getting started and working with <strong>LaTeX has never been so easy.</strong> Start creating beautiful work now.
.span4
mixin plan(plans.personalAccount, "", true)
.span4
mixin plan(plans.allPlans['student'], "big", true)
.span4
mixin plan(plans.allPlans['student-annual'], "", false)
.row
.span12.ab-guarantee-shown(style="text-align: center;")
h2 30 day money back guarantee, cancel anytime.
.pricing-steelblue.pricing-row
.tab-content
.tab-pane.active.monthly-pricing
.page-header
h2 Group Plans
.row
.span12.tagline
p Improve the workflow of your research group by unlocking ShareLaTeX's premium features for everyone on your team
.row
.span4
mixin plan(plans.groupMonthlyPlans[0], "", true)
.span4
mixin plan(plans.groupMonthlyPlans[1], "big", true)
.span4
mixin plan(plans.groupMonthlyPlans[2], "", true)
.tab-pane.annual-pricing
.page-header
h2 Group Plans
.row
.span12.tagline
p Improve the workflow of your research group by unlocking ShareLaTeX's premium features for everyone on your team
.row
.span4
mixin plan(plans.groupAnnualPlans[0], "", false)
.span4
mixin plan(plans.groupAnnualPlans[1], "big", false)
.span4
mixin plan(plans.groupAnnualPlans[2], "", false)
.tab-pane.student-pricing
.row
.span6.offset3
.alert.alert-info(style="color: #333")
h3 Want to use ShareLaTeX for free?
p Tell your university or department about our
a(href="/university") site licenses
| and use of all our
| features for free as a student or member of staff.
include ../general/small-footer
link(rel='stylesheet', href='/brand/plans.css?fingerprint='+fingerprint('/brand/plans.css'))
.col-md-12
.page-header.plans-header.plans-subheader.text-centered
h2 Enjoy all of these great features
.col-md-4
.card.features.text-centered
i.fa.fa-file-text-o.fa-5x
h4 Unlimited projects
p Create as much as you like.
.col-md-4
.card.features.text-centered
i.fa.fa-clock-o.fa-5x
h4 Full document history
p Never lose a step, we've got your back.
.col-md-4
.card.features.text-centered
i.fa.fa-dropbox.fa-5x
h4 Sync to Dropbox
p Access your projects everywhere.
.row(ng-if="ui.view == 'monthly' || ui.view == 'annual'", ng-cloak)
.col-md-12
.page-header.plans-header.plans-subheader.text-centered
h2 Group Plans
p Improve the workflow of your research group by using ShareLaTeX with everyone on your team
.row(ng-if="ui.view == 'monthly' || ui.view == 'annual'", ng-cloak)
.col-md-12
.card-group.text-centered
.card
.card-header
h2 Group
.circle
span(ng-if="ui.view == 'monthly'")
| $50
span.small / mo
span(ng-if="ui.view == 'annual'")
| $500
span.small / yr
ul.list-unstyled
li 5 group members
li.small All the advantages of the Professional account for each team member
li
br
a.btn.btn-primary(href="#{baseUrl}/user/subscription/new?planCode=group_5_members{{ ui.view == 'annual' && '_annual' || ''}}") Sign up now!
.card.highlighted
.card-header
h2 Research Lab
.circle
span(ng-if="ui.view == 'monthly'")
| $90
span.small / mo
span(ng-if="ui.view == 'annual'")
| $900
span.small / yr
ul.list-unstyled
li 10 group members
li.small All the advantages of the Professional account for each team member
li
br
a.btn.btn-primary(href="#{baseUrl}/user/subscription/new?planCode=group_10_members{{ ui.view == 'annual' && '_annual' || ''}}") Sign up now!
.card
.card-header
h2 Department
.circle
span(ng-if="ui.view == 'monthly'")
| $170
span.small / mo
span(ng-if="ui.view == 'annual'")
| $1700
span.small / yr
ul.list-unstyled
li 20 group members
li.small All the advantages of the Professional account for each team member
li
br
a.btn.btn-primary(href="#{baseUrl}/user/subscription/new?planCode=group_20_members{{ ui.view == 'annual' && '_annual' || ''}}") Sign up now!

View file

@ -1,33 +1,36 @@
extends ../layout
block content
link(href='http://fonts.googleapis.com/css?family=Just+Another+Hand', rel='stylesheet', type='text/css')
.container
.row
div &nbsp;
.span8.offset2.span-box
.page-header
h2 Thanks for subscribing!
.alert.alert-success
p Your card will be charged soon.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>, if you do not want to be charged again
a(href="/user/subscription") click here to cancel.
div
p
- if (subscription.groupPlan == true)
a.btn.btn-success.btn-large(href="/subscription/group") Add your first group members now
div.letter-from-founders
p Thank you for subscribing to the #{subscription.name} plan. It's support from people like yourself that allows ShareLaTeX to continue to grow and improve.
.content.content-alt
.container
.row
.col-md-8.col-md-offset-2
.card
.page-header
h2 Thanks for subscribing!
.alert.alert-success
p Your card will be charged soon.
p The next payment of <strong>#{subscription.price}</strong> will be collected on <strong>#{subscription.nextPaymentDueAt}</strong>.
p If you do not want to be charged again
a(href="/user/subscription") click here to cancel.
p If there is anything you ever need please feel free to contact us directly at
a(href='mailto:support@sharelatex.com') support@sharelatex.com
| - it goes straight to both our inboxes.
p Regards,
br
| Henry and James
.portraits
img(src="/img/about/henry_oswald.jpg")
&nbsp;
img(src="/img/about/james_allen.jpg")
div
a.btn.btn-primary(href="/project") < Back to your projects
p
- if (subscription.groupPlan == true)
a.btn.btn-success.btn-large(href="/subscription/group") Add your first group members now
p.letter-from-founders
p Thank you for subscribing to the #{subscription.name} plan. It's support from people like yourself that allows ShareLaTeX to continue to grow and improve.
p If there is anything you ever need please feel free to contact us directly at
a(href='mailto:support@sharelatex.com') support@sharelatex.com
| . It goes straight to both our inboxes.
p Regards,
br
| Henry and James
.portraits
span.img-circle
img(src="/img/about/henry_oswald.jpg")
&nbsp;
span.img-circle
img(src="/img/about/james_allen.jpg")
p
a.btn.btn-primary(href="/project") &lt; Back to your projects

View file

@ -0,0 +1,67 @@
define [
"base"
], (App) ->
App.directive "selectAllList", () ->
return {
controller: ["$scope", ($scope) ->
# Selecting or deselecting all should apply to all projects
selectAll = () ->
$scope.$broadcast "select-all:select"
deselectAll = () ->
$scope.$broadcast "select-all:deselect"
clearSelectAllState = () ->
$scope.$broadcast "select-all:clear"
return {
clearSelectAllState: clearSelectAllState
selectAll: selectAll
deselectAll: deselectAll
}
]
link: (scope, element, attrs) ->
}
App.directive "selectAll", () ->
return {
require: "^selectAllList"
link: (scope, element, attrs, selectAllListController) ->
scope.$on "select-all:clear", () ->
element.prop("checked", false)
element.change () ->
if element.is(":checked")
selectAllListController.selectAll()
else
selectAllListController.deselectAll()
return true
}
App.directive "selectIndividual", () ->
return {
require: "^selectAllList"
scope: {
ngModel: "="
}
link: (scope, element, attrs, selectAllListController) ->
ignoreChanges = false
scope.$watch "ngModel", (value) ->
if value? and !ignoreChanges
selectAllListController.clearSelectAllState()
scope.$on "select-all:select", () ->
ignoreChanges = true
scope.$apply () ->
scope.ngModel = true
ignoreChanges = false
scope.$on "select-all:deselect", () ->
ignoreChanges = true
scope.$apply () ->
scope.ngModel = false
ignoreChanges = false
}

View file

@ -3,12 +3,15 @@ define [
"main/user-details"
"main/account-settings"
"main/templates"
"main/plans"
"main/group-members"
"directives/asyncForm"
"directives/stopPropagation"
"directives/focus"
"directives/equals"
"directives/fineUpload"
"directives/onEnter"
"directives/selectAll"
"filters/formatDate"
], () ->
angular.bootstrap(document.body, ["SharelatexApp"])

View file

@ -0,0 +1,54 @@
define [
"base"
], (App) ->
App.controller "GroupMembersController", ($scope, queuedHttp) ->
$scope.users = window.users
$scope.groupSize = window.groupSize
$scope.selectedUsers = []
$scope.inputs =
emails: ""
parseEmails = (emailsString)->
regexBySpaceOrComma = /[\s,]+/
emails = emailsString.split(regexBySpaceOrComma)
emails = _.map emails, (email)->
email = email.trim()
emails = _.select emails, (email)->
email.indexOf("@") != -1
return emails
$scope.addMembers = () ->
emails = parseEmails($scope.inputs.emails)
for email in emails
queuedHttp
.post("/subscription/group/user", {
email: email,
_csrf: window.csrfToken
})
.success (data) ->
$scope.users.push data.user if data.user?
$scope.inputs.emails = ""
$scope.removeMembers = () ->
for user in $scope.selectedUsers
do (user) ->
queuedHttp({
method: "DELETE",
url: "/subscription/group/user/#{user._id}"
headers:
"X-Csrf-Token": window.csrfToken
})
.success () ->
index = $scope.users.indexOf(user)
return if index == -1
$scope.users.splice(index, 1)
$scope.selectedUsers = []
$scope.updateSelectedUsers = () ->
$scope.selectedUsers = $scope.users.filter (user) -> user.selected
App.controller "GroupMemberListItemController", ($scope) ->
$scope.$watch "user.selected", (value) ->
if value?
$scope.updateSelectedUsers()

View file

@ -0,0 +1,6 @@
define [
"base"
], (App) ->
App.controller "PlansController", ($scope) ->
$scope.ui =
view: "monthly"

View file

@ -1,71 +1,6 @@
define [
"base"
], (App) ->
App.directive "selectAllList", () ->
return {
controller: ["$scope", ($scope) ->
# Selecting or deselecting all should apply to all projects
selectAll = () ->
$scope.$broadcast "select-all:select"
deselectAll = () ->
$scope.$broadcast "select-all:deselect"
clearSelectAllState = () ->
$scope.$broadcast "select-all:clear"
return {
clearSelectAllState: clearSelectAllState
selectAll: selectAll
deselectAll: deselectAll
}
]
link: (scope, element, attrs) ->
}
App.directive "selectAll", () ->
return {
require: "^selectAllList"
link: (scope, element, attrs, selectAllListController) ->
scope.$on "select-all:clear", () ->
element.prop("checked", false)
element.change () ->
if element.is(":checked")
selectAllListController.selectAll()
else
selectAllListController.deselectAll()
return true
}
App.directive "selectIndividual", () ->
return {
require: "^selectAllList"
scope: {
ngModel: "="
}
link: (scope, element, attrs, selectAllListController) ->
ignoreChanges = false
scope.$watch "ngModel", (value) ->
if value? and !ignoreChanges
selectAllListController.clearSelectAllState()
scope.$on "select-all:select", () ->
ignoreChanges = true
scope.$apply () ->
scope.ngModel = true
ignoreChanges = false
scope.$on "select-all:deselect", () ->
ignoreChanges = true
scope.$apply () ->
scope.ngModel = false
ignoreChanges = false
}
App.factory "queuedHttp", ["$http", "$q", ($http, $q) ->
pendingRequests = []
inflight = false

View file

@ -5,12 +5,8 @@ define [
app.factory "Institutions", ->
new AlgoliaSearch(window.algolia.institutions.app_id, window.algolia.institutions.api_key).initIndex("institutions")
App.controller "UpdateForm", ($scope, $http, Institutions)->
App.controller "UserProfileController", ($scope, $modal, $http)->
$scope.institutions = []
$scope.formVisable = false
$scope.hidePersonalInfoSection = true
$scope.roles = ["Student", "Post-graduate student", "Post-doctoral researcher", "Lecturer", "Professor"]
$http.get("/user/personal_info").success (data)->
$scope.userInfoForm =
first_name: data.first_name || ""
@ -19,23 +15,33 @@ define [
institution: data.institution || ""
_csrf : window.csrfToken
if getPercentComplete() != 100
$scope.percentComplete = getPercentComplete()
$scope.hidePersonalInfoSection = false
$scope.showForm = ->
$scope.formVisable = true
$scope.getPercentComplete = ->
results = _.filter $scope.userInfoForm, (value)-> !value? or value?.length != 0
results.length * 20
$scope.$watch "userInfoForm", (value) ->
if value?
$scope.percentComplete = $scope.getPercentComplete()
, true
$scope.openUserProfileModal = () ->
$modal.open {
templateUrl: "userProfileModalTemplate"
controller: "UserProfileModalController"
scope: $scope
}
App.controller "UserProfileModalController", ($scope, $modalInstance, $http, Institutions) ->
$scope.roles = ["Student", "Post-graduate student", "Post-doctoral researcher", "Lecturer", "Professor"]
$scope.sendUpdate = ->
request = $http.post "/user/settings", $scope.userInfoForm
request.success (data, status)->
request.error (data, status)->
console.log "the request failed"
$scope.percentComplete = getPercentComplete()
getPercentComplete = ->
results = _.filter $scope.userInfoForm, (value)-> !value? or value?.length != 0
results.length * 20
$scope.updateInstitutionsList = (inputVal)->
@ -48,3 +54,5 @@ define [
$scope.institutions = _.map response.hits, (institution)->
"#{institution.name} (#{institution.domain})"
$scope.done = () ->
$modalInstance.close()

View file

@ -1,7 +1,6 @@
.recurly {
display: block;
position: relative;
width: 500px;
}
.recurly .cost,
.recurly .discount {

View file

@ -1,14 +1,8 @@
.team-profile {
clear: both;
.img-container {
border-radius: 50%;
float: left;
height: @line-height-computed * 4;
overflow: hidden;
margin: (@line-height-computed / 2) @line-height-computed @line-height-computed (@line-height-computed / 2);
width: @line-height-computed * 4;
}
img {
margin-top: -10px;
}
}

View file

@ -1,3 +1,15 @@
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
.img-circle {
display: inline-block;
overflow: hidden;
border-radius: 50%;
width: @line-height-computed * 4;
height: @line-height-computed * 4;
img {
margin-top: -10px;
}
}

View file

@ -0,0 +1,130 @@
.bonus {
margin-top: 15px;
.page-header h1 {
text-align: center;
}
h2 {
text-align: center;
font-size: 20px;
line-height: 28px;
margin-bottom: @line-height-computed;
margin-top: 0;
&.direct-link {
margin-top: @line-height-computed;
}
}
.bonus-banner {
.bonus-top {
border-bottom: 1px solid lighten(@blue, 40%);
}
.title {
a {
display: block;
font-size: 18px;
padding: 20px 62px;
background-color: white;
border-bottom: 1px solid lighten(@blue, 40%);
color: @blue;
&:hover {
background-color: lighten(@blue, 45%);
}
}
}
a.twitter {
background-image: url(/img/social/twitter-32.png);
background-repeat: no-repeat;
background-position: 16px center;
}
a.facebook {
background-image: url(/img/social/facebook-32.png);
background-repeat: no-repeat;
background-position: 16px center;
}
a.email {
background-image: url(/img/social/mail-32.png);
background-repeat: no-repeat;
background-position: 16px center;
}
a.google-plus {
background-image: url(//www.gstatic.com/images/icons/gplus-32.png);
background-repeat: no-repeat;
background-position: 16px center;
}
a.link {
background-image: url(/img/social/link-32.png);
background-repeat: no-repeat;
background-position: 16px center;
}
h2.direct-link {
}
}
p.thanks {
font-size: 18px;
line-height: 28px;
margin-top: 10px;
text-align: center;
}
.number {
position: absolute;
margin-left: -13px;
width: 26px;
padding: 3px 0;
text-align: center;
background-color: #ddd;
&.active {
background-color: @blue;
color: white;
}
border-radius: 3px;
}
.progress {
margin-top: @line-height-computed / 2;
margin-left: -15px;
margin-right: -15px;
height: 30px;
}
.perk {
position: absolute;
background-color: #ddd;
border-radius: 5px;
text-align: center;
padding: 5px 5px;
width: 100px;
margin-left: -50px;
font-size: 14px;
&:before {
border-bottom: 8px solid #ddd;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
content: '';
position: absolute;
left: 42px;
top: -8px;
}
&.active {
color: white;
background-color: @blue;
&:before {
border-bottom: 8px solid @blue;
}
}
}
}
#link-modal {
.modal-body{
text-align: center;
}
textarea {
width: 95%;
margin-bottom: 0;
}
}

View file

@ -0,0 +1,124 @@
.plans {
p {
color: @gray-dark;
margin-bottom: @line-height-computed;
}
.plans-header{
h1, h2, p {
text-shadow: 0 -1px 1px white;
}
h1, h2 {
color: @red;
}
p {
margin-bottom: 0;
}
}
.plans-subheader {
margin-bottom: @line-height-computed;
}
.card.features {
margin-top: @line-height-computed;
i {
color: @red;
}
p {
margin: 0;
}
}
.card {
background-color: white;
border-radius: 3px;
-webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.1);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
margin: @line-height-computed 0;
padding: @line-height-computed;
.card-header {
border-bottom: 1px solid @gray-lighter;
padding-bottom: @line-height-computed;
margin-bottom: @line-height-computed;
h2 {
margin: 0;
}
}
.circle {
font-size: 1.5rem;
font-weight: 700;
padding: 38px 18px;
margin: 0 auto @line-height-computed;
text-shadow: 0 -1px 1px darken(@link-color, 10%);
width: 120px;
height: 120px;
small {
margin-top: @line-height-computed / 2;
}
}
&.first {
margin-top: 0;
}
&.card-thin {
padding: @line-height-computed / 4;
}
}
.card-group {
margin: @line-height-computed 0;
.card {
border-radius: 0;
display: inline-block;
margin: 0;
&:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
&:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
width: 300px;
}
.highlighted {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
margin-top: -@line-height-computed * 2;
padding-top: @line-height-computed * 2;
padding-bottom: @line-height-computed * 2;
position: relative;
z-index: 10;
}
}
> .card-group > .card {
padding-left: 1rem;
padding-right: 1rem;
}
.circle {
border-radius: 50%;
background-color: @red;
color: white;
padding: @line-height-computed / 2;
margin-bottom: @line-height-computed;
white-space: nowrap;
span.small {
color: rgba(255, 255, 255, 0.75);
font-size: @font-size-base * .8;
}
}
ul.nav-pills {
text-align: center;
margin-bottom: @line-height-computed;
li {
float: none;
display: inline-block;
a {
background-color: darken(@gray-lightest, 5%);
}
&.active {
a {
background-color: @link-color;
}
}
}
> li + li {
margin-left: @line-height-computed / 2;
}
}
}

View file

@ -1,16 +1,31 @@
.project-header {
.btn-group > .btn {
padding-left: @line-height-base / 2;
padding-right: @line-height-base / 2;
}
.btn-group > .btn {
padding-left: @line-height-base / 2;
padding-right: @line-height-base / 2;
}
}
.project-search {
margin: @line-height-base 0;
margin: @line-height-base 0;
}
.project-tools {
display: inline;
display: inline;
}
.first-project {
width: 127px;
text-align: center;
}
.user-profile {
.progress {
height: @line-height-computed / 2;
margin-bottom: @line-height-computed / 4;
}
p {
margin-bottom: @line-height-computed / 4;
}
}
ul.folders-menu {
@ -25,7 +40,7 @@ ul.folders-menu {
color: #333;
padding: (@line-height-computed / 4);
}
}
}
li.active {
//border-right: 4px solid @red;
a {
@ -53,16 +68,16 @@ form.project-search {
}
}
ul.project-list {
ul.structured-list {
list-style-type: none;
margin: 0;
overflow: hidden;
overflow-y: scroll;
overflow-y: auto;
li {
border-bottom: 1px solid @gray-lightest;
padding: (@line-height-computed / 4) 0;
&:first-child {
.last-modified, .owner {
.header {
font-size: 1rem;
}
}
@ -86,6 +101,11 @@ ul.project-list {
.select-item, .select-all {
margin-left: @line-height-computed / 4;
}
}
}
ul.project-list {
li {
.last-modified, .owner {
font-size: .8rem;
}
@ -109,3 +129,54 @@ ul.project-list {
}
}
}
#institution_auto_complete {
ul>li{
list-style:none;
}
.autocomplete {
width: 100%;
position: relative;
}
.autocomplete ul {
position: absolute;
top: 100%;
left: 0;
z-index: @zindex-dropdown;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0; // override default ul
list-style: none;
font-size: @font-size-base;
background-color: @dropdown-bg;
border: 1px solid @dropdown-fallback-border; // IE8 fallback
border: 1px solid @dropdown-border;
border-radius: @border-radius-base;
.box-shadow(0 6px 12px rgba(0,0,0,.175));
background-clip: padding-box;
// Links within the dropdown menu
> li {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: @line-height-base;
color: @dropdown-link-color;
white-space: nowrap; // prevent links from randomly breaking onto new lines
}
> li.active {
text-decoration: none;
color: @dropdown-link-hover-color;
background-color: @dropdown-link-hover-bg;
}
}
.autocomplete .highlight {
font-weight: 700;
}
}

View file

@ -0,0 +1,781 @@
.recurly {
display: block;
position: relative;
box-sizing: content-box;
* {
box-sizing: content-box;
}
.due_now {
display: none;
}
}
.recurly .cost,
.recurly .discount {
font-size: 16px;
text-align: right;
}
.recurly .subscription {
border-radius: 9px 9px 0 0;
text-shadow: 0 1px 0 #fff;
padding-top: 20px;
overflow: hidden;
}
.recurly .plan {
color: #333;
overflow: hidden;
position: relative;
zoom: 1;
font-family: @font-family-serif;
}
.recurly .plan .name {
float: left;
font-size: 32px;
min-width: 200px;
padding-left: 20px;
padding-right: 40px;
}
.recurly .plan .quantity.field {
clear: none;
width: 60px;
margin: 4px 0;
}
.recurly .plan .quantity.field input[type=text] {
width: 48px;
}
.recurly .plan .quantity.field:before {
content: "\d7";
height: 48px;
line-height: 30px;
position: absolute;
right: 100%;
width: 40px;
font-size: 20px;
text-align: center;
vertical-align: middle;
z-index: 1337;
color: #666;
}
.recurly .plan .recurring_cost {
float: right;
text-align: right;
padding-right: 20px;
}
.recurly .plan .recurring_cost .cost {
font-size: 32px;
}
.recurly .plan .recurring_cost .interval {
font-size: 12px;
padding-bottom: 20px;
}
.recurly .free_trial {
clear: left;
float: left;
font-size: 13px;
height: 22px;
margin: 0;
position: absolute;
top: 35px;
left: 20px;
font-style: italic;
}
.recurly .setup_fee {
clear: both;
background: url("/recurly/images/dash.png") repeat-x 1px top;
overflow: hidden;
padding-top: 20px;
}
.recurly .setup_fee .title {
float: left;
padding-left: 20px;
font-weight: bold;
font-size: 16px;
}
.recurly .setup_fee .cost {
float: right;
padding-right: 20px;
}
.recurly .vat {
height: 24px;
padding: 20px 20px;
display: none;
background: url("/recurly/images/dash.png") repeat-x 1px top;
}
.recurly .vat.applicable {
display: block;
}
.recurly .vat .title {
font-size: 16px;
font-weight: normal;
float: left;
}
.recurly .vat .cost {
float: right;
font-size: 18px;
}
.recurly .add_ons {
clear: both;
}
.recurly .add_ons.any {
margin: 20px 10px;
}
.recurly .add_ons .add_on {
background: #ecedee;
background: -webkit-linear-gradient(top, #ecedee, #e5e6e7);
background: -moz-linear-gradient(top, #ecedee, #e5e6e7);
background: -o-linear-gradient(top, #ecedee, #e5e6e7);
background: linear-gradient(top, #ecedee, #e5e6e7);
margin: 0;
height: 43px;
line-height: 42px;
vertical-align: middle;
position: relative;
clear: both;
overflow: hidden;
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
text-shadow: 0 1px 0 #fff;
color: #999;
font-weight: 300;
font-size: 16px;
zoom: 1;
cursor: default;
}
.recurly .add_ons .add_on.first {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.recurly .add_ons .add_on.last {
border-bottom: 1px solid #ccc;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.recurly .add_ons .add_on .name {
font-size: inherit;
font-weight: inherit;
font-style: italic;
color: inherit;
width: 200px;
margin-left: 9px;
margin-right: 20px;
position: absolute;
left: 0;
top: 0;
}
.recurly .add_ons .add_on .quantity.field {
position: absolute;
top: 4px;
left: 249px;
width: 60px;
display: none;
}
.recurly .add_ons .add_on .quantity.field input[type=text] {
width: 48px;
}
.recurly .add_ons .add_on .quantity.field:before {
content: "\d7";
height: 48px;
line-height: 30px;
position: absolute;
right: 100%;
width: 40px;
font-size: 20px;
text-align: center;
vertical-align: middle;
z-index: 1337;
color: #666;
}
.recurly .add_ons .add_on .cost {
font-size: inherit;
line-height: inherit;
vertical-align: middle;
position: absolute;
right: 10px;
}
.recurly .add_ons .add_on:hover {
background: -webkit-linear-gradient(top, #f0f0f0 0%, #dfdfdf 50%, #d5d5d5 50%, #e0e0e0 100%);
background: -moz-linear-gradient(top, #f0f0f0 0%, #dfdfdf 50%, #d5d5d5 50%, #e0e0e0 100%);
background: -o-linear-gradient(top, #f0f0f0 0%, #dfdfdf 50%, #d5d5d5 50%, #e0e0e0 100%);
background: linear-gradient(top, #f0f0f0 0%, #dfdfdf 50%, #d5d5d5 50%, #e0e0e0 100%);
box-shadow: inset 0 1px 0 #fff;
text-shadow: none;
color: #111;
}
.recurly .add_ons .add_on:active,
.recurly .add_ons .add_on.selected {
color: #111;
background: -webkit-linear-gradient(top, #f0f0f0, #fff);
background: -moz-linear-gradient(top, #f0f0f0, #fff);
background: -o-linear-gradient(top, #f0f0f0, #fff);
background: linear-gradient(top, #f0f0f0, #fff);
width: auto;
box-shadow: inset 0 1px 4px 0 rgba(0,0,0,0.07);
text-shadow: none;
}
.recurly .add_ons .add_on.selected {
background: #fff url("/recurly/images/check.png") no-repeat 10px center;
}
.recurly .add_ons .add_on.selected .name {
padding-left: 24px;
}
.recurly .add_ons .add_on.selected:hover {
background: #fcf5f0 url("/recurly/images/uncheck.png") no-repeat 10px center;
}
.recurly .add_ons .add_on.selected .quantity {
display: block;
}
.recurly .coupon {
clear: both;
overflow: hidden;
height: 34px;
color: #333;
padding: 20px 20px;
position: relative;
background: url("/recurly/images/dash.png") repeat-x 1px top;
}
.recurly .coupon .check {
width: 26px;
height: 26px;
float: left;
border-radius: 15px 15px 15px 15px;
background: #70ccf8;
border: 1px solid #0090c9;
margin: 3px 0 1px 10px;
box-shadow: inset 0 1px 0 0 rgba(255,255,255,0.35), 0 1px 1px 0 rgba(0,0,0,0.10);
background: #43bef9 url("/recurly/images/coupon_check.png") no-repeat center center;
background: url("/recurly/images/coupon_check.png") no-repeat center center, -webkit-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -moz-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -o-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
}
.recurly .coupon .check:hover {
background: url("/recurly/images/coupon_check.png") no-repeat center center, -webkit-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -moz-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -o-linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
background: url("/recurly/images/coupon_check.png") no-repeat center center linear-gradient(top, #71CDFA 0%, #43BEF9 50%, #00B1F6 50%, #71CEFB 100%);
box-shadow: inset 0 1px 0 0 rgba(255,255,255,0.75), 0 1px 1px 0 rgba(0,0,0,0.10);
}
.recurly .coupon .check:active {
background: url("/recurly/images/coupon_check.png") no-repeat center center, -webkit-linear-gradient(top, #f0f0f0, #fff);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -moz-linear-gradient(top, #f0f0f0, #fff);
background: url("/recurly/images/coupon_check.png") no-repeat center center, -o-linear-gradient(top, #f0f0f0, #fff);
background: url("/recurly/images/coupon_check.png") no-repeat center center linear-gradient(top, #f0f0f0, #fff);
box-shadow: inset 0 3px 3px 0 rgba(0,0,0,0.03);
border: 1px solid #999;
}
.recurly .coupon.checking .check {
background: #f0f0f0 url("/recurly/images/coupon_checking.gif") no-repeat center center;
box-shadow: inset 0 3px 3px 0 rgba(0,0,0,0.03);
border: 1px solid #999;
}
.recurly .coupon.invalid .coupon_code {
border-color: #a55;
background: #fee;
color: #311;
}
.recurly .coupon .coupon_code .error {
left: 300px;
}
.recurly .coupon .description {
float: left;
margin-left: 20px;
height: 34px;
line-height: 34px;
vertical-align: middle;
font-size: 14.4px;
}
.recurly .coupon .discount {
float: right;
height: 34px;
line-height: 34px;
vertical-align: middle;
}
.recurly .error {
padding: 5px;
line-height: 22px;
vertical-align: middle;
color: #000;
text-shadow: 0 1px 0 #fec;
background: #ffc;
border: 1px solid #ba1;
box-shadow: 3px 5px 5px 0 rgba(0,0,0,0.10);
border-radius: 5px;
font-size: 13px;
}
.recurly .server_errors {
color: #fff;
text-shadow: 0 1px 0 #000;
margin: 0 20px;
opacity: 0;
}
.recurly .server_errors .error {
padding-left: 26px;
background: rgba(240,250,0,0.50) url("/recurly/images/error.png") no-repeat 5px 9px;
}
.recurly .server_errors.any {
opacity: 1;
-webkit-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
margin: 20px 20px;
margin-bottom: 0;
}
.recurly .contact_info,
.recurly .billing_info,
.recurly .accept_tos {
position: relative;
padding: 20px 20px;
overflow: hidden;
zoom: 1;
}
.recurly .title {
font-size: 16px;
height: 20px;
font-weight: bold;
padding-bottom: 20px;
color: #404041;
text-shadow: 0 1px 0 #fff;
float: left;
}
.recurly .credit_card,
.recurly .paypal {
clear: both;
}
.recurly .payment_method {
margin-bottom: 20px;
width: 300px;
}
.recurly .payment_method .payment_option {
float: right;
}
.recurly .payment_method .payment_option input[type=radio] {
margin-right: 10px;
display: none;
}
.recurly .payment_method.multiple {
height: 34px;
clear: both;
}
.recurly .payment_method.multiple input[type=radio] {
display: block;
float: left;
height: 29px;
}
.recurly .payment_method.multiple .card_option {
float: left;
}
.recurly .payment_method.multiple .paypal_option {
float: right;
}
.recurly .payment_method.multiple .logo,
.recurly .payment_method.multiple .accepted_cards {
opacity: 0.5;
}
.recurly .payment_method.multiple .payment_option:hover .logo,
.recurly .payment_method.multiple .payment_option.selected .logo,
.recurly .payment_method.multiple .payment_option:hover .accepted_cards,
.recurly .payment_method.multiple .payment_option.selected .accepted_cards {
cursor: pointer;
opacity: 1;
}
.recurly .payment_method .payment_option {
line-height: 32px;
display: block;
height: 32px;
line-height: 34px;
}
.recurly .payment_method .payment_option .title {
margin: 0;
font-size: 12px;
}
.recurly .payment_method .payment_option .icon {
float: left;
width: 24px;
height: 34px;
margin: 0 5px;
}
.recurly .payment_method .payment_option.card_option {
border-radius: 5px 0 0 5px;
border-right: none;
}
.recurly .payment_method .payment_option.card_option .icon {
width: 42px;
background: url("/recurly/images/credit_cards/generic.png") no-repeat 0 center;
}
.recurly .payment_method .payment_option.paypal_option {
border-radius: 0 5px 5px 0;
float: right;
}
.recurly .payment_method .payment_option.paypal_option .logo {
height: 24px;
width: 90px;
display: inline-block;
vertical-align: middle;
background: url("/recurly/images/paypal_logo.png") no-repeat 0 center;
}
.recurly .paypal_message {
width: 300px;
font-style: italic;
margin-bottom: 10px;
}
.recurly .contact_info {
background: url("/recurly/images/dash.png") repeat-x 1px bottom;
}
.recurly .accept_tos {
background: url("/recurly/images/dash.png") repeat-x 1px top;
overflow: visible;
}
.recurly .accept_tos input[type=checkbox] {
display: inline;
line-height: 34px;
vertical-align: middle;
}
.recurly .accept_tos label {
margin: 0 0 0 5px;
display: inline;
line-height: 34px;
vertical-align: middle;
}
.recurly .accept_tos .field .error {
display: block;
position: static;
}
.recurly .field {
display: inline;
float: left;
clear: left;
width: 300px;
height: 34px;
margin-bottom: 20px;
position: relative;
}
.recurly .field input[type=text] {
width: 288px;
}
.recurly .field.company_name {
margin-bottom: 0;
}
.recurly .field .error {
min-width: 128px;
white-space: nowrap;
position: absolute;
top: 0;
left: 100%;
margin-left: 20px;
z-index: 1337;
}
.recurly .field .placeholder {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding-left: 9px;
font-size: 16px;
font-weight: normal;
line-height: 34px;
vertical-align: middle;
color: #999;
cursor: text;
overflow: hidden;
white-space: nowrap;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;
font-weight: 300;
}
.recurly .field.focus .placeholder {
color: #ccc;
}
.recurly .field.invalid .placeholder {
color: #a77;
}
.recurly .field.coupon_code {
width: 140px;
}
.recurly .field.coupon_code input[type=text] {
width: 128px;
}
.recurly .field.first_name {
clear: left;
width: 140px;
}
.recurly .field.first_name input[type=text] {
width: 128px;
}
.recurly .field.first_name .error {
left: 300px;
}
.recurly .field.last_name {
width: 140px;
margin-left: 20px;
margin-left: 20px;
clear: none;
clear: none;
}
.recurly .field.last_name input[type=text] {
width: 128px;
}
.recurly .field.card_number {
width: 220px;
}
.recurly .field.card_number input[type=text] {
width: 208px;
}
.recurly .field.card_number .error {
left: 300px;
}
.recurly .field.cvv {
width: 60px;
margin-left: 20px;
margin-left: 20px;
clear: none;
clear: none;
}
.recurly .field.cvv input[type=text] {
width: 48px;
}
.recurly .field.expires {
width: 300px;
}
.recurly .field.expires input[type=text] {
width: 288px;
}
.recurly .field.expires .title {
float: left;
font-size: 13px;
line-height: 24px;
vertical-align: middle;
width: 59px;
}
.recurly .field.expires .month {
float: left;
width: 120px;
margin-left: 0;
}
.recurly .field.expires .month input[type=text] {
width: 108px;
}
.recurly .field.expires .year {
float: left;
margin-left: 1px;
width: 60px;
}
.recurly .field.expires .year input[type=text] {
width: 48px;
}
.recurly .field.state {
width: 180px;
}
.recurly .field.state input[type=text] {
width: 168px;
}
.recurly .field.state .error {
left: 300px;
}
.recurly .field.zip {
width: 100px;
margin-left: 20px;
margin-left: 20px;
clear: none;
clear: none;
}
.recurly .field.zip input[type=text] {
width: 88px;
}
.recurly .field.vat_number {
width: 140px;
display: none;
}
.recurly .field.vat_number input[type=text] {
width: 128px;
}
.recurly .field.vat_number.applicable {
display: block;
}
.recurly .only_zipstreet .zip.field,
.recurly .only_zip .zip.field {
margin-left: 0;
clear: left;
}
.recurly .accepted_cards {
display: inline-block;
height: 34px;
overflow: hidden;
}
.recurly .card {
background-position: right top;
background-repeat: no-repeat;
text-indent: -3000px;
width: 32px;
height: 32px;
margin: 0;
padding: 0;
display: inline-block;
}
.recurly .card.mastercard {
background-image: url("/recurly/images/credit_cards/mastercard.png");
}
.recurly .card.american_express {
background-image: url("/recurly/images/credit_cards/american_express.png");
}
.recurly .card.visa {
background-image: url("/recurly/images/credit_cards/visa.png");
}
.recurly .card.discover {
background-image: url("/recurly/images/credit_cards/discover.png");
}
.recurly .card.jcb {
background-image: url("/recurly/images/credit_cards/jcb.png");
}
.recurly .card.laser {
background-image: url("/recurly/images/credit_cards/laser.png");
}
.recurly .card.diners_club {
background-image: url("/recurly/images/credit_cards/diners_club.png");
}
.recurly .card.maestro {
background-image: url("/recurly/images/credit_cards/maestro.png");
}
.recurly .card.no_match {
opacity: 0.5;
}
.recurly input[type=text],
.recurly select {
vertical-align: middle;
color: #000;
}
.recurly input[type=text].invalid,
.recurly select.invalid {
border-color: #a55;
background: #fee;
color: #311;
}
.recurly input[type=text] {
display: block;
background: #fff;
border: 1px solid #a0a0a5;
box-shadow: inset 0 2px 3px rgba(0,0,0,0.10);
font-size: 16px;
font-family: inherit;
padding: 5px;
height: 22px;
}
.recurly input[type=text][disabled] {
background: #eee;
}
.recurly input[type=checkbox] {
color: #f00;
}
.recurly select {
color: inherit;
font-family: inherit;
width: 100%;
}
.recurly select > option {
color: inherit;
}
.recurly .due_now {
background: url("/recurly/images/due_now.png") no-repeat top left;
clear: both;
color: #2a3a3c;
height: 70px;
line-height: 67px;
vertical-align: middle;
padding: 0 25px;
width: 460px;
position: relative;
left: -5px;
text-shadow: 0 1px 0 rgba(255,255,255,0.50);
}
.recurly .due_now .title {
float: left;
font-size: 29px;
position: relative;
}
.recurly .due_now .cost {
color: #fff;
float: right;
font-size: 33px;
font-weight: bold;
letter-spacing: 1px;
margin: 0;
position: relative;
text-shadow: 0px 1px 1px rgba(0,0,0,0.90);
}
.recurly .footer {
border-radius: 0px 0px 9px 9px;
margin: 0px;
padding: 20px;
}
.recurly.submitting .footer {
background: url("/recurly/images/submitting.gif") no-repeat 180px 28px;
}
.recurly button.submit {
.btn;
.btn-lg;
.btn-primary;
}
// .recurly button.submit:hover {
// color: #451;
// }
// .recurly button.submit:active {
// top: 2px;
// color: #302106;
// text-shadow: rgba(255,255,255,0.57) 0 -1px 0;
// outline: none;
// background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ce7b00), to(#fecd00));
// background: -moz-linear-gradient(top, #ce7b00, #fecd00);
// box-shadow: rgba(255,255,255,0.69) 0px -1px 0px inset, rgba(0,0,0,0.26) 0px 2px 3px;
// }
// .recurly button.submit[disabled] {
// position: relative;
// height: 46px;
// max-width: 600px;
// padding: 0 10px;
// font-weight: 700;
// color: #555;
// text-shadow: rgba(255,255,255,0.57) 0 1px 0;
// text-align: center;
// opacity: 0.75;
// border: 1px solid #767674;
// background: #e7a500;
// -moz-border-radius: 10px;
// -webkit-border-radius: 10px;
// border-radius: 10px;
// -webkit-user-select: none;
// -moz-user-select: -moz-none;
// outline: none;
// background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#dbd9d2), to(#999));
// background: -moz-linear-gradient(top, #dbd9d2, #999);
// -webkit-background-clip: padding-box;
// -webkit-box-shadow: rgba(255,255,255,0.69) 0px 1px 0px inset, rgba(0,0,0,0.26) 0px 2px 3px;
// box-shadow: rgba(255,255,255,0.70) 0px 1px 0px inset, rgba(0,0,0,0.27) 0px 2px 3px;
// }
.iefail {
background: #666;
padding: 10px;
position: absolute;
top: -1%;
left: -1%;
height: 102%;
width: 102%;
z-index: 9999;
}
.iefail .chromeframe {
background: #fff;
border: 1px solid #ccc;
padding: 10px;
}
.iefail .chromeframe p {
text-align: center;
}
.iefail .chromeframe p.blast {
font-size: 1.3em;
font-weight: bold;
}
.iefail .chromeframe p a {
color: #4183c4;
text-transform: capitalize;
}

View file

@ -16,7 +16,7 @@
@import "components/forms.less";
@import "components/buttons.less";
@import "components/card.less";
@import "components/code.less";
//@import "components/code.less";
@import "components/component-animations.less";
//@import "components/glyphicons.less";
@import "components/dropdowns.less";
@ -25,19 +25,19 @@
@import "components/navs.less";
@import "components/navbar.less";
@import "components/footer.less";
@import "components/breadcrumbs.less";
@import "components/pagination.less";
@import "components/pager.less";
//@import "components/breadcrumbs.less";
//@import "components/pagination.less";
//@import "components/pager.less";
@import "components/labels.less";
@import "components/badges.less";
@import "components/jumbotron.less";
@import "components/thumbnails.less";
//@import "components/badges.less";
//@import "components/jumbotron.less";
//@import "components/thumbnails.less";
@import "components/alerts.less";
@import "components/progress-bars.less";
@import "components/media.less";
@import "components/list-group.less";
@import "components/panels.less";
@import "components/wells.less";
// @import "components/media.less";
// @import "components/list-group.less";
// @import "components/panels.less";
// @import "components/wells.less";
@import "components/close.less";
@import "components/fineupload.less";
@ -58,3 +58,6 @@
@import "app/project-list.less";
@import "app/editor.less";
@import "app/homepage.less";
@import "app/plans.less";
@import "app/recurly.less";
@import "app/bonus.less";