diff --git a/services/web/app/views/layout-website-redesign-bootstrap-5.pug b/services/web/app/views/layout-website-redesign-bootstrap-5.pug deleted file mode 100644 index e6dc3a8827..0000000000 --- a/services/web/app/views/layout-website-redesign-bootstrap-5.pug +++ /dev/null @@ -1,28 +0,0 @@ -extends ./layout-base - -include ./_mixins/formMessages -include ./_mixins/bootstrap_js - -block entrypointVar - - entrypoint = 'marketing' - - isWebsiteRedesign = true - -block body - if (typeof(suppressNavbar) == "undefined") - include layout/navbar-marketing-bootstrap-5 - - block content - - if (typeof(suppressFooter) == "undefined") - if showThinFooter - include layout/thin-footer-bootstrap-5 - else - include layout/fat-footer-website-redesign - - if (typeof(suppressCookieBanner) == 'undefined') - include _cookie_banner - - != moduleIncludes("contactModal-marketing-bootstrap-5", locals) - -block prepend foot-scripts - +bootstrap-js(5) diff --git a/services/web/app/views/layout-website-redesign.pug b/services/web/app/views/layout-website-redesign.pug index 37ba2f9f32..d04d4b1202 100644 --- a/services/web/app/views/layout-website-redesign.pug +++ b/services/web/app/views/layout-website-redesign.pug @@ -8,20 +8,32 @@ block entrypointVar block body if (typeof(suppressNavbar) == "undefined") - include layout/navbar-website-redesign + if bootstrapVersion === 5 + include layout/navbar-marketing-bootstrap-5 + else + include layout/navbar-website-redesign block content + //- bootstrapVersion needed here, because plans.pug uses both BS version + //- If the `plans-page-bs5` split test has been completed, remove bootstrapVersion logic if (typeof(suppressFooter) == "undefined") if showThinFooter - include layout/thin-footer + if bootstrapVersion === 5 + include layout/thin-footer-bootstrap-5 + else + include layout/thin-footer else include layout/fat-footer-website-redesign if (typeof(suppressCookieBanner) == 'undefined') include _cookie_banner - != moduleIncludes("contactModal-marketing", locals) + block contactModal + if bootstrapVersion === 5 + != moduleIncludes("contactModal-marketing-bootstrap-5", locals) + else + != moduleIncludes("contactModal-marketing", locals) block prepend foot-scripts +bootstrap-js(bootstrapVersion) diff --git a/services/web/app/views/subscriptions/plans/_faq_new.pug b/services/web/app/views/subscriptions/plans/_faq_new.pug index baefb6ed3f..c91fa8471f 100644 --- a/services/web/app/views/subscriptions/plans/_faq_new.pug +++ b/services/web/app/views/subscriptions/plans/_faq_new.pug @@ -81,6 +81,10 @@ include ../../_mixins/eyebrow .row .col-xs-12.plans-faq-support span #{translate('still_have_questions')} - button(data-ol-open-contact-form-modal="general") + button( + data-ol-open-contact-form-modal="general" + data-bs-toggle=bootstrapVersion === 5 ? "modal" : undefined + data-bs-target=bootstrapVersion === 5 ? "#contactUsModal" : undefined + ) span(style="margin-right: 4px") #{translate('contact_support')} i.icon-md.material-symbols.material-symbols-rounded.material-symbols-arrow-right(aria-hidden="true") arrow_right_alt diff --git a/services/web/app/views/user/passwordReset-bs5.pug b/services/web/app/views/user/passwordReset-bs5.pug index 7637a91062..08e0a71b9d 100644 --- a/services/web/app/views/user/passwordReset-bs5.pug +++ b/services/web/app/views/user/passwordReset-bs5.pug @@ -1,10 +1,11 @@ -extends ../layout-website-redesign-bootstrap-5 +extends ../layout-website-redesign include ../_mixins/recaptcha include ../_mixins/notification block vars - var suppressNavbar = true - var suppressFooter = true + - isWebsiteRedesign = true block content - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) diff --git a/services/web/app/views/user/primaryEmailCheck-bs5.pug b/services/web/app/views/user/primaryEmailCheck-bs5.pug index 0828c06e4b..b25136927a 100644 --- a/services/web/app/views/user/primaryEmailCheck-bs5.pug +++ b/services/web/app/views/user/primaryEmailCheck-bs5.pug @@ -1,4 +1,8 @@ -extends ../layout-website-redesign-bootstrap-5 +extends ../layout-website-redesign + +block vars + - bootstrap5PageStatus = 'enabled' + - isWebsiteRedesign = true block content main#main-content diff --git a/services/web/app/views/user/reconfirm-bs5.pug b/services/web/app/views/user/reconfirm-bs5.pug index 8d9d13955f..fce9a44295 100644 --- a/services/web/app/views/user/reconfirm-bs5.pug +++ b/services/web/app/views/user/reconfirm-bs5.pug @@ -1,69 +1,72 @@ -extends ../layout-website-redesign-bootstrap-5 +extends ../layout-website-redesign include ../_mixins/recaptcha +block vars + - isWebsiteRedesign = true + block content - - var email = reconfirm_email ? reconfirm_email : "" - - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) + - var email = reconfirm_email ? reconfirm_email : "" + - var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset) - if showCaptcha - script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit") - div( - id="recaptcha" - class="g-recaptcha" - data-sitekey=settings.recaptcha.siteKey - data-size="invisible" - data-badge="inline" - ) + if showCaptcha + script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit") + div( + id="recaptcha" + class="g-recaptcha" + data-sitekey=settings.recaptcha.siteKey + data-size="invisible" + data-badge="inline" + ) - main#main-content(data-ol-captcha-retry-trigger-area="") - .container.auth-aux-container(style="max-width: 420px;") - form( - data-ol-async-form - name="reconfirmAccountForm" - action="/user/reconfirm" - method="POST" - aria-label=translate('request_reconfirmation_email') - captcha=(showCaptcha ? '' : false) - captcha-action-name=(showCaptcha ? "passwordReset" : false) - ) - h1.h5.mb-3 #{translate("reconfirm_account")} - p #{translate('reconfirm_explained')} - | - a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} - | . - - div(data-ol-not-sent) - +formMessagesNewStyle() + main#main-content(data-ol-captcha-retry-trigger-area="") + .container.auth-aux-container(style="max-width: 420px;") + form( + data-ol-async-form + name="reconfirmAccountForm" + action="/user/reconfirm" + method="POST" + aria-label=translate('request_reconfirmation_email') + captcha=(showCaptcha ? '' : false) + captcha-action-name=(showCaptcha ? "passwordReset" : false) + ) + h1.h5.mb-3 #{translate("reconfirm_account")} + p #{translate('reconfirm_explained')} + | + a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} + | . + + div(data-ol-not-sent) + +formMessagesNewStyle() - input(type="hidden" name="_csrf" value=csrfToken) - .form-group.mb-3 - label.form-label(for='email') #{translate("please_enter_email")} - input.form-control( - aria-label="email" - type='email' - name='email' - placeholder='email@example.com' - required - autofocus - value=email - ) - .actions - button.btn.btn-primary.w-100( - style="white-space: normal;" - type='submit' - data-ol-disabled-inflight - aria-label=translate('request_password_reset_to_reconfirm') - ) - span(data-ol-inflight="idle") - | #{translate('request_password_reset_to_reconfirm')} - span(hidden data-ol-inflight="pending") - | #{translate('request_password_reset_to_reconfirm')}… - div(hidden data-ol-sent) - div.alert.alert-success( - role="alert" - aria-live="polite" - ) - span #{translate('password_reset_email_sent')} + input(type="hidden" name="_csrf" value=csrfToken) + .form-group.mb-3 + label.form-label(for='email') #{translate("please_enter_email")} + input.form-control( + aria-label="email" + type='email' + name='email' + placeholder='email@example.com' + required + autofocus + value=email + ) + .actions + button.btn.btn-primary.w-100( + style="white-space: normal;" + type='submit' + data-ol-disabled-inflight + aria-label=translate('request_password_reset_to_reconfirm') + ) + span(data-ol-inflight="idle") + | #{translate('request_password_reset_to_reconfirm')} + span(hidden data-ol-inflight="pending") + | #{translate('request_password_reset_to_reconfirm')}… + div(hidden data-ol-sent) + div.alert.alert-success( + role="alert" + aria-live="polite" + ) + span #{translate('password_reset_email_sent')} - if showCaptcha - +recaptchaConditions + if showCaptcha + +recaptchaConditions diff --git a/services/web/app/views/user/reconfirm.pug b/services/web/app/views/user/reconfirm.pug index 7c17423d5a..23b77d278d 100644 --- a/services/web/app/views/user/reconfirm.pug +++ b/services/web/app/views/user/reconfirm.pug @@ -23,7 +23,7 @@ block content .row .col-sm-12.col-md-6.col-md-offset-3 .card - h1.card-header #{translate("reconfirm")} #{translate("Account")} + h1.card-header #{translate("reconfirm_account")} p #{translate('reconfirm_explained')}  a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail} | . diff --git a/services/web/app/views/user/setPassword-bs5.pug b/services/web/app/views/user/setPassword-bs5.pug index 007ae5e87c..83c3a531bb 100644 --- a/services/web/app/views/user/setPassword-bs5.pug +++ b/services/web/app/views/user/setPassword-bs5.pug @@ -1,90 +1,91 @@ -extends ../layout-website-redesign-bootstrap-5 +extends ../layout-website-redesign block vars - - var suppressNavbar = true - - var suppressFooter = true + - var suppressNavbar = true + - var suppressFooter = true + - isWebsiteRedesign = true block content - main#main-content - a.auth-aux-logo(href="/") - img(src=buildImgPath("ol-brand/overleaf-o-dark.svg") alt=settings.appName) - .auth-aux-container - form( - data-ol-async-form - name="passwordResetForm" - action="/user/password/set" - method="POST" - data-ol-hide-on-error="token-expired" - ) - div( - hidden - data-ol-sent - ) - h1.h3.mb-3.mt-0 #{translate("password_updated")} - p.mb-4 #{translate("your_password_has_been_successfully_changed")}. - a.btn.btn-primary.w-100(href='/login') #{translate("log_in_now")} + main#main-content + a.auth-aux-logo(href="/") + img(src=buildImgPath("ol-brand/overleaf-o-dark.svg") alt=settings.appName) + .auth-aux-container + form( + data-ol-async-form + name="passwordResetForm" + action="/user/password/set" + method="POST" + data-ol-hide-on-error="token-expired" + ) + div( + hidden + data-ol-sent + ) + h1.h3.mb-3.mt-0 #{translate("password_updated")} + p.mb-4 #{translate("your_password_has_been_successfully_changed")}. + a.btn.btn-primary.w-100(href='/login') #{translate("log_in_now")} - div(data-ol-not-sent) - h1.h3.mb-3.mt-0 #{translate("reset_your_password")} - p(data-ol-hide-on-error-message="token-expired") #{translate("create_a_new_password_for_your_account")}. - +formMessagesNewStyle() + div(data-ol-not-sent) + h1.h3.mb-3.mt-0 #{translate("reset_your_password")} + p(data-ol-hide-on-error-message="token-expired") #{translate("create_a_new_password_for_your_account")}. + +formMessagesNewStyle() - +customFormMessageNewStyle('password-contains-email', 'danger') - | #{translate('invalid_password_contains_email')}. - | #{translate('use_a_different_password')}. + +customFormMessageNewStyle('password-contains-email', 'danger') + | #{translate('invalid_password_contains_email')}. + | #{translate('use_a_different_password')}. - +customFormMessageNewStyle('password-too-similar', 'danger') - | #{translate('invalid_password_too_similar')}. - | #{translate('use_a_different_password')}. + +customFormMessageNewStyle('password-too-similar', 'danger') + | #{translate('invalid_password_too_similar')}. + | #{translate('use_a_different_password')}. - +customFormMessageNewStyle('token-expired', 'danger') - | #{translate('password_reset_token_expired')} - br - a(href="/user/password/reset") - | #{translate('request_new_password_reset_email')} + +customFormMessageNewStyle('token-expired', 'danger') + | #{translate('password_reset_token_expired')} + br + a(href="/user/password/reset") + | #{translate('request_new_password_reset_email')} - input(type="hidden" name="_csrf" value=csrfToken) - input(type="text" hidden name="email" autocomplete="username" value=email) + input(type="hidden" name="_csrf" value=csrfToken) + input(type="text" hidden name="email" autocomplete="username" value=email) - .form-group.mb-3 - label.form-label(for='passwordField', data-ol-hide-on-error-message="token-expired") #{translate("new_password")} - input.form-control.auth-aux-new-password#passwordField( - type='password' - name='password' - autocomplete="new-password" - autofocus - required - minlength=settings.passwordStrengthOptions.length.min - ) + .form-group.mb-3 + label.form-label(for='passwordField', data-ol-hide-on-error-message="token-expired") #{translate("new_password")} + input.form-control.auth-aux-new-password#passwordField( + type='password' + name='password' + autocomplete="new-password" + autofocus + required + minlength=settings.passwordStrengthOptions.length.min + ) - +customValidationMessageNewStyle('invalid-password') - | #{translate('invalid_password')}. + +customValidationMessageNewStyle('invalid-password') + | #{translate('invalid_password')}. - +customValidationMessageNewStyle('password-must-be-different') - | #{translate('password_cant_be_the_same_as_current_one')}. + +customValidationMessageNewStyle('password-must-be-different') + | #{translate('password_cant_be_the_same_as_current_one')}. - +customValidationMessageNewStyle('password-must-be-strong') - | !{translate('password_was_detected_on_a_public_list_of_known_compromised_passwords', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}])}. - | #{translate('use_a_different_password')}. + +customValidationMessageNewStyle('password-must-be-strong') + | !{translate('password_was_detected_on_a_public_list_of_known_compromised_passwords', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}])}. + | #{translate('use_a_different_password')}. - input( - type="hidden" - name="passwordResetToken" - value=passwordResetToken - ) - div(data-ol-hide-on-error-message="token-expired") - div #{translate('in_order_to_have_a_secure_account_make_sure_your_password')} - ul.mb-3.ps-4 - li #{translate('is_longer_than_n_characters', {n: settings.passwordStrengthOptions.length.min})} - li #{translate('does_not_contain_or_significantly_match_your_email')} - li #{translate('is_not_used_on_any_other_website')} - .actions - button.btn.btn-primary.w-100( - type='submit' - data-ol-disabled-inflight - aria-label=translate('set_new_password') - ) - span(data-ol-inflight="idle") - | #{translate('set_new_password')} - span(hidden data-ol-inflight="pending") - | #{translate('set_new_password')}… + input( + type="hidden" + name="passwordResetToken" + value=passwordResetToken + ) + div(data-ol-hide-on-error-message="token-expired") + div #{translate('in_order_to_have_a_secure_account_make_sure_your_password')} + ul.mb-3.ps-4 + li #{translate('is_longer_than_n_characters', {n: settings.passwordStrengthOptions.length.min})} + li #{translate('does_not_contain_or_significantly_match_your_email')} + li #{translate('is_not_used_on_any_other_website')} + .actions + button.btn.btn-primary.w-100( + type='submit' + data-ol-disabled-inflight + aria-label=translate('set_new_password') + ) + span(data-ol-inflight="idle") + | #{translate('set_new_password')} + span(hidden data-ol-inflight="pending") + | #{translate('set_new_password')}… diff --git a/services/web/frontend/stylesheets/bootstrap-5/pages/plans.scss b/services/web/frontend/stylesheets/bootstrap-5/pages/plans.scss index 84c72c7208..65b1e8b12c 100644 --- a/services/web/frontend/stylesheets/bootstrap-5/pages/plans.scss +++ b/services/web/frontend/stylesheets/bootstrap-5/pages/plans.scss @@ -767,6 +767,247 @@ $z-index-group-member-picker-list: 1; border-left: var(--border-width-base) solid var(--green-50); } + .ai-assist { + color: var(--neutral-90); + + @include media-breakpoint-up(lg) { + padding-left: 0 !important; + padding-right: 0 !important; + } + + .ai-assist-heading { + margin-top: var(--spacing-12); + margin-bottom: var(--spacing-12); + text-align: center; + } + + .ai-assist-container { + padding: var(--spacing-10); + border: var(--spacing-02) solid var(--neutral-10); + border-radius: var(--border-radius-large-new); + background: + linear-gradient(270deg, var(--blue-10), #fff) 0.13%, + #fff 63.21%; + + @include media-breakpoint-down(lg) { + background: var(--bg-light-primary); + border-width: 2px; + border-radius: var(--border-radius-medium); + border-color: var(--premium-gradient); + padding: var(--spacing-09); + } + + .ai-assist-content { + display: flex; + justify-content: space-between; + gap: var(--spacing-07); + + @include media-breakpoint-down(lg) { + flex-direction: column; + } + + .ai-assist-left { + display: flex; + gap: var(--spacing-07); + flex-direction: column; + max-width: 480px; + + @include media-breakpoint-down(lg) { + max-width: 100%; + } + + .ai-assist-price { + font-weight: 600; + font-size: var(--font-size-03); + + @include media-breakpoint-down(lg) { + font-weight: normal; + font-size: var(--font-size-02); + + .price { + font-size: var(--font-size-08); + font-weight: 600; + } + } + } + + .ai-assist-annually-price { + display: block; + } + + .ai-assist-monthly-price { + display: none; + } + + .ai-assist-header-switch { + display: none; + } + + .ai-assist-header { + display: flex; + align-items: center; + justify-content: space-between; + + .ai-assist-header-content { + display: flex; + gap: var(--spacing-06); + align-items: center; + + h3 { + font-size: var(--font-size-07); + margin: 0; + padding: 0; + + @include media-breakpoint-down(lg) { + font-size: var(--font-size-05); + } + } + + img { + @include media-breakpoint-down(lg) { + width: 24px; + } + } + } + + .ai-assist-header-switch { + align-items: center; + gap: var(--spacing-03); + user-select: none; + + input { + margin: 0; + } + + label { + margin: 0; + font-weight: normal; + font-size: var(--font-size-03); + } + } + } + } + + .ai-assist-right { + display: flex; + align-items: center; + gap: var(--spacing-06); + + .ai-assist-features { + list-style: none; + display: flex; + flex-direction: column; + gap: var(--spacing-04); + min-width: 210px; + margin-bottom: 0; + + .feature-item { + display: flex; + align-items: center; + font-size: var(--font-size-03); + cursor: default; + + .feature-icon { + margin-right: var(--spacing-05); + color: var(--neutral-70); + width: 16px; + height: 16px; + } + + .feature-text { + color: var(--neutral-90); + } + } + + @include media-breakpoint-up(lg) { + .feature-item-selected { + .feature-text { + color: var(--blue-50); + font-weight: 600; + } + + .feature-icon { + content: url(../../../../public/img/check-circle-blue-filled.svg); + } + } + } + } + + .ai-assist-images { + display: flex; + align-items: flex-start; + width: 280px; + justify-content: center; + + @include media-breakpoint-down(lg) { + display: none; + } + } + } + } + } + + .ai-assist-header-switch { + display: flex !important; + } + + .ai-assist-button-container { + display: flex; + gap: var(--spacing-05); + + &.mobile { + display: none; + margin-top: var(--spacing-06); + flex-direction: column; + } + + @include media-breakpoint-down(lg) { + &.mobile { + display: flex; + } + + &.desktop { + display: none; + } + } + + .btn.monthly { + display: none; + } + } + + .overleaf-assist-screenshot { + height: auto; + max-width: 280px; + max-height: 200px; + border-radius: var(--border-radius-base-new); + display: none; + + &.selected { + display: block; + animation: fade-in 1s; + } + } + } + + .ai-assist.monthly-period { + .ai-assist-annually-price { + display: none !important; + } + + .ai-assist-monthly-price { + display: block !important; + } + + .ai-assist-button-container .btn.annual { + display: none !important; + } + + .ai-assist-button-container .btn.monthly { + display: block !important; + } + } + .plans-new-organizations { padding: var(--spacing-13) var(--spacing-08); diff --git a/services/web/modules/user-activate/app/views/user/activate.pug b/services/web/modules/user-activate/app/views/user/activate.pug index 20ccb4dd8e..1b48041f1c 100644 --- a/services/web/modules/user-activate/app/views/user/activate.pug +++ b/services/web/modules/user-activate/app/views/user/activate.pug @@ -1,4 +1,7 @@ -extends ../../../../../app/views/layout-website-redesign-bootstrap-5 +extends ../../../../../app/views/layout-website-redesign + +block vars + - isWebsiteRedesign = true block content main.content.content-alt#main-content