1
0
mirror of https://github.com/fazo96/homework.git synced 2025-01-10 12:14:22 +01:00
homework/client/client.coffee

199 lines
6.7 KiB
CoffeeScript
Raw Normal View History

# Homework - Client Side
2014-05-31 18:09:56 +02:00
# Variables and utility stuff
notes = new Meteor.Collection "notes"
2014-05-28 18:45:41 +02:00
getUser = -> Meteor.user()
2014-05-31 18:09:56 +02:00
deleteAccount = ->
Meteor.call 'deleteMe', (r) -> if r is yes then Router.go 'home'
2014-05-28 18:45:41 +02:00
amIValid = ->
return no unless getUser()
return yes for mail in getUser().emails when mail.verified is yes; no
2014-05-30 08:27:49 +02:00
2014-05-31 18:09:56 +02:00
# Common Helpers for the Templates
2014-05-28 08:39:11 +02:00
UI.registerHelper "loggingIn", -> Meteor.loggingIn()
2014-05-31 19:31:56 +02:00
UI.registerHelper "email", ->
if getUser() then return getUser().emails[0].address
2014-05-28 18:45:41 +02:00
UI.registerHelper "verified", -> amIValid()
2014-05-30 10:33:32 +02:00
# Router
2014-05-31 18:09:56 +02:00
###
Important: before rendering and routing, always "dispatch" the user to 'home'
if he doesn't have the permission to access the current route. 'home' then
dispatches the user to the correct landing page.
Routes are client side, but even if by hacking the client you can access pages
without being logged in, it's impossible to inteact with data because
the server checks all the things before providing the data. It's safe.
###
2014-05-30 10:33:32 +02:00
Router.configure
layoutTemplate: 'layout'
loadingTemplate: 'loading'
notFoundTemplate: '404'
2014-05-30 10:33:32 +02:00
Router.map ->
@route 'home',
2014-05-31 19:31:56 +02:00
path: '/'
2014-05-31 18:09:56 +02:00
onBeforeAction: ->
# Dispatch user to the right landing page based on his account status
if getUser()
if amIValid() is yes then Router.go 'notes' else Router.go 'verifyEmail'
2014-05-31 18:09:56 +02:00
else Router.go 'login'
@route 'login',
onBeforeAction: -> Router.go 'home' if getUser()
@route 'register',
onBeforeAction: -> Router.go 'home' if getUser()
@route 'account',
onBeforeAction: ->
if not getUser() then Router.go 'home'
2014-05-30 10:33:32 +02:00
@route 'notes',
waitOn: -> Meteor.subscribe "my-notes"
2014-05-30 10:33:32 +02:00
onBeforeAction: ->
if not getUser() then Router.go 'home'
@route 'note',
path: '/note/:_id'
waitOn: -> Meteor.subscribe "my-notes"
2014-05-30 10:33:32 +02:00
data: -> notes.findOne _id: @params._id
onBeforeAction: -> if not @data()? then Router.go 'home'
2014-05-30 10:33:32 +02:00
@route 'verifyEmail',
2014-05-30 11:40:15 +02:00
path: '/verify/:token?'
2014-05-30 10:33:32 +02:00
template: 'verifyEmail'
onBeforeAction: ->
2014-05-31 19:31:56 +02:00
if @params.token? and @params.token isnt ""
2014-05-30 11:40:15 +02:00
Accounts.verifyEmail @params.token, (err) ->
2014-05-31 19:31:56 +02:00
if err
errCallback err; Router.go 'verifyEmail'
else Router.go 'home'
@route '404', path: '*'
2014-05-30 11:40:15 +02:00
2014-05-31 19:31:56 +02:00
# You can't set a callback for when the user logs in using a cookie so...
# Cheap ass work around for routing the user after he logs in with a token
Deps.autorun ->
t = Router.current(); return unless t and t.lookupTemplate
if getUser() and t.lookupTemplate() is 'login' then Router.go 'home'
2014-05-31 18:09:56 +02:00
# Client Templates
# Some utilities
logoutCallback = (err) -> if err then errCallback err else Router.go 'home'
2014-05-31 18:09:56 +02:00
errCallback = (err) ->
if err.reason
showError msg: err.reason
else showErrror msg: err
2014-05-30 10:33:32 +02:00
# Menu
2014-05-31 18:09:56 +02:00
Template.menu.events
'click .go-home': -> Router.go 'home'
'click .go-account': -> Router.go 'account'
'click .go-archive': -> Router.go 'archive'
2014-05-30 08:27:49 +02:00
# User Interface
2014-05-30 10:33:32 +02:00
Template.account.events
'click #btn-logout': (e,template) -> Meteor.logout logoutCallback
2014-05-31 19:31:56 +02:00
'click #btn-delete-me': -> deleteAccount()
# Notes template
2014-05-30 10:33:32 +02:00
Template.notelist.empty = -> notes.find().count() is 0
Template.notelist.notes = ->
d = notes.find().fetch()
2014-05-30 10:33:32 +02:00
Template.notelist.events
'click .close-note': -> notes.remove @_id
'click .edit-note': -> Router.go 'note', {_id: @_id}
'keypress #newNote': (e,template) ->
2014-05-28 10:19:06 +02:00
if e.keyCode is 13 and template.find('#newNote').value isnt ""
notes.insert
title: template.find('#newNote').value
2014-05-28 10:19:06 +02:00
content: ""
userId: Meteor.userId()
template.find('#newNote').value = ""
# Note Editor
2014-05-30 12:18:04 +02:00
Template.editor.note = -> Router.current.data() # Only when we're in /note/:_id
saveCurrentNote = (t,e) ->
2014-05-31 18:09:56 +02:00
if e and e.keyCode isnt 13 then return
2014-05-30 10:33:32 +02:00
notes.update Router.current().data()._id,
$set:
2014-05-28 14:57:43 +02:00
title: t.find('.editor-title').value
content: t.find('.area').value
Template.editor.events
2014-05-30 10:33:32 +02:00
'click .close-editor': -> Router.go 'notes'
'click .save-editor': (e,t) -> saveCurrentNote t
'keypress .title': (e,t) -> saveCurrentNote t, e
# Notifications
alerts = []
alertDep = new Deps.Dependency
# Show a notification
notify = (data) ->
alerts.push
title: data.title
msg: data.msg
type: data.type or "danger"
alertDep.changed()
# Clear all notifications
clearNotifications = -> alerts.clear(); alertDep.changed()
# Get all the notifications
Template.notifications.notification = -> alertDep.depend(); alerts
2014-05-28 10:19:06 +02:00
Template.notifications.events
'click .close-notification': (e,template) ->
alerts.splice alerts.indexOf(this), 1
alertDep.changed()
2014-05-28 10:19:06 +02:00
# "Error" visualization template
errorDep = new Deps.Dependency; shownError = undefined
showError = (err) ->
shownError = err; shownError.type = err.type or "danger"
errorDep.changed()
clearError = -> shownError = undefined; errorDep.changed()
Template.error.error = -> errorDep.depend(); shownError
Template.error.events 'click .close': -> clearError()
2014-05-28 18:45:41 +02:00
# Verify Email
Template.verifyEmail.events
'click #btn-verify': (e,template) ->
2014-05-31 19:31:56 +02:00
t = template.find('#token-field').value; t = t.split("/")
t = t[t.length-1] # Remove all the part before the last "/"
console.log "Email ver. using token: "+template.find('#token-field').value
Accounts.verifyEmail t, (err) ->
2014-05-30 10:33:32 +02:00
if err then errCallback err else Router.go 'notes'
2014-05-28 18:45:41 +02:00
'click #btn-resend': ->
2014-05-30 10:33:32 +02:00
Meteor.call 'resendConfirmEmail', (err) ->
if err
errCallback err
else showError { type:"success", msg: "Confirmation email sent" }
2014-05-31 18:09:56 +02:00
'click #btn-delete': -> deleteAccount()
2014-05-30 10:33:32 +02:00
'click #btn-logout': -> Meteor.logout logoutCallback
2014-05-28 18:45:41 +02:00
2014-05-31 18:09:56 +02:00
# Login
loginRequest = (e,template) ->
if e and e.keyCode isnt 13 then return
mail = template.find('#l-mail').value; pass = template.find('#l-pass').value
Meteor.loginWithPassword mail, pass, (err) ->
2014-05-31 19:31:56 +02:00
if err then errCallback err else Router.go 'notes'
2014-05-31 18:09:56 +02:00
Template.login.events
'keypress .login': (e,template) -> loginRequest e,template
'click #login-btn': (e,template) -> loginRequest null,template
2014-05-28 18:45:41 +02:00
2014-05-31 18:09:56 +02:00
# Register
registerRequest = (e,template) ->
if e and e.keyCode isnt 13 then return
mail = template.find('#r-mail').value; pass = template.find('#r-pass').value
pass2 = template.find('#r-pass-2').value
if not mail
showError msg: "Please enter an Email"
else if not pass
showError msg: "Please enter a password"
else if pass.length < 8
showError msg: "Password too short"
else if pass2 isnt pass
showError msg: "The passwords don't match"
else # Sending actual registration request
try
Accounts.createUser {
email: mail,
password: pass
}, (err) -> if err then errCallback err else Router.go 'confirmEmail'
catch err
showError msg: err
Template.register.events
'click #register-btn': (e,t) -> registerRequest null,t
'keypress .register': (e,t) -> registerRequest e,t