diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index b59bf711b..6a827f010 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -879,6 +879,7 @@
   courses:
     course: "Course"
     courses: "courses"
+    create_new_class: "Create New Class"
     not_enrolled: "You are not enrolled in this course."
     visit_pref: "Please visit the"
     visit_suf: "page to enroll."
diff --git a/app/templates/courses/classroom-settings-modal.jade b/app/templates/courses/classroom-settings-modal.jade
index 88064bcd1..fdcb0ee40 100644
--- a/app/templates/courses/classroom-settings-modal.jade
+++ b/app/templates/courses/classroom-settings-modal.jade
@@ -1,24 +1,30 @@
 extends /templates/core/modal-base
 
 block modal-header-content
-  button.close(data-dismiss='modal')
-    span ×
-  h3.modal-title(data-i18n="courses.edit_settings1")
+  if view.classroom
+    h3.modal-title(data-i18n="courses.edit_settings1")
+  else
+    h3.modal-title(data-i18n="courses.create_new_class")
 
 block modal-body-content
   .form
     .form-group
       label(data-i18n="courses.title")
-      input.form-control.settings-name-input(type='text', value="#{view.classroom.get('name') || ''}")
+      - var name = view.classroom && view.classroom.get('name') ? view.classroom.get('name') : '';
+      input.form-control.settings-name-input(type='text', value="#{name}")
     .form-group
       label(data-i18n="courses.description")
-      textarea.form-control.settings-description-input(rows=2)= view.classroom.get('description')
+      - var description = view.classroom && view.classroom.get('description') ? view.classroom.get('description') : '';
+      textarea.form-control.settings-description-input(rows=2)= description
     .form-group
       label(data-i18n="choose_hero.programming_language")
       select.form-control#programming-language-select
-        - var aceConfig = view.classroom.get('aceConfig') || {};
+        - var aceConfig = view.classroom ? view.classroom.get('aceConfig') || {} : {};
         option(value="python", selected=aceConfig.language==='python') Python
         option(value="javascript", selected=aceConfig.language==='javascript') JavaScript
 
 block modal-footer-content
-  button#save-settings-btn.btn(data-i18n="common.save_changes")
\ No newline at end of file
+  if view.classroom
+    button#save-settings-btn.btn(data-i18n="common.save_changes")
+  else
+    button#save-settings-btn.btn(data-i18n="courses.create_class")
diff --git a/app/templates/courses/teacher-courses-view.jade b/app/templates/courses/teacher-courses-view.jade
index ab59c8bb6..66eb4c5e0 100644
--- a/app/templates/courses/teacher-courses-view.jade
+++ b/app/templates/courses/teacher-courses-view.jade
@@ -19,7 +19,7 @@ block content
     .no-students No classes yet!
 
   .text-center
-    button.btn.btn-lg.btn-success.uppercase create new class
+    button.btn.btn-lg.btn-success.uppercase.create-new-class create new class
 
   h3 Available Courses
   
@@ -47,29 +47,29 @@ block footer
 
 mixin classroom(classroom)
   .row
-    - var classMemberCount = classroom.get('members').length
+    - var classMemberCount = classroom.get('members') ? classroom.get('members').length : 0;
     if classMemberCount > 0
       .col-md-8
         p
           span.spr.class-name= classroom.get('name')
-          if classroom.get('aceConfig') && classroom.get('aceConfig').language
-            span.spr (#{classroom.get('aceConfig').language})
+          if classroom.get('aceConfig') && classroom.get('aceConfig').language === 'javascript'
+            span.spr.class-name (JavaScript)
           else
             span.spr.class-name (Python)
-          a edit class details
+          a.edit-classroom-small(data-i18n="courses.edit_settings", data-classroom-id="#{classroom.id}")
           .active-courses active courses
-          - var courseInstances = view.courseInstances.where({classroomID: classroom.id})
+          - var courseInstances = view.courseInstances.where({classroomID: classroom.id});
           each courseInstance in courseInstances
             +course(courseInstance, classMemberCount)
     else
       .col-md-12
         p
           span.spr.class-name= classroom.get('name')
-          if classroom.get('aceConfig') && classroom.get('aceConfig').language
-            span.spr (#{classroom.get('aceConfig').language})
+          if classroom.get('aceConfig') && classroom.get('aceConfig').language === 'javascript'
+            span.spr.class-name (JavaScript)
           else
             span.spr.class-name (Python)
-          a edit class details
+          a.edit-classroom-small(data-i18n="courses.edit_settings", data-classroom-id="#{classroom.id}")
         .no-students No students yet!
         .text-center
           a.btn.btn-info.uppercase(href='/courses/#{classroom.id}') add students
@@ -84,9 +84,9 @@ mixin classroom(classroom)
       .divider
 
 mixin course(courseInstance, classMemberCount)
-  - var courseMemberCount = courseInstance.get('members').length
+  - var courseMemberCount = courseInstance.get('members') ? courseInstance.get('members').length : 0;
   if courseMemberCount > 0
-    - var course = view.courses.get(courseInstance.get('courseID'))
+    - var course = view.courses.get(courseInstance.get('courseID'));
     p
       .course-name= course.get('name')
       .course-enrolled #{courseMemberCount} / #{classMemberCount} students enrolled
diff --git a/app/views/courses/ClassroomSettingsModal.coffee b/app/views/courses/ClassroomSettingsModal.coffee
index bd4a5eb1b..e9b210e61 100644
--- a/app/views/courses/ClassroomSettingsModal.coffee
+++ b/app/views/courses/ClassroomSettingsModal.coffee
@@ -1,10 +1,11 @@
+Classroom = require 'models/Classroom'
 ModalView = require 'views/core/ModalView'
 template = require 'templates/courses/classroom-settings-modal'
 
 module.exports = class AddLevelSystemModal extends ModalView
   id: 'classroom-settings-modal'
   template: template
-  
+
   events:
     'click #save-settings-btn': 'onClickSaveSettingsButton'
 
@@ -12,15 +13,16 @@ module.exports = class AddLevelSystemModal extends ModalView
     @classroom = options.classroom
 
   onClickSaveSettingsButton: ->
-    return unless @classroom
-    if name = $('.settings-name-input').val()
+    name = $('.settings-name-input').val()
+    unless @classroom
+      return unless name
+      @classroom = new Classroom({ name: name })
+    if name
       @classroom.set('name', name)
     description = $('.settings-description-input').val()
     @classroom.set('description', description)
     @classroom.set('aceConfig', {
       language: @$('#programming-language-select').val()
     })
-    @classroom.patch()
+    @classroom.save()
     @hide()
-
-  
\ No newline at end of file
diff --git a/app/views/courses/TeacherCoursesView.coffee b/app/views/courses/TeacherCoursesView.coffee
index 516c0d170..4c75e59ab 100644
--- a/app/views/courses/TeacherCoursesView.coffee
+++ b/app/views/courses/TeacherCoursesView.coffee
@@ -5,12 +5,9 @@ CocoModel = require 'models/CocoModel'
 Course = require 'models/Course'
 Classroom = require 'models/Classroom'
 User = require 'models/User'
-Prepaid = require 'models/Prepaid'
 CourseInstance = require 'models/CourseInstance'
 RootView = require 'views/core/RootView'
 template = require 'templates/courses/teacher-courses-view'
-utils = require 'core/utils'
-InviteToClassroomModal = require 'views/courses/InviteToClassroomModal'
 ClassroomSettingsModal = require 'views/courses/ClassroomSettingsModal'
 
 module.exports = class TeacherCoursesView extends RootView
@@ -18,11 +15,7 @@ module.exports = class TeacherCoursesView extends RootView
   template: template
 
   events:
-    'click #create-new-class-btn': 'onClickCreateNewclassButton'
-    'click .add-students-btn': 'onClickAddStudentsButton'
-    'click .course-instance-membership-checkbox': 'onClickCourseInstanceMembershipCheckbox'
-    'click #save-changes-btn': 'onClickSaveChangesButton'
-    'click #manage-tab-link': 'onClickManageTabLink'
+    'click .create-new-class': 'onClickCreateNewClassButton'
     'click .edit-classroom-small': 'onClickEditClassroomSmall'
 
   constructor: (options) ->
@@ -38,15 +31,7 @@ module.exports = class TeacherCoursesView extends RootView
     @courseInstances.sliceWithMembers = -> return @filter (courseInstance) -> _.size(courseInstance.get('members')) and courseInstance.get('classroomID')
     @supermodel.loadCollection(@courseInstances, 'course_instances', {data: {ownerID: me.id}})
     @members = new CocoCollection([], { model: User })
-    @prepaids = new CocoCollection([], { url: "/db/prepaid", model: Prepaid })
-    sum = (numbers) -> _.reduce(numbers, (a, b) -> a + b)
-    @prepaids.totalMaxRedeemers = -> sum((prepaid.get('maxRedeemers') for prepaid in @models)) or 0
-    @prepaids.totalRedeemers = -> sum((_.size(prepaid.get('redeemers')) for prepaid in @models)) or 0
-    @prepaids.comparator = '_id'
-    @supermodel.loadCollection(@prepaids, 'prepaids', {data: {creator: me.id}})
-    @listenTo @members, 'sync', @renderManageTab
-    @usersToRedeem = new CocoCollection([], { model: User })
-    @hoc = utils.getQueryVariable('hoc')
+    @listenTo @members, 'sync', @render
     @
 
   onceClassroomsSync: ->
@@ -56,160 +41,19 @@ module.exports = class TeacherCoursesView extends RootView
         url: "/db/classroom/#{classroom.id}/members"
       })
 
-  onClickCreateNewclassButton: ->
-    name = @$('#new-classroom-name-input').val()
-    return unless name
-    classroom = new Classroom({ name: name })
-    classroom.save()
-    @classrooms.add(classroom)
-    classroom.saving = true
-    @renderManageTab()
-    @listenTo classroom, 'sync', ->
-      classroom.saving = false
-      @fillMissingCourseInstances()
-
-  renderManageTab: ->
-    isActive = @$('#manage-tab-pane').hasClass('active')
-    @renderSelectors('#manage-tab-pane')
-    @$('#manage-tab-pane').toggleClass('active', isActive)
+  onClickCreateNewClassButton: ->
+    return @openModalView new AuthModal() if me.get('anonymous')
+    modal = new ClassroomSettingsModal({})
+    @openModalView(modal)
+    @listenToOnce modal, 'hide', =>
+      # TODO: how to get new classroom from modal?
+      @classrooms.add(modal.classroom)
+      # TODO: will this definitely fire after modal saves new classroom?
+      @listenToOnce modal.classroom, 'sync', @render
 
   onClickEditClassroomSmall: (e) ->
-    classroomID = $(e.target).closest('small').data('classroom-id')
+    classroomID = $(e.target).data('classroom-id')
     classroom = @classrooms.get(classroomID)
     modal = new ClassroomSettingsModal({classroom: classroom})
     @openModalView(modal)
-    @listenToOnce modal, 'hide', @renderManageTab
-
-  onClickAddStudentsButton: (e) ->
-    classroomID = $(e.target).data('classroom-id')
-    classroom = @classrooms.get(classroomID)
-    modal = new InviteToClassroomModal({classroom: classroom})
-    @openModalView(modal)
-
-  onLoaded: ->
-    super()
-    @linkCourseIntancesToCourses()
-    @fillMissingCourseInstances()
-
-  linkCourseIntancesToCourses: ->
-    for courseInstance in @courseInstances.models
-      courseInstance.course = @courses.get(courseInstance.get('courseID'))
-
-  fillMissingCourseInstances: ->
-    # TODO: Give teachers control over which courses are enabled for a given class.
-    # Add/remove course instances and columns in the view to match.
-    for classroom in @classrooms.models
-      classroom.filling = false
-      for course in @courses.models
-        courseInstance = @courseInstances.findWhere({classroomID: classroom.id, courseID: course.id})
-        if not courseInstance
-          classroom.filling = true
-          courseInstance = new CourseInstance({
-            classroomID: classroom.id
-            courseID: course.id
-          })
-          # TODO: figure out a better way to get around triggering validation errors for properties
-          # that the server will end up filling in, like an empty members array, ownerID
-          courseInstance.save(null, {validate: false})
-          courseInstance.course = course
-          @courseInstances.add(courseInstance)
-          @listenToOnce courseInstance, 'sync', @fillMissingCourseInstances
-          @renderManageTab()
-          return
-    @renderManageTab()
-
-  onClickCourseInstanceMembershipCheckbox: ->
-    usersToRedeem = {}
-    checkedBoxes = @$('.course-instance-membership-checkbox:checked')
-    _.each checkedBoxes, (el) =>
-      $el = $(el)
-      userID = $el.data('user-id')
-      return if usersToRedeem[userID]
-      user = @members.get(userID)
-      return if user.get('coursePrepaidID')
-      courseInstanceID = $el.data('course-instance-id')
-      courseInstance = @courseInstances.get(courseInstanceID)
-      return if courseInstance.course.get('free')
-      usersToRedeem[userID] = user
-
-    @usersToRedeem = new CocoCollection(_.values(usersToRedeem), {model: User})
-    @numCourseInstancesToAddTo = checkedBoxes.length
-    @renderSelectors '#fixed-area'
-
-  onClickSaveChangesButton: ->
-    @$('.course-instance-membership-checkbox').attr('disabled', true)
-    checkedBoxes = @$('.course-instance-membership-checkbox:checked')
-    raw = _.map checkedBoxes, (el) =>
-      $el = $(el)
-      userID = $el.data('user-id')
-      courseInstanceID = $el.data('course-instance-id')
-      courseInstance = @courseInstances.get(courseInstanceID)
-      return {
-        courseInstance: courseInstance
-        userID: userID
-      }
-    @membershipAdditions = new CocoCollection(raw, { model: User }) # TODO: Allow collections not to have models defined?
-    @membershipAdditions.originalSize = @membershipAdditions.size()
-    @usersToRedeem.originalSize = @usersToRedeem.size()
-    @state = 'saving-changes'
-    @renderSelectors '#fixed-area'
-    @redeemUsers()
-
-  redeemUsers: ->
-    if not @usersToRedeem.size()
-      @addMemberships()
-      return
-
-    user = @usersToRedeem.first()
-
-    prepaid = @prepaids.find((prepaid) -> prepaid.get('properties').endDate? and prepaid.openSpots())
-    prepaid = @prepaids.find((prepaid) -> prepaid.openSpots()) unless prepaid
-    $.ajax({
-      method: 'POST'
-      url: _.result(prepaid, 'url') + '/redeemers'
-      data: { userID: user.id }
-      context: @
-      success: ->
-        @usersToRedeem.remove(user)
-        @renderSelectors '#fixed-area'
-        @redeemUsers()
-      error: (jqxhr, textStatus, errorThrown) ->
-        if jqxhr.status is 402
-          @state = 'error'
-          @stateMessage = arguments[2]
-        else
-          @state = 'error'
-          @stateMessage = "#{jqxhr.status}: #{jqxhr.responseText}"
-        @renderSelectors '#fixed-area'
-    })
-
-  addMemberships: ->
-    if not @membershipAdditions.size()
-      @renderSelectors '#fixed-area'
-      document.location.reload()
-      return
-
-    membershipAddition = @membershipAdditions.first()
-    courseInstance = membershipAddition.get('courseInstance')
-    userID = membershipAddition.get('userID')
-    $.ajax({
-      method: 'POST'
-      url: _.result(courseInstance, 'url') + '/members'
-      data: { userID: userID }
-      context: @
-      success: ->
-        @membershipAdditions.remove(membershipAddition)
-        @renderSelectors '#fixed-area'
-        @addMemberships()
-      error: (jqxhr, textStatus, errorThrown) ->
-        if jqxhr.status is 402
-          @state = 'error'
-          @stateMessage = arguments[2]
-        else
-          @state = 'error'
-          @stateMessage = "#{jqxhr.status}: #{jqxhr.responseText}"
-        @renderSelectors '#fixed-area'
-    })
-
-  onClickManageTabLink: ->
-    @$('.nav-tabs a[href="#manage-tab-pane"]').tab('show')
+    @listenToOnce modal, 'hide', @render