Skip to content

Instantly share code, notes, and snippets.

@webhat
Created August 27, 2015 09:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save webhat/e06f00eb480233270ffc to your computer and use it in GitHub Desktop.
Save webhat/e06f00eb480233270ffc to your computer and use it in GitHub Desktop.
Oplerno Edit Page
%div{ ng: { controller: 'TopBarController' } }
%div{ scroll: { position: 'scroll' }, ng: { class: '{smallTopbar: scroll > 50}' }, id: 'topbar' }
%a(href="/")
#logo
#search
%form(action= 'https://enroll.oplerno.com/searches' accept-charset='UTF-8' target='_new' method='post')
%input(type='text' placeholder='I want to learn ...' name='search[term]')
%input(type='hidden')
%ul#left-menu
%li.menu-item{ ng: { show: 'menu_item'} } Courses
%li.menu-item{ ng: { show: 'menu_item' } } Instructors
%ul#right-menu
%li.menu-item{ ng: { show: 'menu_item' } } Canvas
%li.menu-item{ ng: { show: 'menu_item' } } About
%button#cart{ ng: { controller: 'CartButtonController' } }
.cart-number {{items}}
.glyphicon.glyphicon-shopping-cart
.cart-price ${{price}}
#top-bar-overflow
#alert-bar
/%h3.hidden-md.hidden-sm.hidden-xs LG
/%h3.hidden-lg.hidden-sm.hidden-xs MD
/%h3.hidden-lg.hidden-md.hidden-xs SM
/%h3.hidden-lg.hidden-md.hidden-sm XS
%div{ ng: { controller: 'CoursesController' }, id: 'angular_courses_list' }
.course{ ng: { repeat: 'course in courses() track by $index' } }
.course.vevent.h-event.row(itemscope="" itemtype="http://schema.org/Event")
.course_icon.col-sm-4.col-xs-12(style=" ")
%a(href="https://enroll.oplerno.com/courses/{{ course.slug }}" class="url")
.course_image(itemprop="image" back-img="https://enroll.oplerno.com/dynamic/courses/avatars/000/000/{{ ('000' + course.id).substr(-3) }}/medium/{{ course.avatar_file_name }}")
.course_right.col-sm-8.col-xs-12
.course_body
%h2
%a(href="https://enroll.oplerno.com/courses/{{ course.slug }}" class="url")
%input.course_title.summary.p-name.editable{ ng: { blur: "saveShelf(course, 'name', $event)", click:"editShelf(course)", value: 'course.name' }, itemprop: "name" }
.description
.course_description.hidden-xs.summary.e-description.description(ng-bind-html-unsafe="html" itemprop="description")
{{ course.description.stripHTML().trunc(500,true) }}
.course_button.top20.row
.col-lg-10.col-md-9.hidden-sm.col-xs-6
%form(class='wrapper')
%input{class:"btn btn-success oplerno-cta btn-lg", type:"submit", value:"Enroll" }
.col-lg-2.col-md-3.col-sm-4.col-xs-6{ng:{controller: 'CartFormController'}}
%form(class='wrapper' ng-submit='clickToOpen()')
%input{class:"btn btn-success oplerno-cta btn-lg", type:"submit", value:"More info" }
%input{name:'course', type:'hidden', value:'{{ course.id }}', ng: { init: 'formData.course=course.id', model: 'formData.course' } }
%input{name:'authenticity_token', type:'hidden', ng: { init: "formData.authenticity_token='x'", model: 'formData.authenticity_token' } }
.col-md-push-2.col-md-7.col-sm-8.hidden-xs
.time-ago
%time-ago(from-time='{{ course.start_date }}T00:00:00Z')
.col-sm-push-1.col-md-push-1.col-md-5.col-sm-6.hidden-xs
%h2.course-price.top10
%small
%strike
$ {{ course.price + 20 }}
%a.price_info{ data:{ toggle:'tooltip', placement:'bottom' }, title:'Due to the success of our crowdfunding campaign we are able to offer these seats for the first year without a sign up fee'} *
%div(style='inline-block') $
.editable{ ng: { blur: "saveShelf(course, 'price', $event)", click:"editShelf(course)" }} {{ course.price}}
%hr
%div{ ng: { controller: 'CoursesController' }, id: 'angular_courses_list' }
.course{ ng: { repeat: 'course in courses() track by $index' } }
.description
.editable.course_description.hidden-xs.summary.e-description.description{ ng: { blur: "saveShelf(course, 'description', $event)", click:"editShelf(course)",
bind: { html: "course.description" } }, itemprop: "description", contenteditable: 'true' }
'use strict'
bootstrapAngular = ->
angular.bootstrap(document.body, ['coursesApp'])
window.coursesApp =
angular
.module 'coursesApp', ['ngResource',
'ngSanitize',
'yaru22.angular-timeago',
'ngDialog'], ->
console.log 'Angular Course Module'
.factory 'CoursesIO', [ '$resource', ($resource) ->
args = {}
methods =
query:
method: 'GET',
isArray: true
update:
method: 'PUT'
CoursesIO = $resource 'https://enroll.oplerno.com/courses/introduction-to-existentialism.json', args, methods
return CoursesIO
]
.service 'CoursesModel', [ 'CoursesIO', 'timeAgo', (CoursesIO, timeAgo) ->
timeAgo.settings.allowFuture = true
CoursesSession = ->
this.data = {}
this.created = Date.NOW
CoursesSession.prototype.fetch = (query) ->
self = this
CoursesIO.query query, (result) ->
console.log "called get"
self.data = result
console.log result.result
new CoursesSession()
]
.controller 'CoursesController', ['$scope', 'CoursesIO', 'CoursesModel', '$http', '$compile', ($scope, CoursesIO, CoursesModel, $http, $compile) ->
console.log 'Angular Courses'
$scope.editShelf = (course) ->
course.edit = true
$scope.saveShelf = (course, field, $event) ->
course.edit = false
course[field] = (
if typeof course[field] == 'number'
parseInt($event.target.innerText)
else
$event.target.innerHTML
)
$scope.courses_list = [course]
console.log 'send trans'
angular.element(document.getElementById('angular_courses_list'))
console.log CoursesModel
$scope.courses_list = CoursesModel.fetch()
$scope.courses = ->
#$('[data-toggle="tooltip"]').tooltip()
$scope.courses_list
0 # DON'T REMOVE
]
.controller 'TopBarController', [ '$scope', '$http', '$compile', ($scope, $http, $compile) ->
console.log 'Angular TopBar'
$scope.scroll = 0
$scope.menu_item = true
]
.directive 'backImg', ->
console.log 'Directive'
return (scope, element, attrs) ->
if attrs.backImg.lastIndexOf('/') == attrs.backImg.length-1
attrs.backImg += '../../../../../../../../assets/medium/missing.png'
url = 'url('
url += attrs.backImg
url += ')'
style =
'background-image': url
element.css(style)
.directive 'scrollPosition', ($window) ->
console.log('directive')
return {
scope: {
scroll: '=scrollPosition'
},
link: (scope, element, attrs) ->
handler = ->
scope.scroll = document.body.scrollTop
angular.element($window).on('scroll', scope.$apply.bind(scope, handler ))
handler()
}
.controller 'CartFormController', [ '$scope', '$http', 'ngDialog', ($scope, $http, ngDialog) ->
$scope.formData =
course : '',
authenticity_token : ''
$scope.clickToOpen = ->
request =
method : 'POST',
url : '/carts/',
data : $.param($scope.formData)
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
$http(request).success (data) ->
$scope.message = ''
ngDialog.open({ template: 'putInCartDialog', scope: $scope })
.error ->
console.log 'Error'
$scope.message = 'NOT'
ngDialog.open({ template: 'putInCartDialog', scope: $scope })
]
.factory 'CartIO', [ '$resource', ($resource) ->
args = {}
methods =
query:
method: 'GET',
isArray: true
CartIO = $resource 'https://enroll.oplerno.com/carts/mycart.json', args, methods
return CartIO
]
.service 'CartModel', [ 'CartIO', 'timeAgo', (CartIO, timeAgo) ->
timeAgo.settings.allowFuture = true
CartSession = ->
this.data = {}
this.created = Date.NOW
CartSession.prototype.fetch = (query) ->
self = this
CartIO.query query, (result) ->
console.log "called get"
self.data = result
console.log result.result
new CartSession()
]
.controller 'CartButtonController', ['$scope', 'CartModel', ($scope, CartModel) ->
$scope.cart = CartModel.fetch()
$scope.items = $scope.cart.length
$scope.price = $scope.cart.sum (item) -> item.price
]
String.prototype.trunc = String.prototype.trunc || (n, useWord) ->
toLong = this.length>n
s_ = if toLong then this.substr(0,n-1) else this
s_ = if useWord && toLong then s_.substr(0,s_.lastIndexOf(' ')) else s_
if toLong then s_ + '...' else s_
String.prototype.stripHTML = String.prototype.stripHTML || ->
this.replace(/<[^>]+>/gm, '').replace(/&[^;]+;/gm, '')
Array::sum = (fn = (x) -> x) ->
@reduce ((a, b) -> a + fn b), 0
bootstrapAngular()
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-resource.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-route.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-sanitize.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.3.12/js/ngDialog.min.js"></script>
<script src="//rawgit.com/yaru22/angular-timeago/master/src/timeAgo.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-animate.js"></script>
$break-min: 320px;
$break-small: 768px;
$break-medium: 1024px;
$break-large: 1440px;
$icon-size: 256px;
@mixin respond-to($media) {
@if $media == mini {
@media only screen and (max-width: $break-min) { @content; }
}
@if $media == handhelds {
@media only screen and (min-width: $break-min + 1) and (max-width: $break-small) { @content; }
}
@else if $media == small-screens {
@media only screen and (min-width: $break-small + 1) and (max-width: $break-medium - 1) { @content; }
}
@else if $media == medium-screens {
@media only screen and (min-width: $break-medium + 1) and (max-width: $break-large - 1) { @content; }
}
@else if $media == wide-screens {
@media only screen and (min-width: $break-large) { @content; }
}
}
@mixin animate{
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
-o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
}
#topbar, #topbar * {
@include animate;
z-index: 10;
}
#top-bar-overflow {
@include respond-to(mini) {
height: 50px;
}
@include respond-to(handhelds) {
height: 50px;
}
@include respond-to(small-screens) {
height: 100px;
}
@include respond-to(medium-screens) {
height: 100px;
}
@include respond-to(wide-screens) {
height: 100px;
}
}
.course {
@include respond-to(mini) {
width: $break-min;
}
@include respond-to(handhelds) {
max-width: $break-min;
}
@include respond-to(small-screens) {
max-width: $break-small;
//color: red !important;
display: block !important;
}
.course_icon {
width: $icon-size !important;
height: $icon-size !important;
padding: 0 0 0 0;
@include respond-to(handhelds) {
margin-left: ($break-min/7)
}
.course_image {
width: $icon-size;
height: $icon-size;
background-size:auto 256px;
}
}
.course_right {
@include respond-to(handhelds) {
margin-left: 30px;
}
}
.course_title {
color: black;
font-family: Verdana-Bold;
font-size: 24px;
color: #262626;
line-height: 29px;
text-align: center;
width: 100%;
}
.oplerno-cta {
width: 112px;
background: #C0DC86;
border: 1px solid #979797;
box-shadow: 0px 1px 2px 0px #1D4975, inset 0px 2px 0px 0px #FFFFFF;
border-radius: 6px;
font-family: AvenirNext-Heavy;
font-size: 14.66px;
color: #1D4975;
line-height: 20px;
text-shadow: -1px -1px 0px rgba(255,254,255,0.50);
}
.time-ago {
font-family: Verdana-Bold;
font-size: 24px;
color: #262626;
line-height: 29px;
}
}
#angular_courses_list {
overflow-y: scroll;
overflow-x: hidden;
@include respond-to(mini) {
width: $break-min;
}
@include respond-to(handhelds) {
min-width: $break-min;
max-width: $break-small;
}
@include respond-to(small-screens) {
min-width: $break-small;
max-width: $break-medium;
}
@include respond-to(medium-screens) {
min-width: $break-medium;
max-width: $break-large;
}
min-width: $break-large;
}
#alert-bar {}
.smallTopbar {
@include animate;
height: 50px !important;
#left-menu, #right-menu {
position: absolute;
top: -100px !important;
}
.menu-item {
display: none;
}
a #logo {
background-size: 50px 50px !important;
height: 50px !important;
width: 50px !important;
}
button#cart {
top: 7px !important;
right: 8px !important;
}
#search form input {
@include animate;
position: absolute;
top: 10px;
left: 61px;
width: 45%;
}
}
#topbar {
position: fixed;
width: 100%;
@include respond-to(mini) {
height: 50px;
}
@include respond-to(handhelds) {
height: 50px;
}
height: 100px;
background: #C0DC86;
border: 0px;
#logo {
background-image: url(https://enroll.oplerno.com/assets/OplernoLogoLarge.png);
@include respond-to(handhelds) {
background-size: 50px 50px;
height: 50px;
width: 50px;
}
@include respond-to(mini) {
background-size: 50px 50px;
height: 50px;
width: 50px;
}
background-size: 100px 100px;
height: 100px;
width: 100px;
background-color: rgba(0,0,0,0.1);
background-position: 0px 0px;
display: inline-block;
border-top-left-radius:0px;
border-top-right-radius:0px;
border-bottom-left-radius:0px;
border-bottom-right-radius:0px;
box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.50);
}
#cart {
position: absolute;
@include respond-to(handhelds) {
top: 7px;
right: 8px;
}
@include respond-to(mini) {
display: none;
visibility: hidden;
}
top: 33px;
right: 22px;
background: #C0DC86;
border-radius: 6px;
text-shadow: 0px 2px 4px 0px rgba(255,254,255,0.50);
text-align: center;
height: 34px;
display: inline;
.cart-number {
display: inline;
border: 0px solid #C0DC86;
font-family: AvenirNext-Heavy;
font-size: 14.66px;
color: #1D4975;
line-height: 20px;
text-shadow: -1px -1px 0px rgba(255,254,255,0.50);
height: 20px;
width: 20px;
}
.cart-price {
display: inline;
font-family: AvenirNext-Bold;
font-size: 20px;
color: #000000;
line-height: 27px;
}
}
#left-menu {
top: 21px;
left: 126px;
@include respond-to(handhelds) {
top: -100px;
}
@include respond-to(medium-screens) {
top: 39px;
left: 123px;
}
@include respond-to(wide-screens) {
top: 39px;
left: 123px;
}
}
#right-menu {
top: 21px;
left: 510px;
@include respond-to(handhelds) {
top: -100px;
}
@include respond-to(medium-screens) {
top: 39px;
left: 609px;
}
@include respond-to(wide-screens) {
top: 39px;
left: 816px;
}
}
#left-menu, #right-menu {
list-style: none outside none;
position: absolute;
.menu-item {
@include respond-to(small-screens) {
display: block;
}
@include respond-to(handhelds) {
display: none;
}
@include respond-to(mini) {
display: none;
}
display: inline-block;
font-family: AvenirNext-Medium;
font-size: 20px;
color: #4A4A4A;
line-height: 27px;
text-shadow: 0px 1px 0px #FFFFFF;
}
}
}
#search form input {
z-index: 20;
@include respond-to(mini) {
position: absolute;
top: 10px;
left: 61px;
width: 45%;
}
@include respond-to(handhelds) {
position: absolute;
top: 10px;
left: 61px;
width: 45%;
}
@include respond-to(small-screens) {
top: 32px;
left: 293px;
width: 20%;
}
@include respond-to(medium-screens) {
top: 32px;
left: 379px;
width: 18%;
}
@include respond-to(wide-screens) {
top: 32px;
left: 379px;
width: 18%;
}
position: absolute;
top: 33px;
left: 273px;
background: #FFFFFF;
border: 1px solid #979797;
box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.50);
border-radius: 3px;
display: inline-block;
font-family: AvenirNext-Regular;
font-size: 12px;
color: #4A4A4A;
line-height: 16px;
width: 144px;
padding: 6px 25px 6px 6px;
}
input.editable {
display: inline-block;
border: 0px solid;
}
// Tweeks
.course-price {
margin-top: 0px;
input.editable {
width: 100px;
}
div {
display: inline-block;
}
}
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment