Commit 372084e0 by Greg Price

Merge branch 'drupal-new'

Conflicts:
	lms/envs/common.py
parents 5f7e856c de5b4d7d
......@@ -317,3 +317,7 @@ INSTALLED_APPS = (
'staticfiles',
'static_replace',
)
################# EDX MARKETING SITE ##################################
EDXMKTG_COOKIE_NAME = 'edxloggedin'
......@@ -14,9 +14,57 @@
from django.template import Context
from django.http import HttpResponse
import logging
from . import middleware
from django.conf import settings
from django.core.urlresolvers import reverse
log = logging.getLogger(__name__)
def marketing_link(name):
"""Returns the correct URL for a link to the marketing site
depending on if the marketing site is enabled
Since the marketing site is enabled by a setting, we have two
possible URLs for certain links. This function is to decides
which URL should be provided.
"""
# link_map maps URLs from the marketing site to the old equivalent on
# the Django site
link_map = settings.MKTG_URL_LINK_MAP
if settings.MITX_FEATURES.get('ENABLE_MKTG_SITE') and name in settings.MKTG_URLS:
# special case for when we only want the root marketing URL
if name == 'ROOT':
return settings.MKTG_URLS.get('ROOT')
return settings.MKTG_URLS.get('ROOT') + settings.MKTG_URLS.get(name)
# only link to the old pages when the marketing site isn't on
elif not settings.MITX_FEATURES.get('ENABLE_MKTG_SITE') and name in link_map:
return reverse(link_map[name])
else:
log.warning("Cannot find corresponding link for name: {name}".format(name=name))
return '#'
def marketing_link_context_processor(request):
"""
A django context processor to give templates access to marketing URLs
Returns a dict whose keys are the marketing link names usable with the
marketing_link method (e.g. 'ROOT', 'CONTACT', etc.) prefixed with
'MKTG_URL_' and whose values are the corresponding URLs as computed by the
marketing_link method.
"""
return dict(
[
("MKTG_URL_" + k, marketing_link(k))
for k in (
settings.MKTG_URL_LINK_MAP.viewkeys() |
settings.MKTG_URLS.viewkeys()
)
]
)
def render_to_string(template_name, dictionary, context=None, namespace='main'):
......@@ -27,6 +75,7 @@ def render_to_string(template_name, dictionary, context=None, namespace='main'):
context_dictionary = {}
context_instance['settings'] = settings
context_instance['MITX_ROOT_URL'] = settings.MITX_ROOT_URL
context_instance['marketing_link'] = marketing_link
# In various testing contexts, there might not be a current request context.
if middleware.requestcontext is not None:
......
......@@ -14,6 +14,7 @@
from django.conf import settings
from mako.template import Template as MakoTemplate
from mitxmako.shortcuts import marketing_link
from mitxmako import middleware
......@@ -37,7 +38,6 @@ class Template(MakoTemplate):
kwargs.update(overrides)
super(Template, self).__init__(*args, **kwargs)
def render(self, context_instance):
"""
This takes a render call with a context (from Django) and translates
......@@ -55,5 +55,6 @@ class Template(MakoTemplate):
context_dictionary['settings'] = settings
context_dictionary['MITX_ROOT_URL'] = settings.MITX_ROOT_URL
context_dictionary['django_context'] = context_instance
context_dictionary['marketing_link'] = marketing_link
return super(Template, self).render_unicode(**context_dictionary)
from django.test import TestCase
from django.test.utils import override_settings
from django.core.urlresolvers import reverse
from django.conf import settings
from mitxmako.shortcuts import marketing_link
from mock import patch
class ShortcutsTests(TestCase):
"""
Test the mitxmako shortcuts file
"""
@override_settings(MKTG_URLS={'ROOT': 'dummy-root', 'ABOUT': '/about-us'})
@override_settings(MKTG_URL_LINK_MAP={'ABOUT': 'login'})
def test_marketing_link(self):
# test marketing site on
with patch.dict('django.conf.settings.MITX_FEATURES', {'ENABLE_MKTG_SITE': True}):
expected_link = 'dummy-root/about-us'
link = marketing_link('ABOUT')
self.assertEquals(link, expected_link)
# test marketing site off
with patch.dict('django.conf.settings.MITX_FEATURES', {'ENABLE_MKTG_SITE': False}):
# we are using login because it is common across both cms and lms
expected_link = reverse('login')
link = marketing_link('ABOUT')
self.assertEquals(link, expected_link)
......@@ -122,6 +122,13 @@ def should_see_a_link_called(step, text):
assert len(world.browser.find_link_by_text(text)) > 0
@step(r'should see (?:the|a) link with the id "([^"]*)" called "([^"]*)"$')
def should_have_link_with_id_and_text(step, link_id, text):
link = world.browser.find_by_id(link_id)
assert len(link) > 0
assert_equals(link.text, text)
@step(r'should see "(.*)" (?:somewhere|anywhere) in (?:the|this) page')
def should_see_in_the_page(step, text):
assert_in(text, world.css_text('body'))
......@@ -144,3 +151,8 @@ def i_am_an_edx_user(step):
@step(u'User "([^"]*)" is an edX user$')
def registered_edx_user(step, uname):
world.create_user(uname)
@step(u'All dialogs should be closed$')
def dialogs_are_closed(step):
assert world.dialogs_closed()
#pylint: disable=C0111
#pylint: disable=W0621
from lettuce import world, step
from lettuce import world
import time
from urllib import quote_plus
from selenium.common.exceptions import WebDriverException
......@@ -105,10 +105,21 @@ def css_visible(css_selector):
@world.absorb
def dialogs_closed():
def are_dialogs_closed(driver):
'''
Return True when no modal dialogs are visible
'''
return not css_visible('.modal')
wait_for(are_dialogs_closed)
return not css_visible('.modal')
@world.absorb
def save_the_html(path='/tmp'):
u = world.browser.url
html = world.browser.html.encode('ascii', 'ignore')
filename = '%s.html' % quote_plus(u)
f = open('%s/%s' % (path, filename), 'w')
f.write(html)
f.close
f.close()
......@@ -6,6 +6,7 @@ from django_future.csrf import ensure_csrf_cookie
import student.views
import branding
import courseware.views
from mitxmako.shortcuts import marketing_link
from util.cache import cache_if_anonymous
......@@ -22,6 +23,8 @@ def index(request):
if settings.MITX_FEATURES.get('AUTH_USE_MIT_CERTIFICATES'):
from external_auth.views import ssl_login
return ssl_login(request)
if settings.MITX_FEATURES.get('ENABLE_MKTG_SITE'):
return redirect(settings.MKTG_URLS.get('ROOT'))
university = branding.get_university(request.META.get('HTTP_HOST'))
if university is None:
......@@ -34,9 +37,12 @@ def index(request):
@cache_if_anonymous
def courses(request):
"""
Render the "find courses" page. If subdomain branding is on, this is the
university profile page, otherwise it's the edX courseware.views.courses page
Render the "find courses" page. If the marketing site is enabled, redirect
to that. Otherwise, if subdomain branding is on, this is the university
profile page. Otherwise, it's the edX courseware.views.courses page
"""
if settings.MITX_FEATURES.get('ENABLE_MKTG_SITE', False):
return redirect(marketing_link('COURSES'), permanent=True)
university = branding.get_university(request.META.get('HTTP_HOST'))
if university is None:
......
......@@ -5,29 +5,24 @@ Feature: Homepage for web users
Scenario: User can see the "Login" button
Given I visit the homepage
Then I should see a link called "Log In"
Then I should see a link called "Log in"
Scenario: User can see the "Sign up" button
Scenario: User can see the "Register Now" button
Given I visit the homepage
Then I should see a link called "Sign Up"
Then I should see a link called "Register Now"
Scenario Outline: User can see main parts of the page
Given I visit the homepage
Then I should see a link called "<Link>"
When I click the link with the text "<Link>"
Then I should see that the path is "<Path>"
Then I should see a link with the id "<id>" called "<Link>"
Examples:
| Link | Path |
| Find Courses | /courses |
| About | /about |
| Jobs | /jobs |
| Contact | /contact |
| id | Link |
| about | About |
| jobs | Jobs |
| faq | FAQ |
| contact | Contact|
| press | Press |
Scenario: User can visit the blog
Given I visit the homepage
When I click the link with the text "Blog"
Then I should see that the url is "http://blog.edx.org/"
# TODO: test according to domain or policy
Scenario: User can see the partner institutions
......
......@@ -7,7 +7,7 @@ Feature: Login in as a registered user
Given I am an edX user
And I am an unactivated user
And I visit the homepage
When I click the link with the text "Log In"
When I click the link with the text "Log in"
And I submit my credentials on the login form
Then I should see the login error message "This account has not been activated"
......@@ -15,7 +15,7 @@ Feature: Login in as a registered user
Given I am an edX user
And I am an activated user
And I visit the homepage
When I click the link with the text "Log In"
When I click the link with the text "Log in"
And I submit my credentials on the login form
Then I should be on the dashboard page
......@@ -23,5 +23,5 @@ Feature: Login in as a registered user
Given I am logged in
When I click the dropdown arrow
And I click the link with the text "Log Out"
Then I should see a link with the text "Log In"
Then I should see a link with the text "Log in"
And I should see that the path is "/"
......@@ -19,13 +19,13 @@ def i_am_an_activated_user(step):
def i_submit_my_credentials_on_the_login_form(step):
fill_in_the_login_form('email', 'robot@edx.org')
fill_in_the_login_form('password', 'test')
login_form = world.browser.find_by_css('form#login_form')
login_form.find_by_value('Access My Courses').click()
login_form = world.browser.find_by_css('form#login-form')
login_form.find_by_name('submit').click()
@step(u'I should see the login error message "([^"]*)"$')
def i_should_see_the_login_error_message(step, msg):
login_error_div = world.browser.find_by_css('form#login_form #login_error')
login_error_div = world.browser.find_by_css('.submission-error.is-shown')
assert (msg in login_error_div.text)
......@@ -49,6 +49,6 @@ def user_is_an_activated_user(uname):
def fill_in_the_login_form(field, value):
login_form = world.browser.find_by_css('form#login_form')
login_form = world.browser.find_by_css('form#login-form')
form_field = login_form.find_by_name(field)
form_field.fill(value)
......@@ -15,4 +15,6 @@ Feature: Register for a course
And I visit the dashboard
When I click the link with the text "Unregister"
And I press the "Unregister" button in the Unenroll dialog
Then I should see "Looks like you haven't registered for any courses yet." somewhere in the page
Then All dialogs should be closed
And I should be on the dashboard page
And I should see "Looks like you haven't registered for any courses yet." somewhere in the page
......@@ -5,12 +5,12 @@ Feature: Sign in
Scenario: Sign up from the homepage
Given I visit the homepage
When I click the link with the text "Sign Up"
When I click the link with the text "Register Now"
And I fill in "email" on the registration form with "robot2@edx.org"
And I fill in "password" on the registration form with "test"
And I fill in "username" on the registration form with "robot2"
And I fill in "name" on the registration form with "Robot Two"
And I check the checkbox named "terms_of_service"
And I check the checkbox named "honor_code"
And I press the "Create My Account" button on the registration form
And I submit the registration form
Then I should see "THANKS FOR REGISTERING!" in the dashboard banner
......@@ -3,17 +3,18 @@
from lettuce import world, step
@step('I fill in "([^"]*)" on the registration form with "([^"]*)"$')
def when_i_fill_in_field_on_the_registration_form_with_value(step, field, value):
register_form = world.browser.find_by_css('form#register_form')
register_form = world.browser.find_by_css('form#register-form')
form_field = register_form.find_by_name(field)
form_field.fill(value)
@step('I press the "([^"]*)" button on the registration form$')
def i_press_the_button_on_the_registration_form(step, button):
register_form = world.browser.find_by_css('form#register_form')
register_form.find_by_value(button).click()
@step('I submit the registration form$')
def i_press_the_button_on_the_registration_form(step):
register_form = world.browser.find_by_css('form#register-form')
register_form.find_by_name('submit').click()
@step('I check the checkbox named "([^"]*)"$')
......
......@@ -220,25 +220,20 @@ class LoginEnrollmentTestCase(TestCase):
# Now make sure that the user is now actually activated
self.assertTrue(get_user(email).is_active)
def _enroll(self, course):
"""Post to the enrollment view, and return the parsed json response"""
def try_enroll(self, course):
"""Try to enroll. Return bool success instead of asserting it."""
resp = self.client.post('/change_enrollment', {
'enrollment_action': 'enroll',
'course_id': course.id,
})
return parse_json(resp)
def try_enroll(self, course):
"""Try to enroll. Return bool success instead of asserting it."""
data = self._enroll(course)
print ('Enrollment in %s result: %s'
% (course.location.url(), str(data)))
return data['success']
print ('Enrollment in %s result status code: %s'
% (course.location.url(), str(resp.status_code)))
return resp.status_code == 200
def enroll(self, course):
"""Enroll the currently logged-in user, and check that it worked."""
data = self._enroll(course)
self.assertTrue(data['success'])
result = self.try_enroll(course)
self.assertTrue(result)
def unenroll(self, course):
"""Unenroll the currently logged-in user, and check that it worked."""
......@@ -246,8 +241,7 @@ class LoginEnrollmentTestCase(TestCase):
'enrollment_action': 'unenroll',
'course_id': course.id,
})
data = parse_json(resp)
self.assertTrue(data['success'])
self.assertTrue(resp.status_code == 200)
def check_for_get_code(self, code, url):
"""
......
......@@ -515,6 +515,9 @@ def registered_for_course(course, user):
@ensure_csrf_cookie
@cache_if_anonymous
def course_about(request, course_id):
if settings.MITX_FEATURES.get('ENABLE_MKTG_SITE', False):
raise Http404
course = get_course_with_access(request.user, course_id, 'see_exists')
registered = registered_for_course(course, request.user)
......@@ -531,6 +534,37 @@ def course_about(request, course_id):
'registered': registered,
'course_target': course_target,
'show_courseware_link': show_courseware_link})
@ensure_csrf_cookie
@cache_if_anonymous
def mktg_course_about(request, course_id):
try:
course = get_course_with_access(request.user, course_id, 'see_exists')
except (ValueError, Http404) as e:
# if a course does not exist yet, display a coming
# soon button
return render_to_response('courseware/mktg_coming_soon.html',
{'course_id': course_id})
registered = registered_for_course(course, request.user)
if has_access(request.user, course, 'load'):
course_target = reverse('info', args=[course.id])
else:
course_target = reverse('about_course', args=[course.id])
allow_registration = has_access(request.user, course, 'enroll')
show_courseware_link = (has_access(request.user, course, 'load') or
settings.MITX_FEATURES.get('ENABLE_LMS_MIGRATION'))
return render_to_response('courseware/mktg_course_about.html',
{'course': course,
'registered': registered,
'allow_registration': allow_registration,
'course_target': course_target,
'show_courseware_link': show_courseware_link})
@ensure_csrf_cookie
......
......@@ -133,6 +133,7 @@ COMMENTS_SERVICE_KEY = ENV_TOKENS.get("COMMENTS_SERVICE_KEY", '')
CERT_QUEUE = ENV_TOKENS.get("CERT_QUEUE", 'test-pull')
ZENDESK_URL = ENV_TOKENS.get("ZENDESK_URL")
FEEDBACK_SUBMISSION_EMAIL = ENV_TOKENS.get("FEEDBACK_SUBMISSION_EMAIL")
MKTG_URLS = ENV_TOKENS.get('MKTG_URLS', MKTG_URLS)
for name, value in ENV_TOKENS.get("CODE_JAIL", {}).items():
oldvalue = CODE_JAIL.get(name)
......
......@@ -36,6 +36,7 @@ DISCUSSION_SETTINGS = {
'MAX_COMMENT_DEPTH': 2,
}
# Features
MITX_FEATURES = {
'SAMPLE': False,
......@@ -182,6 +183,9 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.messages.context_processors.messages',
'sekizai.context_processors.sekizai',
'course_wiki.course_nav.context_processor',
# Hack to get required link URLs to password reset templates
'mitxmako.shortcuts.marketing_link_context_processor',
)
STUDENT_FILEUPLOAD_MAX_SIZE = 4 * 1000 * 1000 # 4 MB
......@@ -691,3 +695,17 @@ INSTALLED_APPS = (
# Student notes
'notes',
)
######################### MARKETING SITE ###############################
EDXMKTG_COOKIE_NAME = 'edxloggedin'
MKTG_URLS = {}
MKTG_URL_LINK_MAP = {
'ABOUT': 'about_edx',
'CONTACT': 'contact',
'FAQ': 'help_edx',
'COURSES': 'courses',
'ROOT': 'root',
'TOS': 'tos',
'HONOR': 'honor',
'PRIVACY': 'privacy_edx',
}
lms/static/images/header-logo.png

1.51 KB | W: | H:

lms/static/images/header-logo.png

1.19 KB | W: | H:

lms/static/images/header-logo.png
lms/static/images/header-logo.png
lms/static/images/header-logo.png
lms/static/images/header-logo.png
  • 2-up
  • Swipe
  • Onion skin
// edX LMS - shame
// shame file - used for any bad-form/orphaned scss that knowingly violate edX FED architecture/standards (see - http://csswizardry.com/2013/04/shame-css/)
// ====================
// marketing site - registration iframe band-aid (poor form enough to isolate out)
.view-partial-mktgregister {
background: transparent;
// dimensions needed for course about page on marketing site
.wrapper-view {
overflow: hidden;
}
// button elements - not a better place to put these, sadly
.btn {
@include box-sizing('border-box');
display: block;
padding: $baseline/2;
text-transform: lowercase;
color: $white;
letter-spacing: 0.1rem;
cursor: pointer;
text-align: center;
border: none !important;
text-decoration: none;
text-shadow: none;
letter-spacing: 0.1rem;
font-size: 17px;
font-weight: 300;
box-shadow: 0 !important;
strong {
font-weight: 400;
text-transform: none;
}
}
.btn-primary {
@extend .btn;
@include linear-gradient($m-blue-s1 5%, $m-blue-d1 95%);
// no hover state conventions to follow from marketing :/
&:hover, &:active {
}
}
.btn-secondary {
@extend .btn;
@include linear-gradient($m-gray 5%, $m-gray-d1 95%);
// no hover state conventions to follow from marketing :/
&:hover, &:active {
}
}
.btn-tertiary {
@extend .btn;
background: $m-blue-l1;
color: $m-blue;
// no hover state conventions to follow from marketing :/
&:hover, &:active {
}
}
// nav list
.list-actions {
list-style: none;
margin: 0;
padding: 0;
.item {
margin: 0;
}
}
.action {
// register or access courseware
&.action-register, &.access-courseware {
@extend .btn-primary;
}
// already registered but course not started or registration is closed
&.is-registered, &.registration-closed {
@extend .btn-secondary;
pointer-events: none !important;
}
// coming soon
&.coming-soon {
@extend .btn-tertiary;
pointer-events: none !important;
outline: none;
}
}
}
......@@ -19,6 +19,7 @@
@import 'multicourse/home';
@import 'multicourse/dashboard';
@import 'multicourse/account';
@import 'multicourse/testcenter-register';
@import 'multicourse/courses';
@import 'multicourse/course_about';
......@@ -33,3 +34,5 @@
@import 'discussion';
@import 'news';
@import 'shame';
html, body {
// html {
// overflow-y: scroll;
// }
body {
background: rgb(250,250,250);
font-family: $sans-serif;
font-size: 1em;
......@@ -81,9 +85,10 @@ a:link, a:visited {
}
.content-wrapper {
background: rgb(255,255,255);
margin: 0 auto 0;
width: flex-grid(12);
margin: 0 auto;
padding-bottom: ($baseline*2);
background: rgb(255,255,255);
}
.container {
......@@ -92,6 +97,7 @@ a:link, a:visited {
padding: 0px 30px;
max-width: grid-width(12);
min-width: 760px;
width: flex-grid(12);
}
span.edx {
......@@ -202,6 +208,10 @@ mark {
}
}
.sr {
@include text-sr();
}
.help-tab {
@include transform(rotate(-90deg));
@include transform-origin(0 0);
......
......@@ -7,10 +7,23 @@
@return $body-line-height * $amount;
}
@mixin hide-text(){
text-indent: -9999px;
// image-replacement hidden text
@mixin text-hide() {
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
display: block;
}
// hidden elems - screenreaders
@mixin text-sr() {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
@mixin vertically-and-horizontally-centered ( $height, $width ) {
......@@ -22,3 +35,10 @@
position: absolute;
top: 150px;
}
// sunsetted, but still used mixins
@mixin hide-text(){
text-indent: -9999px;
overflow: hidden;
display: block;
}
$baseline: 20px;
$gw-column: 80px;
$gw-gutter: 20px;
......@@ -8,27 +10,48 @@ $fg-max-width: 1400px;
$fg-min-width: 810px;
$sans-serif: 'Open Sans', $verdana;
$monospace: Monaco, 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;
$body-font-family: $sans-serif;
$serif: $georgia;
$monospace: Monaco, 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;
$body-font-size: em(14);
$body-line-height: golden-ratio(.875em, 1);
$base-font-color: rgb(60,60,60);
$baseFontColor: rgb(60,60,60);
$base-font-color: rgb(60,60,60);
$lighter-base-font-color: rgb(100,100,100);
$white: rgb(255,255,255);
$black: rgb(0,0,0);
$blue: rgb(29,157,217);
$pink: rgb(182,37,104);
$yellow: rgb(255, 252, 221);
$red: rgb(178, 6, 16);
$error-red: rgb(253, 87, 87);
$border-color: #C8C8C8;
$sidebar-color: #f6f6f6;
$outer-border-color: #aaa;
$light-gray: rgb(221, 221, 221);
$dark-gray: rgb(51, 51, 51);
$border-color: rgb(200, 200, 200);
$sidebar-color: rgb(246, 246, 246);
$outer-border-color: rgb(170, 170, 170);
// old variables
$light-gray: #ddd;
$dark-gray: #333;
// edx.org-related
$m-gray-l1: rgb(203,203,203);
$m-gray-l2: rgb(246,246,246);
$m-gray: rgb(153,153,153);
$m-gray-d1: rgb(102,102,102);
$m-gray-d2: rgb(51,51,51);
$m-gray-a1: rgb(80,80,80);
$m-blue: rgb(85, 151, 221);
$m-blue-l1: rgb(230,245,252);
$m-blue-d1: shade($m-blue,15%);
$m-blue-s1: saturate($m-blue,15%);
$m-pink: rgb(204,51,102);
$m-base-font-size: em(15);
$base-font-color: rgb(60,60,60);
$baseFontColor: rgb(60,60,60);
$lighter-base-font-color: rgb(100,100,100);
$text-color: $dark-gray;
$body-font-family: $sans-serif;
$body-font-size: em(14);
$body-line-height: golden-ratio(.875em, 1);
......@@ -61,10 +61,10 @@ nav.course-material {
}
header.global.slim {
border-bottom: 1px solid $outer-border-color;
@include box-shadow(0 1px 2px rgba(0, 0, 0, .1));
height: 50px;
@include linear-gradient(top, #fff, #eee);
border-bottom: 1px solid $outer-border-color;
background: $white;
.guest .secondary {
margin-right: 0;
......@@ -111,7 +111,7 @@ header.global.slim {
margin-right: 20px;
padding-right: 20px;
&::before {
&:before {
@extend .faded-vertical-divider;
content: "";
display: block;
......@@ -122,7 +122,7 @@ header.global.slim {
width: 1px;
}
&::after {
&:after {
@extend .faded-vertical-divider-light;
content: "";
display: block;
......@@ -134,7 +134,7 @@ header.global.slim {
}
}
.find-courses-button {
.nav-global {
display: none;
}
......
......@@ -154,6 +154,15 @@
@include transition();
width: flex-grid(5, 8);
}
#register_error {
background: $error-red;
border: 1px solid rgb(202, 17, 17);
color: rgb(143, 14, 14);
display: none;
padding: 12px;
margin-top: 5px;
}
}
}
......
.dashboard {
@include clearfix;
padding: 60px 0px 120px;
padding: 60px 0 0 0;
.dashboard-banner {
background: $yellow;
......@@ -327,7 +327,7 @@
color: $lighter-base-font-color;
}
h3 a {
h3 a, h3 span {
display: block;
margin-bottom: 10px;
font-family: $sans-serif;
......
......@@ -73,6 +73,7 @@
input[type="email"],
input[type="text"],
input[type="password"] {
border: 1px solid red !important;
background: rgb(255,255,255);
display: block;
height: 45px;
......
// ==========
$baseline: 20px;
$yellow: rgb(255, 235, 169);
$red: rgb(178, 6, 16);
// ==========
// Pearson VUE Test Center Registration
// =====
.testcenter-register {
@include clearfix;
......
footer {
background: transparent;
border-top: 1px solid rgb(200,200,200);
@include box-shadow(inset 0 1px 3px 0 rgba(0,0,0, 0.1));
margin: 0 auto;
width: flex-grid(12);
&.fixed-bottom {
bottom: 0px;
max-width: 100%;
position: absolute;
}
nav {
max-width: 1200px;
margin: 0 auto;
padding: 30px 10px 0;
.wrapper-footer {
@include box-shadow(0 -1px 5px 0 rgba(0,0,0, 0.1));
border-top: 1px solid tint($m-gray,50%);
padding: 25px ($baseline/2) ($baseline*1.5) ($baseline/2);
background: $white;
footer {
@include clearfix();
max-width: grid-width(12);
min-width: 760px;
width: flex-grid(12);
margin: 0 auto;
p, ol, ul {
font-family: $sans-serif;
}
a {
@include transition(color 0.15s ease-in-out, border 0.15s ease-in-out);
.top {
border-bottom: 1px solid rgb(200,200,200);
@include clearfix;
padding-bottom: 30px;
width: flex-grid(12);
text-align: center;
&:link, &:visited, &:hover, &:active {
border-bottom: none;
color: $m-blue;
text-decoration: none !important;
font-family: $sans-serif;
}
&:hover, &:active {
border-bottom: 1px dotted $m-blue-s1;
color: $m-blue-s1;
}
}
ol {
float: right;
// colophon
.colophon {
margin-right: flex-gutter(2);
width: flex-grid(6,12);
float: left;
.nav-colophon {
@include clearfix();
margin: ($baseline/4) 0 ($baseline*1.5) 0;
li {
@include inline-block;
list-style: none;
padding: 0px 15px;
position: relative;
vertical-align: middle;
&::after {
@extend .faded-vertical-divider;
content: "";
display: block;
height: 30px;
right: 0px;
position: absolute;
top: -5px;
width: 1px;
float: left;
margin-right: ($baseline*0.75);
a {
color: tint($black, 20%);
&:hover, &:active {
color: $m-blue-s1;
}
}
a:link, a:visited {
color: $lighter-base-font-color;
padding: 6px 0px;
&:last-child {
margin-right: 0;
}
}
}
.primary {
@include clearfix;
float: left;
a.logo {
@include background-image(url('/static/images/logo.png'));
background-position: 0 -24px;
background-repeat: no-repeat;
@include inline-block;
height: 22px;
margin-right: 15px;
margin-top: 2px;
padding-right: 15px;
position: relative;
width: 47px;
vertical-align: middle;
@include transition(none);
&:hover {
background-position: 0 0;
}
.colophon-about {
@include clearfix();
&::after {
@extend .faded-vertical-divider;
content: "";
display: block;
height: 30px;
right: 0px;
position: absolute;
top: -3px;
width: 1px;
}
img {
width: 68px;
height: 34px;
margin-right: 0;
float: left;
}
a {
color: $lighter-base-font-color;
@include inline-block;
margin-right: 20px;
padding-top: 2px;
vertical-align: middle;
&:hover {
color: $base-font-color;
text-decoration: none;
}
p {
float: left;
width: 460px;
margin-left: $baseline;
padding-left: $baseline;
font-size: em(13);
background: transparent url(/static/images/bg-footer-divider.jpg) 0 0 no-repeat;
}
}
}
.social {
float: right;
// references
.references {
margin: -10px 0 0 0;
width: flex-grid(4,12);
float: right;
&.social {
border: none;
margin: 0 0 0 5px;
padding: 0;
.nav-social {
margin: 0;
text-align: right;
li {
margin-right: ($baseline/10);
display: inline-block;
&:last-child {
margin-right: 0;
}
a {
@include inline-block;
opacity: 0.3;
@include transition(all, 0.1s, linear);
display: block;
&:hover {
opacity: 1;
&:hover, &:active {
border: none;
}
}
img {
display: block;
}
}
}
}
.bottom {
@include clearfix;
opacity: 0.8;
padding: 10px 0px 30px;
@include transition(all, 0.15s, linear);
width: flex-grid(12);
&:hover {
opacity: 1;
.copyright {
margin: -2px 0 8px 0;
font-size: em(11);
color: tint($m-gray,50%);
text-align: right;
}
.copyright {
float: left;
.nav-legal {
@include clearfix();
text-align: right;
p {
color: $lighter-base-font-color;
font-style: italic;
@include inline-block;
margin: 0 auto;
padding-top: 1px;
text-align: center;
vertical-align: middle;
li {
display: inline-block;
font-size: em(11);
a {
color: $lighter-base-font-color;
font-style: italic;
margin-left: 5px;
&:hover {
color: $blue;
}
display: block;
}
}
}
.secondary {
float: right;
text-align: left;
a {
color: $lighter-base-font-color;
font-family: $serif;
font-style: italic;
line-height: 1.6em;
margin-left: 20px;
text-transform: lowercase;
.nav-legal-01 a {
&:hover {
color: $blue;
&:after {
margin-left: 5px;
content: "-";
}
}
}
}
}
}
// marketing site design syncing
.view-register, .view-login {
.wrapper-footer footer {
width: 960px;
.colophon-about img {
margin-top: ($baseline*1.5);
}
.colophon-about p {
width: 360px;
}
}
}
\ No newline at end of file
header.global {
border-bottom: 1px solid rgb(190,190,190);
border-bottom: 1px solid $m-gray;
@include box-shadow(0 1px 5px 0 rgba(0,0,0, 0.1));
@include background-image(linear-gradient(-90deg, rgba(255,255,255, 1), rgba(230,230,230, 0.9)));
height: 68px;
background: $white;
height: 76px;
position: relative;
width: 100%;
z-index: 10;
......@@ -11,40 +11,17 @@ header.global {
@include clearfix;
height: 40px;
margin: 0 auto;
max-width: 1200px;
padding: 14px 10px 0px;
padding: 18px 10px 0px;
max-width: grid-width(12);
min-width: 760px;
width: flex-grid(12);
}
h1.logo {
float: left;
margin: 0px 15px 0px 0px;
padding-right: 20px;
margin: -2px 39px 0px 0px;
position: relative;
&::before {
@extend .faded-vertical-divider;
content: "";
display: block;
height: 50px;
position: absolute;
right: 1px;
top: -8px;
width: 1px;
}
&::after {
@extend .faded-vertical-divider-light;
content: "";
display: block;
height: 50px;
position: absolute;
right: 0px;
top: -12px;
width: 1px;
}
a {
display: block;
}
......@@ -251,4 +228,104 @@ header.global {
}
}
}
.nav-global {
margin-top: ($baseline/2);
list-style: none;
li {
display: inline-block;
margin: 0 $baseline+1 0 0;
font-size: em(14);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0 !important;
&:last-child {
margin-right: 0;
}
a {
display:block;
padding: ($baseline/4);
color: $m-gray-d1;
font-weight: 600;
&:hover, &:active {
text-decoration: none;
color: $m-blue-s1;
}
}
&.active {
a {
text-decoration: none;
color: $m-blue-s1;
}
}
}
// logged in
&.authenticated {
}
}
.nav-courseware {
float: right;
margin-top: ($baseline/4);
list-style: none;
li {
display: inline-block;
a {
@include border-radius(0);
@include linear-gradient($m-blue-s1 5%, $m-blue-d1 95%);
display: inline-block;
padding: $baseline/2 $baseline*2.5;
text-transform: lowercase;
color: $white;
letter-spacing: 0.1rem;
font-weight: 300;
cursor: pointer;
text-align: center;
border: none !important;
text-shadow: none;
letter-spacing: 0.1rem;
font-size: 14px;
box-shadow: none !important;
&:hover {
text-decoration: none;
}
}
}
// logged in
&.authenticated {
}
}
}
// marketing site design syncing
.view-register, .view-login {
header.global nav {
width: 960px;
}
}
// page-based nav states
.view-howitworks .nav-global-01,
.view-courses .nav-global-02,
.view-schools .nav-global-03,
.view-register .nav-global-04 {
a {
text-decoration: none;
color: $m-blue-s1 !important;
}
}
\ No newline at end of file
<%! from django.core.urlresolvers import reverse %>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%block name="headextra">
<style type="text/css">
.login-box {
display: block;
position: relative;
left: 0;
margin: 100px auto;
top: 0;
height:500px;
}
.login-box input[type=submit] {
white-space: normal;
height: auto !important;
}
</style>
</%block>
<section class='login-box'></section>
<script type="text/javascript">
(function() {
$(document).ready(
function() {
// show dialog
$('#login').click();
}
);
})(this)
</script>
......@@ -13,42 +13,26 @@
<%block name="js_extra">
% if not registered:
%if user.is_authenticated():
## If the user is authenticated, clicking the enroll button just submits a form
<script type="text/javascript">
(function() {
$(".register").click(function() {
$("#class_enroll_form").submit();
});
$(document).delegate('#class_enroll_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
location.href="${reverse('dashboard')}";
}else{
$('#register_message').html('<p class="inline-error">' + json.error + "</p>");
}
});
})(this)
</script>
%else:
## If the user is not authenticated, clicking the enroll button pops up the register
## field. We also slip in the registration fields into the login/register fields so
## the user is automatically registered after logging in / registering
<script type="text/javascript">
(function() {
$(".register").click(function() {
if ($(".login_form .enroll_fieldset").length === 0) {
$(".login_form").append( $(".enroll_fieldset").first().clone() );
}
if ($(".register_form .enroll_fieldset").length === 0) {
$(".register_form").append( $(".enroll_fieldset").first().clone() );
}
});
})(this)
</script>
%endif
%endif
<script type="text/javascript">
(function() {
$(".register").click(function(event) {
$("#class_enroll_form").submit();
event.preventDefault();
});
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) {
location.href = "${reverse('dashboard')}";
} else if (xhr.status == 403) {
location.href = "${reverse('register_user')}?course_id=${course.id}&enrollment_action=enroll";
} else {
$('#register_error').html(
(xhr.responseText ? xhr.responseText : 'An error occurred. Please try again later.')
).css("display", "block");
}
});
})(this)
</script>
<script src="${static.url('js/course_info.js')}"></script>
</%block>
......@@ -66,8 +50,7 @@
</hgroup>
<div class="main-cta">
%if user.is_authenticated():
%if registered:
%if user.is_authenticated() and registered:
%if show_courseware_link:
<a href="${course_target}">
%endif
......@@ -76,16 +59,9 @@
<strong>View Courseware</strong>
</a>
%endif
%else:
<a href="#" class="register">Register for ${course.number}</a>
<div id="register_message"></div>
%endif
%else:
<a href="#signup-modal" class="register" rel="leanModal" data-notice='You must Sign Up
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
or <a href="#login-modal" rel="leanModal">Log In</a>
% endif
to enroll.'>Register for ${course.number}</a>
<a href="#" class="register">Register for ${course.number}</a>
<div id="register_error"></div>
%endif
</div>
......@@ -204,5 +180,4 @@
</div>
%endif
<%include file="../video_modal.html" />
<%!
from django.core.urlresolvers import reverse
from courseware.courses import course_image_url, get_course_about_section
from courseware.access import has_access
%>
<%namespace name='static' file='../static_content.html'/>
<%inherit file="../mktg_iframe.html" />
<%block name="title"><title>About ${course_id}</title></%block>
<%block name="bodyclass">view-partial-mktgregister</%block>
<%block name="headextra">
<%include file="../google_analytics.html" />
</%block>
<%block name="content">
<script src="${static.url('js/course_info.js')}"></script>
<ul class="list-actions register">
<li class="item">
<a class="action coming-soon" href="">Coming Soon</a>
</li>
</ul>
</%block>
<%!
from django.core.urlresolvers import reverse
from courseware.courses import course_image_url, get_course_about_section
from courseware.access import has_access
%>
<%namespace name='static' file='../static_content.html'/>
<%inherit file="../mktg_iframe.html" />
<%block name="title"><title>About ${course.number}</title></%block>
<%block name="bodyclass">view-partial-mktgregister</%block>
<%block name="headextra">
<%include file="../google_analytics.html" />
</%block>
<%block name="js_extra">
<script type="text/javascript">
(function() {
$(".register").click(function(event) {
$("#class_enroll_form").submit();
event.preventDefault();
});
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) {
window.top.location.href = "${reverse('dashboard')}";
} else if (xhr.status == 403) {
window.top.location.href = "${reverse('register_user')}?course_id=${course.id}&enrollment_action=enroll";
} else {
$('#register_error').html(
(xhr.responseText ? xhr.responseText : 'An error occurred. Please try again later.')
).css("display", "block");
}
});
})(this)
</script>
</%block>
<%block name="content">
<script src="${static.url('js/course_info.js')}"></script>
<ul class="list-actions">
<li class="item">
%if user.is_authenticated() and registered:
%if show_courseware_link:
<a class="action access-courseware" href="${course_target}" target="_top">Access Courseware</a>
%else:
<div class="action is-registered">You Are Registered</div>
%endif
%elif allow_registration:
<a class="action action-register register" href="#">Register for <strong>${course.number}</strong></a>
%else:
<div class="action registration-closed">Registration Is Closed</div>
%endif
</li>
</ul>
%if not registered:
<div style="display: none;">
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
<fieldset class="enroll_fieldset">
<input name="course_id" type="hidden" value="${course.id}">
<input name="enrollment_action" type="hidden" value="enroll">
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }">
</fieldset>
<div class="submit">
<input name="enroll" type="submit" value="enroll">
</div>
</form>
</div>
%endif
</%block>
......@@ -59,14 +59,16 @@
$("#unenroll_course_number").text( $(event.target).data("course-number") );
});
$(document).delegate('#unenroll_form', 'ajax:success', function(data, json, xhr) {
if(json.success) {
location.href="${reverse('dashboard')}";
$('#unenroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) {
location.href = "${reverse('dashboard')}";
} else if (xhr.status == 403) {
location.href = "${reverse('signin_user')}?course_id=" +
$("#unenroll_course_id").val() + "&enrollment_action=unenroll";
} else {
if($('#unenroll_error').length == 0) {
$('#unenroll_form').prepend('<div id="unenroll_error" class="modal-form-error"></div>');
}
$('#unenroll_error').text(json.error).stop().css("display", "block");
$('#unenroll_error').html(
xhr.responseText ? xhr.responseText : "An error occurred. Please try again later."
).stop().css("display", "block");
}
});
......@@ -192,17 +194,20 @@
<article class="my-course">
<%
if has_access(user, course, 'load'):
course_target = reverse('info', args=[course.id])
else:
course_target = reverse('about_course', args=[course.id])
%>
<a href="${course_target}" class="cover">
<img src="${course_image_url(course)}" />
</a>
% if course.id in show_courseware_links_for:
<a href="${course_target}" class="cover">
<img src="${course_image_url(course)}" />
</a>
% else:
<div class="cover">
<img src="${course_image_url(course)}" />
</div>
% endif
<section class="info">
<hgroup>
......@@ -216,7 +221,13 @@
% endif
</p>
<h2 class="university">${get_course_about_section(course, 'university')}</h2>
<h3><a href="${course_target}">${course.number} ${course.display_name_with_default}</a></h3>
<h3>
% if course.id in show_courseware_links_for:
<a href="${course_target}">${course.number} ${course.display_name_with_default}</a>
% else:
<span>${course.number} ${course.display_name_with_default}</span>
% endif
</h3>
</hgroup>
<%
......@@ -326,7 +337,9 @@
% else:
<section class="empty-dashboard-message">
<p>Looks like you haven't registered for any courses yet.</p>
<a href="${reverse('courses')}">Find courses now!</a>
<a href="${marketing_link('COURSES')}">
Find courses now!
</a>
</section>
% endif
......@@ -355,6 +368,8 @@
<hr/>
</header>
<div id="unenroll_error" class="modal-form-error"></div>
<form id="unenroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
<input name="course_id" id="unenroll_course_id" type="hidden" />
<input name="enrollment_action" type="hidden" value="unenroll" />
......
......@@ -2,39 +2,89 @@
<%! from django.core.urlresolvers import reverse %>
<%namespace name='static' file='static_content.html'/>
<footer>
<nav>
<section class="top">
<section class="primary">
<a href="${reverse('root')}" class="logo"></a>
<a href="${reverse('courses')}">Find Courses</a>
<a href="${reverse('about_edx')}">About</a>
<a href="http://blog.edx.org/">Blog</a>
<a href="${reverse('jobs')}">Jobs</a>
<a href="${reverse('contact')}">Contact</a>
</section>
<div class="wrapper wrapper-footer">
<footer>
<div class="colophon">
<nav class="nav-colophon">
<ol>
<li class="nav-colophon-01">
<a id="about" href="${marketing_link('ABOUT')}">
About
</a>
</li>
<li class="nav-colophon-02">
<a id="jobs" href="${marketing_link('JOBS')}">
Jobs
</a>
</li>
<li class="nav-colophon-03">
<a id="press" href="${marketing_link('PRESS')}">
Press
</a>
</li>
<li class="nav-colophon-04">
<a id="faq" href="${marketing_link('FAQ')}">
FAQ
</a>
</li>
<li class="nav-colophon-05">
<a id="contact" href="${marketing_link('CONTACT')}">
Contact
</a>
</li>
</ol>
</nav>
<section class="social">
<a href="http://youtube.com/user/edxonline"><img src="${static.url('images/social/youtube-sharing.png')}" /></a>
<a href="https://plus.google.com/108235383044095082735"><img src="${static.url('images/social/google-plus-sharing.png')}" /></a>
<a href="http://www.facebook.com/EdxOnline"><img src="${static.url('images/social/facebook-sharing.png')}" /></a>
<a href="https://twitter.com/edXOnline"><img src="${static.url('images/social/twitter-sharing.png')}" /></a>
</section>
</section>
<div class="colophon-about">
<img src="${MITX_ROOT_URL}/static/images/header-logo.png" />
<section class="bottom">
<section class="copyright">
## <p>&copy; 2013 edX, <a href="${reverse('copyright')}">some rights reserved.</a></p> # TODO: (bridger) Update the copyright for edX, then re-enable the link.
<p>&copy; 2013 edX, some rights reserved.</p>
</section>
<p>EdX is a non-profit created by founding partners Harvard and MIT whose mission is to bring the best of higher education to students of all ages anywhere in the world, wherever there is Internet access. EdX’s free online MOOCs are interactive and subjects include computer science, public health, and artificial intelligence.</p>
</div>
</div>
<section class="secondary">
<a href="${reverse('tos')}">Terms of Service</a>
<a href="${reverse('privacy_edx')}">Privacy Policy</a>
<a href="${reverse('honor')}">Honor Code</a>
<a href="${reverse('help_edx')}">Help</a>
</section>
</section>
<div class="references">
<nav class="nav-social">
<ul>
<li class="nav-social-01">
<a href="http://www.meetup.com/edX-Global-Community/" rel="external">
<img src="${MITX_ROOT_URL}/static/images/social/ico-social-meetup.png" alt="edX on Meetup" />
</a>
</li>
<li class="nav-social-02">
<a href="http://www.facebook.com/EdxOnline" rel="external">
<img src="${MITX_ROOT_URL}/static/images/social/ico-social-facebook.png" alt="edX on Facebook" />
</a>
</li>
<li class="nav-social-03">
<a href="https://twitter.com/edXOnline" rel="external">
<img src="${MITX_ROOT_URL}/static/images/social/ico-social-twitter.png" alt="edX on Twitter" />
</a>
</li>
<li class="nav-social-04">
<a href="https://plus.google.com/108235383044095082735/posts" rel="external">
<img src="${MITX_ROOT_URL}/static/images/social/ico-social-google.png" alt="edX on Google+" />
</a>
</li>
<li class="nav-social-05">
<a href="http://youtube.com/user/edxonline" rel="external">
<img src="${MITX_ROOT_URL}/static/images/social/ico-social-youtube.png" alt="edX on YouTube" />
</a>
</li>
</ul>
</nav>
</nav>
</footer>
<p class="copyright">&copy; 2013 edX, some rights reserved.</p>
<nav class="nav-legal">
<ul>
<li class="nav-legal-01">
<a href="${marketing_link('TOS')}">Terms of Service and Honor Code</a>
</li>
<li class="nav-legal-02">
<a href="${marketing_link('PRIVACY')}">Privacy Policy</a>
</li>
</ul>
</nav>
</div>
</footer>
</div>
......@@ -3,19 +3,28 @@
<div class="inner-wrapper">
<div id="password-reset">
<header>
<h2>Password reset</h2>
<hr>
<h2>Password Reset</h2>
</header>
<div class="message">
<p>Enter your e-mail address below, and we will e-mail instructions for setting a new password.</p>
<div class="instructions">
<p>Please enter your e-mail address below, and we will e-mail instructions for setting a new password.</p>
</div>
<form id="pwd_reset_form" action="${reverse('password_reset')}" method="post" data-remote="true">
<label for="pwd_reset_email">E-mail address:</label>
<input id="pwd_reset_email" type="email" name="email" maxlength="75" placeholder="Your E-mail"/>
<div class="submit">
<input type="submit" id="pwd_reset_button" value="Reset my password" />
<fieldset class="group group-form group-form-requiredinformation">
<legend class="is-hidden">Required Information</legend>
<ol class="list-input">
<li class="field required text" id="field-email">
<label for="pwd_reset_email">Your E-mail Address</label>
<input class="" id="pwd_reset_email" type="email" name="email" value="" placeholder="example: username@domain.com" />
<span class="tip tip-input">This is the email address you used to register with edX</span>
</li>
</ol>
</fieldset>
<div class="form-actions">
<button name="submit" type="submit" id="pwd_reset_button" class="action action-primary action-update">Reset My Password</button>
</div>
</form>
</div>
......
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%! from django.core.urlresolvers import reverse %>
<%block name="title"><title>Log into your edX Account</title></%block>
<%block name="js_extra">
<script type="text/javascript">
$(function() {
var view_name = 'view-login';
// adding js class for styling with accessibility in mind
$('body').addClass('js').addClass(view_name);
// new window/tab opening
$('a[rel="external"], a[class="new-vp"]')
.click( function() {
window.open( $(this).attr('href') );
return false;
});
// form field label styling on focus
$("form :input").focus(function() {
$("label[for='" + this.id + "']").parent().addClass("is-focused");
}).blur(function() {
$("label").parent().removeClass("is-focused");
});
});
(function() {
toggleSubmitButton(true);
$('#login-form').on('submit', function() {
toggleSubmitButton(false);
});
$('#login-form').on('ajax:complete', function() {
toggleSubmitButton(true);
});
$('#login-form').on('ajax:success', function(event, json, xhr) {
if(json.success) {
$('.message.submission-error').removeClass('is-shown');
var u=decodeURI(window.location.search);
next=u.split("next=")[1];
if (next) {
location.href=next;
} else {
location.href="${reverse('dashboard')}";
}
} else {
$('.message.submission-error').addClass('is-shown');
$('.message.submission-error .message-copy').html(json.value);
}
});
})(this);
function toggleSubmitButton(enable) {
var $submitButton = $('form .form-actions #submit');
if(enable) {
$submitButton.
removeClass('is-disabled').
removeProp('disabled').
html('Log into My edX Account <span class="orn-plus">+</span> Access My Courses');
}
else {
$submitButton.
addClass('is-disabled').
prop('disabled', true).
html('Processing your account information &hellip;');
}
}
</script>
</%block>
<section class="introduction">
<header>
<h1 class="sr">Log Into Your Account</h1>
</header>
</section>
<section class="login container">
<section role="main" class="content">
<header>
<h2 class="sr">Login Form</h2>
</header>
<form role="form" id="login-form" method="post" data-remote="true" action="/login_ajax">
<!-- status messages -->
<div role="alert" class="status message">
<h3 class="message-title">We're Sorry, edX accounts are unavailable currently</h3>
<p class="message-copy">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
<div role="alert" class="status message submission-error">
<h3 class="message-title">The following errors occured while logging you in: </h3>
<ul class="message-copy">
<li>Your email or password is incorrect</li>
</ul>
</div>
<p class="instructions sr">
Please provide the following information to log into your edX account. Required fields are noted by <strong class="indicator">bold text and an asterisk (*)</strong>.
</p>
<fieldset class="group group-form group-form-requiredinformation">
<legend class="sr">Required Information</legend>
<ol class="list-input">
<li class="field required text" id="field-email">
<label for="email">E-mail</label>
<input class="" id="email" type="email" name="email" value="" placeholder="example: username@domain.com" />
</li>
<li class="field required password" id="field-password">
<label for="password">Password</label>
<input id="password" type="password" name="password" value="" />
<span class="tip tip-input">
<a href="#forgot-password-modal" rel="leanModal" class="pwd-reset action action-forgotpw">Forgot password?</a>
</span>
</li>
</ol>
</fieldset>
<fieldset class="group group-form group-form-secondary group-form-accountpreferences">
<legend class="sr">Account Preferences</legend>
<ol class="list-input">
<li class="field required checkbox" id="field-remember">
<input id="remember-yes" type="checkbox" name="remember" value="true" />
<label for="remember-yes">Remember me</label>
</li>
</ol>
</fieldset>
% if course_id and enrollment_action:
<input type="hidden" name="enrollment_action" value="${enrollment_action | h}" />
<input type="hidden" name="course_id" value="${course_id | h}" />
% endif
<div class="form-actions">
<button name="submit" type="submit" id="submit" class="action action-primary action-update"></button>
</div>
</form>
</section>
<aside role="complementary">
<header>
<h2 class="sr">Helpful Information</h2>
</header>
% if settings.MITX_FEATURES.get('AUTH_USE_OPENID'):
<!-- <div class="cta cta-login-options-openid">
<h3>Login via OpenID</h3>
<p>You can now start learning with edX by logging in with your <a rel="external" href="http://openid.net/">OpenID account</a>.</p>
<a class="action action-login-openid" href="#">Login via OpenID</a>
</div> -->
% endif
<div class="cta cta-help">
<h3>Not Enrolled?</h3>
<p><a href="${reverse('register_user')}">Sign up for edX today!</a></p>
<h3>Need Help?</h3>
<p>Looking for help in logging in or with your edX account?
<a href="${marketing_link('FAQ')}">
View our help section for answers to commonly asked questions.
</a></p>
</div>
</aside>
</section>
<%namespace name='static' file='static_content.html'/>
<%! from django.utils import html %>
<!DOCTYPE html>
<html>
<head>
<%block name="title"><title>edX</title></%block>
<script type="text/javascript">
/* immediately break out of an iframe if coming
from the marketing website */
(function(window) {
if (window.location !== window.top.location) {
window.top.location = window.location;
}
})(this);
</script>
<link rel="icon" type="image/x-icon" href="${static.url('images/favicon.ico')}" />
......@@ -48,3 +58,10 @@
<%block name="js_extra"/>
</body>
</html>
<%def name="login_query()">${
"?course_id={0}&enrollment_action={1}".format(
html.escape(course_id),
html.escape(enrollment_action)
) if course_id and enrollment_action else ""
}</%def>
<%namespace name='static' file='static_content.html'/>
<!DOCTYPE html>
<html>
<head>
<%block name="title"></%block>
<link rel="icon" type="image/x-icon" href="${static.url('images/favicon.ico')}" />
<meta name="path_prefix" content="${MITX_ROOT_URL}" />
<meta name="google-site-verification" content="_mipQ4AtZQDNmbtOkwehQDOgCxUUV2fb_C0b6wbiRHY" />
<%static:css group='application'/>
<%static:js group='main_vendor'/>
<!--[if IE]>
<script src="${static.url('js/html5shiv.js')}"></script>
<![endif]-->
<!--[if lte IE 9]>
<%static:css group='ie-fixes'/>
<![endif]-->
<%block name="headextra"/>
% if not course:
<%include file="google_analytics.html" />
% endif
<!-- repeated button styles needed for IE (copied from _shame.scss) -->
<style type="text/css" media="screen">
.view-partial-mktgregister{background:transparent}.view-partial-mktgregister .wrapper-view{overflow:hidden}.view-partial-mktgregister .btn,.view-partial-mktgregister .btn-primary,.view-partial-mktgregister .action.action-register,.view-partial-mktgregister .action.access-courseware,.view-partial-mktgregister .btn-secondary,.view-partial-mktgregister .action.is-registered,.view-partial-mktgregister .action.registration-closed,.view-partial-mktgregister .btn-tertiary,.view-partial-mktgregister .action.coming-soon{-webkit-box-sizing:"border-box";-moz-box-sizing:"border-box";box-sizing:"border-box";display:block;padding:10px;text-transform:lowercase;color:#fff;letter-spacing:0.1rem;cursor:pointer;text-align:center;border:none !important;text-decoration:none;text-shadow:none;letter-spacing:0.1rem;font-size:17px;font-weight:300;box-shadow:0 !important}.view-partial-mktgregister .btn strong,.view-partial-mktgregister .btn-primary strong,.view-partial-mktgregister .action.action-register strong,.view-partial-mktgregister .action.access-courseware strong,.view-partial-mktgregister .btn-secondary strong,.view-partial-mktgregister .action.is-registered strong,.view-partial-mktgregister .action.registration-closed strong,.view-partial-mktgregister .btn-tertiary strong,.view-partial-mktgregister .action.coming-soon strong{font-weight:400;text-transform:none}.view-partial-mktgregister .btn-primary,.view-partial-mktgregister .action.action-register,.view-partial-mktgregister .action.access-courseware{background-color:#4697ec;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(5%, #4697ec),color-stop(95%, #4880bb));background-image:-webkit-linear-gradient(#4697ec 5%,#4880bb 95%);background-image:linear-gradient(#4697ec 5%,#4880bb 95%)}.view-partial-mktgregister .btn-secondary,.view-partial-mktgregister .action.is-registered,.view-partial-mktgregister .action.registration-closed{background-color:#999;background-image:-webkit-gradient(linear, left top, left bottom, color-stop(5%, #999),color-stop(95%, #666));background-image:-webkit-linear-gradient(#999 5%,#666 95%);background-image:linear-gradient(#999 5%,#666 95%)}.view-partial-mktgregister .btn-tertiary,.view-partial-mktgregister .action.coming-soon{background:#e6f5fc;color:#5597dd}.view-partial-mktgregister .list-actions{list-style:none;margin:0;padding:0}.view-partial-mktgregister .list-actions .item{margin:0}.view-partial-mktgregister .action.is-registered,.view-partial-mktgregister .action.registration-closed{pointer-events:none !important}.view-partial-mktgregister .action.coming-soon{pointer-events:none !important;outline:none}
</style>
</head>
<body class="<%block name='bodyclass'></%block>">
<!-- view -->
<div class="wrapper wrapper-view">
<%block name="content"></%block>
</div>
<%static:js group='application'/>
<%block name="js_extra"></%block>
</body>
</html>
## mako
## TODO: Split this into two files, one for people who are authenticated, and
## one for people who aren't. Assume a Course object is passed to the former,
## instead of using settings.COURSE_TITLE
<%namespace name='static' file='static_content.html'/>
<%namespace file='main.html' import="login_query"/>
<%!
from django.core.urlresolvers import reverse
......@@ -38,19 +36,23 @@ site_status_msg = get_site_status_msg(course_id)
<header class="global" aria-label="Global Navigation">
% endif
<nav>
<h1 class="logo"><a href="${reverse('root')}"><img src="${static.url(branding.get_logo_url(request.META.get('HTTP_HOST')))}"/></a></h1>
<h1 class="logo">
<a href="${marketing_link('ROOT')}">
<img src="${static.url(branding.get_logo_url(request.META.get('HTTP_HOST')))}"/>
</a></h1>
% if course:
<h2><span class="provider">${course.org}:</span> ${course.number} ${course.display_name_with_default}</h2>
% endif
<ol class="left find-courses-button">
<li class="primary">
<a href="${reverse('courses')}">Find Courses</a>
% if user.is_authenticated():
<ol class="left nav-global authenticated">
<li class="nav-global-01">
<a href="${marketing_link('COURSES')}">Find Courses</a>
</li>
</ol>
% if user.is_authenticated():
<ol class="user">
<li class="primary">
<a href="${reverse('dashboard')}" class="user-link">
......@@ -61,30 +63,43 @@ site_status_msg = get_site_status_msg(course_id)
<li class="primary">
<a href="#" class="dropdown">&#9662</a>
<ul class="dropdown-menu">
## <li><a href="#">Account Settings</a></li>
<li><a href="${reverse('help_edx')}">Help</a></li>
<li>
<a href="${marketing_link('FAQ')}">
Help
</a></li>
<li><a href="${reverse('logout')}">Log Out</a></li>
</ul>
</li>
</ol>
% else:
<ol class="guest">
<li class="secondary">
<a href="${reverse('about_edx')}">About</a>
<a href="http://edxonline.tumblr.com/">Blog</a>
<a href="${reverse('jobs')}">Jobs</a>
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
<a href="#login-modal" id="login" rel="leanModal">Log In</a>
% endif
% else:
<ol class="left nav-global">
% if settings.MITX_FEATURES.get('ENABLE_MKTG_SITE'):
<li class="nav-global-01">
<a href="${marketing_link('HOW_IT_WORKS')}">How it Works</a>
</li>
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
<li class="primary">
<a href="#signup-modal" id="signup" rel="leanModal">Sign Up</a>
<li class="nav-global-02">
<a href="${marketing_link('COURSES')}">Courses</a>
</li>
% endif
<li class="nav-global-03">
<a href="${marketing_link('SCHOOLS')}">Schools</a>
</li>
% endif
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
<li class="nav-global-04">
<a class="cta cta-register" href="/register">Register Now</a>
</li>
% endif
</ol>
%endif
<ol class="right nav-courseware">
<li class="nav-courseware-01">
% if not settings.MITX_FEATURES['DISABLE_LOGIN_BUTTON']:
<a class="cta cta-login" href="/login${login_query()}">Log in</a>
% endif
</li>
</ol>
% endif
</nav>
</header>
% if course:
......@@ -92,8 +107,6 @@ site_status_msg = get_site_status_msg(course_id)
% endif
%if not user.is_authenticated():
<%include file="login_modal.html" />
<%include file="signup_modal.html" />
<%include file="forgot_password_modal.html" />
%endif
......
......@@ -23,7 +23,7 @@
%if user_logged_in:
Visit your <a href="${reverse('dashboard')}">dashboard</a> to see your courses.
%else:
You can now <a href="#login-modal" rel="leanModal">login</a>.
You can now <a href="${reverse('signin_user')}">log in</a>.
%endif
</p>
</section>
......
{% load i18n %}
{% load compressed %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<h1> Password reset complete </h1>
<title>Your Password Reset is Complete</title>
{% block content %}
{% compressed_css 'application' %}
Your password has been set. You may go ahead and <a href="/">log in</a> now.
<!--[if lt IE 9]>
<script src="{% static 'js/html5shiv.js' %}"></script>
<![endif]-->
{% endblock %}
<script type="text/javascript">
$(function() {
var view_name = 'view-passwordreset';
// adding js class for styling with accessibility in mind
$('body').addClass('js').addClass(view_name);
// new window/tab opening
$('a[rel="external"], a[class="new-vp"]')
.click( function() {
window.open( $(this).attr('href') );
return false;
});
// form field label styling on focus
$("form :input").focus(function() {
$("label[for='" + this.id + "']").parent().addClass("is-focused");
}).blur(function() {
$("label").parent().removeClass("is-focused");
});
});
</script>
</head>
<body class="view-passwordreset">
<header class="global">
<nav>
<h1 class="logo">
<a href="{{MKTG_URL_ROOT}}"><img src="/static/images/header-logo.png"></a>
</h1>
</nav>
</header>
<section class="content-wrapper">
<section class="passwordreset container">
<section class="introduction">
<header>
<h1>Your Password Reset is Complete</h1>
</header>
</section>
{% block content %}
<section role="main" class="content">
<p>Your password has been set. You may go ahead and <a href="/login">log in</a> now.</a>.</p>
</section>
{% endblock %}
</section>
</section>
{% load compressed %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>Reset password - MITx 6.002x</title>
<title>Reset Your edX Password</title>
{% compressed_css 'application' %}
......@@ -12,55 +12,120 @@
<script src="{% static 'js/html5shiv.js' %}"></script>
<![endif]-->
</head>
<body>
<script type="text/javascript">
$(function() {
<header class="global" aria-label="Global Navigation">
<nav>
<h1 class="logo"><a href="${reverse('root')}"></a></h1>
</nav>
</header>
var view_name = 'view-passwordreset';
{% block content %}
<section class="password-reset">
// adding js class for styling with accessibility in mind
$('body').addClass('js').addClass(view_name);
{% if validlink %}
// new window/tab opening
$('a[rel="external"], a[class="new-vp"]')
.click( function() {
window.open( $(this).attr('href') );
return false;
});
<header>
<h2>Enter new password</h2>
<hr>
</header>
// form field label styling on focus
$("form :input").focus(function() {
$("label[for='" + this.id + "']").parent().addClass("is-focused");
}).blur(function() {
$("label").parent().removeClass("is-focused");
});
});
</script>
<p>Please enter your new password twice so we can verify you typed it in correctly.</p>
<form action="" method="post">{% csrf_token %}
{{ form.new_password1.errors }}
<label for="id_new_password1">New password:</label>
{{ form.new_password1 }}
{{ form.new_password2.errors }}
<label for="id_new_password2">Confirm password:</label>
{{ form.new_password2 }}
</head>
<div class="submit">
<input type="submit" value="Change my password" />
<body class="view-passwordreset">
<header class="global">
<nav>
<h1 class="logo">
<a href="{{MKTG_URL_ROOT}}"><img src="/static/images/header-logo.png"></a>
</h1>
</nav>
</header>
<section class="content-wrapper">
<section class="passwordreset container">
<section class="introduction">
<header>
<h1>Reset Your edX Password</h1>
</header>
</section>
<section role="main" class="content">
{% if validlink %}
<header>
<h2 class="sr">Password Reset Form</h2>
</header>
<form role="form" id="passwordreset-form" method="post" data-remote="true" action="">{% csrf_token %}
<!-- status messages -->
<div role="alert" class="status message">
<h3 class="message-title">We're sorry, edX enrollment is not available in your region</h3>
<p class="message-copy">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
</div>
<div role="alert" class="status message submission-error">
<h3 class="message-title">The following errors occured while processing your registration: </h3>
<ul class="message-copy">
<li>You must complete all fields.</li>
<li>The two password fields didn't match.</li>
</ul>
</div>
<div role="alert" class="status message system-error">
<h3 class="message-title">We're sorry, our systems seem to be having trouble processing your password reset</h3>
<p class="message-copy">Someone has been made aware of this issue. Please try again shortly. Please <a href="{{MKTG_URL_CONTACT}}">contact us</a> about any concerns you have.</p>
</div>
<p class="instructions">
Please enter your new password twice so we can verify you typed it in correctly. <br />
Required fields are noted by <strong class="indicator">bold text and an asterisk (*)</strong>.
</p>
<fieldset class="group group-form group-form-requiredinformation">
<legend class="sr">Required Information</legend>
<ol class="list-input">
<li class="field required password" id="field-new_password1">
<label for="new_password1">Your New Password</label>
<input id="new_password1" type="password" name="new_password1" placeholder="*****" />
</li>
<li class="field required password" id="field-new_password2">
<label for="new_password2">Your New Password Again</label>
<input id="new_password2" type="password" name="new_password2" placeholder="*****" />
</li>
</ol>
</fieldset>
<div class="form-actions">
<button name="submit" type="submit" id="submit" class="action action-primary action-update">Change My Password</button>
</div>
</form>
{% else %}
<header>
<h2 class="sr">Your Password Reset Was Unsuccessful</h2>
</header>
<p>The password reset link was invalid, possibly because the link has already been used. Please return to the <a href="/login">login page</a> and start the password reset process again.</p>
{% endif %}
</section>
<aside role="complementary">
<header>
<h3 class="sr">Password Reset Help</h3>
</header>
<div class="cta cta-help">
<h3>Need Help?</h3>
<p>View our <a href="{{MKTG_URL_FAQ}}">help section for contact information and answers to commonly asked questions</a></p>
</div>
</form>
{% else %}
<header>
<h1>Password reset unsuccessful</h1>
<hr>
</header>
<p>The password reset link was invalid, possibly because the link has already been used. Please request a new password reset.</p>
{% endif %}
</aside>
</section>
{% endblock %}
</body>
</html>
</section>
......@@ -17,6 +17,8 @@ urlpatterns = ('', # nopep8
url(r'^update_certificate$', 'certificates.views.update_certificate'),
url(r'^$', 'branding.views.index', name="root"), # Main marketing page, or redirect to courseware
url(r'^dashboard$', 'student.views.dashboard', name="dashboard"),
url(r'^login$', 'student.views.signin_user', name="signin_user"),
url(r'^register$', 'student.views.register_user', name="register_user"),
url(r'^admin_dashboard$', 'dashboard.views.dashboard'),
......@@ -35,8 +37,8 @@ urlpatterns = ('', # nopep8
url(r'^accounts/login$', 'student.views.accounts_login', name="accounts_login"),
url(r'^login$', 'student.views.login_user', name="login"),
url(r'^login/(?P<error>[^/]*)$', 'student.views.login_user'),
url(r'^login_ajax$', 'student.views.login_user', name="login"),
url(r'^login_ajax/(?P<error>[^/]*)$', 'student.views.login_user'),
url(r'^logout$', 'student.views.logout_user', name='logout'),
url(r'^create_account$', 'student.views.create_account'),
url(r'^activate/(?P<key>[^/]*)$', 'student.views.activate_account', name="activate"),
......@@ -177,11 +179,19 @@ if settings.COURSEWARE_ENABLED:
url(r'^courses/?$', 'branding.views.courses', name="courses"),
url(r'^change_enrollment$',
'student.views.change_enrollment_view', name="change_enrollment"),
'student.views.change_enrollment', name="change_enrollment"),
#About the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$',
'courseware.views.course_about', name="about_course"),
#View for mktg site (kept for backwards compatibility TODO - remove before merge to master)
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/mktg-about$',
'courseware.views.mktg_course_about', name="mktg_about_course"),
#View for mktg site
url(r'^mktg/(?P<course_id>.*)$',
'courseware.views.mktg_course_about', name="mktg_about_course"),
#Inside the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/$',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment