Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
ecommerce
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
ecommerce
Commits
68e66025
Commit
68e66025
authored
Jul 28, 2015
by
Clinton Blackburn
Committed by
Clinton Blackburn
Aug 05, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated course detail view
- Moved view into course admin app - Updated styling XCOM-507
parent
e0c1f170
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
333 additions
and
127 deletions
+333
-127
bower.json
+2
-1
ecommerce/courses/urls.py
+0
-2
ecommerce/courses/views.py
+0
-18
ecommerce/static/js/apps/course_admin_app.js
+3
-1
ecommerce/static/js/config.js
+1
-0
ecommerce/static/js/models/course_model.js
+24
-15
ecommerce/static/js/models/course_seat_model.js
+8
-0
ecommerce/static/js/models/product_model.js
+50
-7
ecommerce/static/js/pages/course_detail_page.js
+19
-4
ecommerce/static/js/routers/course_router.js
+22
-2
ecommerce/static/js/test/specs/course_detail_view_spec.js
+116
-0
ecommerce/static/js/views/course_detail_view.js
+17
-23
ecommerce/static/sass/base/main.scss
+0
-1
ecommerce/static/sass/utilities/_variables.scss
+1
-0
ecommerce/static/sass/views/_course_admin.scss
+37
-0
ecommerce/static/sass/views/_course_detail.scss
+0
-26
ecommerce/static/templates/_course_seat.html
+8
-9
ecommerce/static/templates/course_detail.html
+25
-8
ecommerce/templates/courses/course_detail.html
+0
-10
No files found.
bower.json
View file @
68e66025
...
...
@@ -25,6 +25,7 @@
"moment"
:
"~2.10.3"
,
"underscore.string"
:
"~3.1.1"
,
"backbone-super"
:
"~1.0.4"
,
"backbone-route-filter"
:
"~0.1.2"
"backbone-route-filter"
:
"~0.1.2"
,
"backbone-relational"
:
"~0.9.0"
}
}
ecommerce/courses/urls.py
View file @
68e66025
from
django.conf.urls
import
patterns
,
url
from
ecommerce.core.constants
import
COURSE_ID_PATTERN
from
ecommerce.courses
import
views
urlpatterns
=
patterns
(
''
,
url
(
r'^migrate/$'
,
views
.
CourseMigrationView
.
as_view
(),
name
=
'migrate'
),
url
(
r'^{}/$'
.
format
(
COURSE_ID_PATTERN
),
views
.
CourseDetailView
.
as_view
(),
name
=
'detail'
),
# Declare all paths above this line to avoid dropping into the Course Admin Tool (which does its own routing)
url
(
r'^(.*)$'
,
views
.
CourseAppView
.
as_view
(),
name
=
'app'
),
...
...
ecommerce/courses/views.py
View file @
68e66025
...
...
@@ -8,8 +8,6 @@ from django.http import Http404, HttpResponse
from
django.utils.decorators
import
method_decorator
from
django.views.generic
import
View
,
TemplateView
from
ecommerce.courses.models
import
Course
logger
=
logging
.
getLogger
(
__name__
)
...
...
@@ -26,22 +24,6 @@ class CourseAppView(StaffOnlyMixin, TemplateView):
template_name
=
'courses/course_app.html'
class
CourseDetailView
(
TemplateView
):
template_name
=
'courses/course_detail.html'
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
Course
.
objects
.
filter
(
id
=
kwargs
[
'course_id'
])
.
exists
():
raise
Http404
return
super
(
CourseDetailView
,
self
)
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
CourseDetailView
,
self
)
.
get_context_data
()
context
.
update
({
'course_id'
:
kwargs
[
'course_id'
]
})
return
context
class
CourseMigrationView
(
View
):
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
is_superuser
:
...
...
ecommerce/static/js/apps/course_admin_app.js
View file @
68e66025
...
...
@@ -41,12 +41,14 @@ require([
$
(
function
()
{
var
$app
=
$
(
'#app'
);
// Let's start the show!
courseApp
=
new
CourseRouter
({
$el
:
$app
});
courseApp
.
start
();
// Handle navbar clicks.
$
(
'a.navbar-brand'
).
on
(
'click'
,
navigate
);
// Handle internal clicks
$app
.
on
(
'click'
,
'a'
,
navigate
);
});
}
);
ecommerce/static/js/config.js
View file @
68e66025
...
...
@@ -3,6 +3,7 @@ require.config({
paths
:
{
'backbone'
:
'bower_components/backbone/backbone'
,
'backbone.paginator'
:
'bower_components/backbone.paginator/lib/backbone.paginator'
,
'backbone.relational'
:
'bower_components/backbone-relational/backbone-relational'
,
'backbone.route-filter'
:
'bower_components/backbone-route-filter/backbone-route-filter'
,
'backbone.super'
:
'bower_components/backbone-super/backbone-super/backbone-super'
,
'bootstrap'
:
'bower_components/bootstrap-sass/assets/javascripts/bootstrap'
,
...
...
ecommerce/static/js/models/course_model.js
View file @
68e66025
define
([
'backbone'
,
'backbone.relational'
,
'underscore'
,
'collections/product_collection'
,
'models/course_seat_model'
],
function
(
Backbone
,
BackboneRelational
,
_
,
ProductCollection
,
CourseSeatModel
)
{
'use strict'
;
return
Backbone
.
Model
.
extend
({
return
Backbone
.
Relational
Model
.
extend
({
urlRoot
:
'/api/v2/courses/'
,
defaults
:
{
name
:
''
id
:
null
,
name
:
null
,
type
:
null
},
getProducts
:
function
()
{
if
(
_
.
isUndefined
(
this
.
_products
))
{
this
.
_products
=
new
ProductCollection
();
this
.
_products
.
url
=
this
.
get
(
'products_url'
);
return
this
.
_products
.
getFirstPage
({
fetch
:
true
});
}
return
this
.
_products
;
},
relations
:
[{
type
:
Backbone
.
HasMany
,
key
:
'products'
,
relatedModel
:
CourseSeatModel
,
includeInJSON
:
false
,
parse
:
true
}],
getSeats
:
function
()
{
// Returns the seat products
return
this
.
getProducts
().
filter
(
function
(
product
)
{
// Filter out parent products since there is no need to display or modify.
return
(
product
instanceof
CourseSeatModel
)
&&
product
.
get
(
'structure'
)
!==
'parent'
;
});
var
seats
=
this
.
get
(
'products'
).
filter
(
function
(
product
)
{
// Filter out parent products since there is no need to display or modify.
return
(
product
instanceof
CourseSeatModel
)
&&
product
.
get
(
'structure'
)
!==
'parent'
;
}),
seatTypes
=
_
.
map
(
seats
,
function
(
seat
)
{
return
seat
.
get
(
'certificate_type'
);
});
return
_
.
object
(
seatTypes
,
seats
);
}
});
}
...
...
ecommerce/static/js/models/course_seat_model.js
View file @
68e66025
...
...
@@ -5,6 +5,14 @@ define([
'use strict'
;
return
ProductModel
.
extend
({
defaults
:
{
certificate_type
:
null
,
expires
:
null
,
id_verification_required
:
null
,
price
:
null
,
product_class
:
'Seat'
},
getSeatType
:
function
()
{
switch
(
this
.
get
(
'certificate_type'
))
{
case
'verified'
:
...
...
ecommerce/static/js/models/product_model.js
View file @
68e66025
define
([
'backbone'
'backbone'
,
'backbone.relational'
,
'moment'
,
'underscore'
],
function
(
Backbone
)
{
function
(
Backbone
,
BackboneRelational
,
moment
,
_
)
{
'use strict'
;
return
Backbone
.
Model
.
extend
({
return
Backbone
.
Relational
Model
.
extend
({
urlRoot
:
'/api/v2/products/'
,
nestedAttributes
:
[
'certificate_type'
,
'id_verification_required'
,
'course_key'
],
initialize
:
function
()
{
// Expose the nested attribute values as top-level attributes on the model
this
.
get
(
'attribute_values'
).
forEach
(
function
(
av
)
{
this
.
set
(
av
.
name
,
av
.
value
);
parse
:
function
(
response
)
{
// Un-nest the attributes
_
.
each
(
response
.
attribute_values
,
function
(
data
)
{
this
.
nestedAttributes
.
push
(
data
.
name
);
response
[
data
.
name
]
=
data
.
value
;
},
this
);
delete
response
.
attribute_values
;
// The view displaying the expires value assumes times are in the user's local timezone. We want all
// times to be displayed in UTC to avoid confusion. Strip the timezone data to workaround the UI
// deficiencies. We will restore the UTC timezone in toJSON().
if
(
response
.
expires
)
{
response
.
expires
=
moment
.
utc
(
response
.
expires
).
format
(
'YYYY-MM-DDTHH:mm:ss'
);
}
return
response
;
},
toJSON
:
function
()
{
var
data
=
_
.
clone
(
this
.
attributes
);
data
.
attribute_values
=
[];
// Re-nest the attributes
_
.
each
(
_
.
uniq
(
this
.
nestedAttributes
),
function
(
attribute
)
{
if
(
this
.
has
(
attribute
))
{
data
.
attribute_values
.
push
({
name
:
attribute
,
value
:
this
.
get
(
attribute
)
});
delete
data
[
attribute
];
}
},
this
);
// Restore the timezone component, and output the ISO 8601 format expected by the server.
if
(
data
.
expires
)
{
data
.
expires
=
moment
.
utc
(
data
.
expires
+
'Z'
).
format
();
}
return
data
;
}
});
}
...
...
ecommerce/static/js/pages/course_detail_page.js
View file @
68e66025
require
([
'views/course_detail_view'
define
([
'models/course_model'
,
'views/course_detail_view'
,
'pages/page'
],
function
(
CourseDetailView
)
{
function
(
Course
,
CourseDetailView
,
Page
)
{
'use strict'
;
new
CourseDetailView
();
return
Page
.
extend
({
title
:
function
()
{
return
this
.
model
.
get
(
'name'
)
+
' - '
+
gettext
(
'View Course'
);
},
initialize
:
function
(
options
)
{
this
.
model
=
Course
.
findOrCreate
({
id
:
options
.
id
});
this
.
view
=
new
CourseDetailView
({
model
:
this
.
model
});
this
.
listenTo
(
this
.
model
,
'change sync'
,
this
.
render
);
this
.
model
.
fetch
({
data
:
{
include_products
:
true
}});
}
});
}
);
ecommerce/static/js/routers/course_router.js
View file @
68e66025
define
([
'backbone'
,
'backbone.route-filter'
,
'backbone.super'
,
'pages/course_list_page'
'pages/course_list_page'
,
'pages/course_detail_page'
],
function
(
Backbone
,
BackboneRouteFilter
,
BackboneSuper
,
CourseListPage
)
{
CourseListPage
,
CourseDetailPage
)
{
'use strict'
;
return
Backbone
.
Router
.
extend
({
...
...
@@ -33,8 +37,13 @@ define([
* refers to a jQuery Element where the pages will be rendered.
*/
initialize
:
function
(
options
)
{
var
courseIdRegex
=
/
([^/
+
]
+
(\/
|
\+)[^/
+
]
+
(\/
|
\+)[^/]
+
)
/
;
// This is where views will be rendered
this
.
$el
=
options
.
$el
;
// Custom routes, requiring RegExp or other complex placeholders, should be defined here
this
.
route
(
new
RegExp
(
'^'
+
courseIdRegex
.
source
+
'(
\
/)?$'
),
'show'
);
},
/**
...
...
@@ -73,6 +82,17 @@ define([
var
page
=
new
CourseListPage
();
this
.
currentView
=
page
;
this
.
$el
.
html
(
page
.
el
);
},
/**
* Display details for a single course.
* @param {String} id - ID of the course to display.
*/
show
:
function
(
id
)
{
var
page
=
new
CourseDetailPage
({
id
:
id
});
this
.
currentView
=
page
;
this
.
$el
.
html
(
page
.
el
);
}
});
}
...
...
ecommerce/static/js/test/specs/course_detail_view_spec.js
0 → 100644
View file @
68e66025
define
([
'jquery'
,
'underscore.string'
,
'views/course_detail_view'
,
'models/course_model'
],
function
(
$
,
_s
,
CourseDetailView
,
Course
)
{
'use strict'
;
describe
(
'course detail view'
,
function
()
{
var
view
,
model
,
data
=
{
id
:
'edX/DemoX/Demo_Course'
,
url
:
'http://ecommerce.local:8002/api/v2/courses/edX/DemoX/Demo_Course/'
,
name
:
'edX Demonstration Course'
,
verification_deadline
:
null
,
type
:
'verified'
,
products_url
:
'http://ecommerce.local:8002/api/v2/courses/edX/DemoX/Demo_Course/products/'
,
last_edited
:
'2015-07-27T00:27:23Z'
,
products
:
[
{
id
:
9
,
url
:
'http://ecommerce.local:8002/api/v2/products/9/'
,
structure
:
'child'
,
product_class
:
'Seat'
,
title
:
'Seat in edX Demonstration Course with honor certificate'
,
price
:
'0.00'
,
expires
:
null
,
attribute_values
:
[
{
name
:
'certificate_type'
,
value
:
'honor'
},
{
name
:
'course_key'
,
value
:
'edX/DemoX/Demo_Course'
},
{
name
:
'id_verification_required'
,
value
:
false
}
],
is_available_to_buy
:
true
},
{
id
:
8
,
url
:
'http://ecommerce.local:8002/api/v2/products/8/'
,
structure
:
'child'
,
product_class
:
'Seat'
,
title
:
'Seat in edX Demonstration Course with verified certificate (and ID verification)'
,
price
:
'15.00'
,
expires
:
null
,
attribute_values
:
[
{
name
:
'certificate_type'
,
value
:
'verified'
},
{
name
:
'course_key'
,
value
:
'edX/DemoX/Demo_Course'
},
{
name
:
'id_verification_required'
,
value
:
true
}
],
is_available_to_buy
:
true
},
{
id
:
7
,
url
:
'http://ecommerce.local:8002/api/v2/products/7/'
,
structure
:
'parent'
,
product_class
:
'Seat'
,
title
:
'Seat in edX Demonstration Course'
,
price
:
null
,
expires
:
null
,
attribute_values
:
[
{
name
:
'course_key'
,
value
:
'edX/DemoX/Demo_Course'
}
],
is_available_to_buy
:
false
}
]
};
beforeEach
(
function
()
{
model
=
Course
.
findOrCreate
(
data
,
{
parse
:
true
});
view
=
new
CourseDetailView
({
model
:
model
}).
render
();
});
it
(
'should display course details'
,
function
()
{
expect
(
view
.
$el
.
find
(
'.course-name'
).
text
()).
toEqual
(
model
.
get
(
'name'
));
expect
(
view
.
$el
.
find
(
'.course-id'
).
text
()).
toEqual
(
model
.
get
(
'id'
));
expect
(
view
.
$el
.
find
(
'.course-type'
).
text
()).
toEqual
(
_s
.
capitalize
(
model
.
get
(
'type'
)));
expect
(
view
.
$el
.
find
(
'.course-verification-deadline'
).
length
).
toEqual
(
0
);
});
it
(
'should list the course seats'
,
function
()
{
var
$seats
=
view
.
$el
.
find
(
'.course-seat'
),
products
=
_
.
filter
(
data
.
products
,
function
(
product
)
{
return
product
.
product_class
===
'Seat'
&&
product
.
structure
===
'child'
;
});
expect
(
$seats
.
length
).
toEqual
(
products
.
length
);
// TODO Verify the rendered info matches the data
});
});
}
);
ecommerce/static/js/views/course_detail_view.js
View file @
68e66025
...
...
@@ -4,7 +4,6 @@ define([
'underscore'
,
'underscore.string'
,
'moment'
,
'models/course_model'
,
'text!templates/course_detail.html'
,
'text!templates/_course_seat.html'
],
...
...
@@ -13,27 +12,15 @@ define([
_
,
_s
,
moment
,
CourseModel
,
CourseDetailTemplate
,
CourseSeatTemplate
)
{
'use strict'
;
return
Backbone
.
View
.
extend
({
el
:
'.
course-detail-view'
,
className
:
'
course-detail-view'
,
initialize
:
function
()
{
var
self
=
this
,
course_id
=
self
.
$el
.
data
(
'course-id'
);
this
.
course
=
new
CourseModel
({
id
:
course_id
});
this
.
course
.
fetch
({
success
:
function
(
course
)
{
self
.
render
();
course
.
getProducts
().
done
(
function
()
{
self
.
renderSeats
();
});
}
});
this
.
listenTo
(
this
.
model
,
'change'
,
this
.
render
);
},
getSeats
:
function
()
{
...
...
@@ -43,7 +30,8 @@ define([
'honor'
,
'verified'
,
'no-id-professional'
,
'professional'
,
'credit'
])));
seats
=
_
.
sortBy
(
this
.
course
.
getSeats
(),
function
(
seat
)
{
seats
=
_
.
values
(
this
.
model
.
getSeats
());
seats
=
_
.
sortBy
(
seats
,
function
(
seat
)
{
return
sortObj
[
seat
.
get
(
'certificate_type'
)]
});
...
...
@@ -51,27 +39,33 @@ define([
},
render
:
function
()
{
var
html
,
templateData
;
document
.
title
=
this
.
course
.
get
(
'name'
)
+
' - '
+
gettext
(
'View Course'
);
var
html
,
verifcationDeadline
=
this
.
model
.
get
(
'verification_deadline'
),
templateData
;
templateData
=
{
course
:
this
.
course
.
attributes
,
courseType
:
_s
.
capitalize
(
this
.
course
.
get
(
'type'
))
course
:
this
.
model
.
attributes
,
courseType
:
_s
.
capitalize
(
this
.
model
.
get
(
'type'
)),
verificationDeadline
:
verifcationDeadline
?
moment
.
utc
(
verifcationDeadline
).
format
(
'lll z'
)
:
null
};
html
=
_
.
template
(
CourseDetailTemplate
)(
templateData
);
this
.
$el
.
html
(
html
)
this
.
$el
.
html
(
html
);
this
.
renderSeats
();
return
this
;
},
renderSeats
:
function
()
{
var
html
=
''
,
$seatHolder
=
$
(
'.course-seats'
,
this
.
$el
);
this
.
getSeats
().
forEach
(
function
(
seat
)
{
_
.
each
(
this
.
getSeats
(),
function
(
seat
)
{
html
+=
_
.
template
(
CourseSeatTemplate
)({
seat
:
seat
,
moment
:
moment
});
});
$seatHolder
.
append
(
html
);
$seatHolder
.
html
(
html
);
}
});
}
...
...
ecommerce/static/sass/base/main.scss
View file @
68e66025
...
...
@@ -30,4 +30,3 @@
// --------------------
@import
'../views/credit'
;
@import
'../views/course_admin'
;
@import
'../views/course_detail'
;
ecommerce/static/sass/utilities/_variables.scss
View file @
68e66025
...
...
@@ -35,3 +35,4 @@ $footer-margin: $footer-height;
// Miscellaneous
$container-bg
:
white
;
$breadcrumb-bg
:
white
;
ecommerce/static/sass/views/_course_admin.scss
View file @
68e66025
...
...
@@ -10,4 +10,41 @@
font-weight
:
bold
;
}
}
.breadcrumb
{
background-color
:
$breadcrumb-bg
;
padding-left
:
0
;
margin-top
:
spacing-vertical
(
small
);
}
.course-detail-view
{
.page-header
{
margin-top
:
0
;
}
.course-information
{
margin-bottom
:
spacing-vertical
(
small
);
.info-item
{
margin-bottom
:
10px
;
.heading
{
font-weight
:
bold
;
}
}
}
.course-seats
{
.course-seat
{
margin-bottom
:
spacing-vertical
(
mid-small
);
.seat-type
{
margin-bottom
:
5px
;
border-bottom
:
1px
solid
$page-header-border-color
;
padding-bottom
:
3px
;
font-weight
:
bold
;
}
}
}
}
}
ecommerce/static/sass/views/_course_detail.scss
deleted
100644 → 0
View file @
e0c1f170
.course-detail-view
{
.course-information
{
margin-bottom
:
spacing-vertical
(
small
);
.heading
{
font-weight
:
bold
;
}
.course-id
{
margin-bottom
:
spacing-vertical
(
x-small
);
}
}
.course-seats
{
.course-seat
{
margin-bottom
:
spacing-vertical
(
small
);
.seat-type
{
font-weight
:
bold
;
}
.seat-certificate-type
{
}
}
}
}
ecommerce/static/templates/_course_seat.html
View file @
68e66025
<div
class=
"row course-seat"
>
<div
class=
"col-
md-4
"
>
<div
class=
"col-
sm-12
"
>
<div
class=
"seat-type"
><
%=
seat
.
getSeatType
()
%
></div>
<
%
if
(
seat
.
get
('
price
'))
{
%
>
<div
class=
"seat-price"
><
%=
gettext
('
Price:
')
+
'
$'
+
seat
.
get
('
price
')
%
></div>
<
%
}
%
>
</div>
<div
class=
"col-md-4 seat-certificate-type"
>
<i
class=
"fa fa-check-square-o"
></i>
<
%=
seat
.
getCertificateDisplayName
()
%
>
</div>
<div
class=
"col-md-4 seat-additional-info"
>
<div
class=
"col-sm-4"
>
<div
class=
"seat-price"
><
%=
gettext
('
Price:
')
+
'
$'
+
Number
(
seat
.
get
('
price
')).
toLocaleString
()
%
></div>
<
%
var
expires =
seat.get('expires');
if
(
expires
)
{
print
(
gettext
('
Verification
Close:
')
+
'
'
+
moment
(
expires
).
format
('
LLL
Z
'));
print
(
gettext
('
Upgrade
Deadline:
')
+
'
'
+
moment
.
utc
(
expires
).
format
('
lll
z
'));
}
%
>
</div>
<div
class=
"col-sm-4 seat-certificate-type"
>
<
%=
seat
.
getCertificateDisplayName
()
%
>
</div>
<div
class=
"col-sm-4 seat-additional-info"
></div>
</div>
ecommerce/static/templates/course_detail.html
View file @
68e66025
<div
class=
"container"
>
<ol
class=
"breadcrumb"
>
<li><a
href=
"/courses/"
><
%=
gettext
('
Courses
')
%
></a></li>
<li
class=
"active"
><
%=
course
['
name
']
%
></li>
</ol>
<div
class=
"page-header"
>
<h1
class=
"hd-1 emphasized"
>
<
%=
gettext
('
View
Course
')
%
>
<span
class=
"course-name"
><
%=
course
['
name
']
%
></span>
<div
class=
"pull-right"
>
<button
class=
"btn btn-primary btn-small"
><
%=
gettext
('
Edit
Course
')
%
></button>
<a
class=
"btn btn-primary btn-small"
href=
"/courses/<%= course['id'] %>/edit/"
>
<
%=
gettext
('
Edit
Course
')
%
>
</a>
</div>
</h1>
</div>
<div
class=
"course-information"
>
<h3
class=
"hd-3"
><
%=
gettext
('
Course
Information
')
%
></h3>
<h3
class=
"hd-3
de-emphasized
"
><
%=
gettext
('
Course
Information
')
%
></h3>
<div
class=
"heading course-name"
><
%=
course
['
name
']
%
></div>
<div
class=
"course-id"
><
%=
course
['
id
']
%
></div>
<div
class=
"info-item"
>
<div
class=
"heading"
><
%=
gettext
('
Course
ID
')
%
></div>
<div
class=
"course-id"
><
%=
course
['
id
']
%
></div>
</div>
<div
class=
"info-item"
>
<div
class=
"heading"
><
%=
gettext
('
Course
Type
')
%
></div>
<div
class=
"course-type"
><
%=
courseType
%
></div>
</div>
<div
class=
"heading"
><
%=
gettext
('
Course
Type
')
%
></div>
<div
class=
"course-type"
><
%=
courseType
%
></div>
<
%
if
(
verificationDeadline
)
{
%
>
<div
class=
"info-item"
>
<div
class=
"heading"
><
%=
gettext
('
Verification
Deadline
')
%
></div>
<div
class=
"course-verification-deadline"
><
%=
verificationDeadline
%
></div>
</div>
<
%
}
%
>
</div>
<h3
class=
"hd-3"
><
%=
gettext
('
Course
Seats
')
%
></h3>
<h3
class=
"hd-3
de-emphasized
"
><
%=
gettext
('
Course
Seats
')
%
></h3>
<div
class=
"course-seats"
></div>
</div>
ecommerce/templates/courses/course_detail.html
deleted
100644 → 0
View file @
e0c1f170
{% extends 'edx/base.html' %}
{% load staticfiles %}
{% block content %}
<div
class=
"course-detail-view"
data-course-id=
"{{ course_id }}"
></div>
{% endblock %}
{% block javascript %}
<script
src=
"{% static 'js/pages/course_detail_page.js' %}"
></script>
{% endblock %}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment