Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tallykatt/eabb105824a50967261e76771dba1dfd to your computer and use it in GitHub Desktop.
Save tallykatt/eabb105824a50967261e76771dba1dfd to your computer and use it in GitHub Desktop.

Revisions

  1. @webhat webhat created this gist Aug 27, 2015.
    7 changes: 7 additions & 0 deletions Oplerno Edit Page.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    Oplerno Edit Page
    -----------------


    A [Pen](http://codepen.io/webhat/pen/JdYxxY) by [Daniel W. Crompton](http://codepen.io/webhat) on [CodePen](http://codepen.io/).

    [License](http://codepen.io/webhat/pen/JdYxxY/license).
    73 changes: 73 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    %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' }









    160 changes: 160 additions & 0 deletions script.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,160 @@
    '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()
    7 changes: 7 additions & 0 deletions scripts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    <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>
    353 changes: 353 additions & 0 deletions style.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,353 @@
    $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;
    }
    }
    1 change: 1 addition & 0 deletions styles
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />