diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..3fb4f69 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Enrico Fasoli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index e8f2f23..a36b40c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,32 @@ # Homework -New homework app rewritten using Meteor because I realized the MEAN stack was -a bad idea: meteor is just better (or at least faster to write). +Schoolwork management application for students. -**requires Meteorite** and `bootstrap-3` and `fontawesome` Meteorite packages. +### Try it +[the app is hosted online!](http://homework.meteor.com) + +### Development +Clone the repo, [install meteor](http://meteor.com) and **meteorite**. +Install dependent packages and then run `meteor`. That's it. ### License -GPLv3 +The MIT License (MIT) + +Copyright (c) 2014 Enrico Fasoli + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app.coffee b/app.coffee deleted file mode 100644 index 6c69c1e..0000000 --- a/app.coffee +++ /dev/null @@ -1,111 +0,0 @@ -notes = new Meteor.Collection "notes" - -# Server -if Meteor.isServer - Accounts.config { - sendVerificationEmail: false - loginExpirationInDays: 1 - } - - Meteor.publish "my-notes", -> - notes.find( { userId: @userId } ) unless not @userId - - # Authentication - Accounts.validateNewUser (user) -> - if user.email and Meteor.check(user.email,String) is yes and user.email.contains '@' is yes and user.email.endsWith '.' is no and user.email.endsWith '@' is no - return yes - else throw new Meteor.Error 403, "Invalid Email" - if user.password and Meteor.check(user.password,String) is yes and user.password.length > 7 - return yes - else throw new Meteor.Error 403, "Password invalid" - -# Client -if Meteor.isClient - Deps.autorun -> Meteor.subscribe "my-notes" unless not Meteor.userId() - - # User Interface - Template.userInfo.events { - 'click #logout': (e,template) -> Meteor.logout() - 'keypress #newNote': (e,template) -> - if e.keyCode is 13 - notes.insert { - title: template.find('#newNote').value - content: "..." - userId: Meteor.userId() - } - template.find('#newNote').value = "" - } - Template.userInfo.in = -> Meteor.user().emails[0].address - - # Notes template - Template.notes.truncateNoteDesc = (s) -> - if s.length > 52 then s.slice(0,48)+"..." else s - Template.notes.notes = -> - d = notes.find().fetch(); - #d.splice d.indexOf(Session.get('note')), 1 ; d - Template.notes.events { - 'click .close-note': -> notes.remove @_id - 'click .edit-note': -> Session.set 'note', this - } - - # Note Editor - Template.editor.note = -> Session.get 'note' - saveCurrentNote = (t,e) -> - if e and e.keyCode isnt 13 then return; - notes.update Session.get('note')._id, - $set: - title: t.find('.title').value - content: t.find('.area').value - Template.editor.events - 'click .close-editor': -> Session.set 'note', undefined - 'click .save-editor': (e,t) -> saveCurrentNote t - #'keypress .edit-note': (e,t) -> saveCurrentNote t, e # Doesnt work?? - 'keypress .title': (e,t) -> saveCurrentNote t, e - - # Notifications - alerts = [] - alertDep = new Deps.Dependency - errCallback = (err) -> notify { msg: err.reason } - # Show a notification - notify = (data) -> - alerts.push { - title: data.title - msg: data.msg - id: data.id or alerts.length - 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 - Template.notifications.events { - 'click .close-notification': (e,template) -> - alerts.splice alerts.indexOf(this), 1 - alertDep.changed() - } - - # Login and Register - pressLogin = (template) -> - mail = template.find('#mail').value; pass = template.find('#pass').value - Meteor.loginWithPassword mail, pass, (err) -> - errCallback err - Template.auth.working = -> Meteor.loggingIn() - Template.auth.events { - 'keypress .login': (e,template) -> - if e.keyCode is 13 then pressLogin template - # Login - 'click #login': (e,template) -> pressLogin template - # Register - 'click #register': (e,template) -> - mail = template.find('#mail').value; pass = template.find('#pass').value - if not mail or mail.contains '@' is no or mail.endsWith '.' is yes or mail.endsWith '@' is yes - notify { msg: "Invalid Email" } - else - try - Accounts.createUser { - email: mail, - password: pass - }, (e) -> errCallback e - catch err - notify { msg: err } - } diff --git a/client/client.coffee b/client/client.coffee new file mode 100644 index 0000000..1c8bd72 --- /dev/null +++ b/client/client.coffee @@ -0,0 +1,94 @@ +# Homework - Client Side +notes = new Meteor.Collection "notes" +Deps.autorun -> Meteor.subscribe "my-notes" unless not Meteor.userId() +#Meteor.subscribe "my-notes" + +# User Interface +Template.userInfo.events { + 'click #logout': (e,template) -> Meteor.logout() +} +Template.userInfo.in = -> Meteor.user().emails[0].address + +# Notes template +Template.notes.truncateNoteDesc = (s) -> + if s.length > 52 then s.slice(0,48)+"..." else s +Template.notes.notes = -> + d = notes.find().fetch() +Template.notes.events { + 'click .close-note': -> notes.remove @_id + 'click .edit-note': -> Session.set 'note', this + 'keypress #newNote': (e,template) -> + if e.keyCode is 13 + notes.insert { + title: template.find('#newNote').value + content: "..." + userId: Meteor.userId() + } + template.find('#newNote').value = "" +} + +# Note Editor +Template.editor.note = -> Session.get 'note' +saveCurrentNote = (t,e) -> + if e and e.keyCode isnt 13 then return; + notes.update Session.get('note')._id, + $set: + title: t.find('.title').value + content: t.find('.area').value +Template.editor.events + 'click .close-editor': -> Session.set 'note', undefined + 'click .save-editor': (e,t) -> saveCurrentNote t + #'keypress .edit-note': (e,t) -> saveCurrentNote t, e # Doesnt work?? + 'keypress .title': (e,t) -> saveCurrentNote t, e + +# Notifications +alerts = [] +alertDep = new Deps.Dependency +errCallback = (err) -> notify { msg: err.reason } +# Show a notification +notify = (data) -> + alerts.push { + title: data.title + msg: data.msg + id: data.id or alerts.length + 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 +Template.notifications.events { + 'click .close-notification': (e,template) -> + alerts.splice alerts.indexOf(this), 1 + alertDep.changed() +} + +# Login and Register +pressLogin = (template) -> + mail = template.find('#mail').value; pass = template.find('#pass').value + Meteor.loginWithPassword mail, pass, (err) -> + errCallback err +Template.auth.working = -> Meteor.loggingIn() +Template.auth.events { + 'keypress .login': (e,template) -> + if e.keyCode is 13 then pressLogin template + # Login + 'click #login': (e,template) -> pressLogin template + # Register + 'click #register': (e,template) -> + mail = template.find('#mail').value; pass = template.find('#pass').value + if not mail + notify { msg: "Please enter an Email" } + else if not pass + notify { msg: "Please enter a password" } + else if pass.length < 8 + notify { msg: "Password too short" } + else # Sending actual registration request + try + Accounts.createUser { + email: mail, + password: pass + }, (e) -> errCallback e + catch err + notify { msg: err } +} diff --git a/index.html b/client/index.html similarity index 73% rename from index.html rename to client/index.html index 91fa4cd..fe73f51 100644 --- a/index.html +++ b/client/index.html @@ -3,19 +3,21 @@
+ {{> ribbon}}Logged in as {{in}}
+{{in}}
This app is Free Software, under the MIT License
+Built by Enrico Fasoli
+ + + + + + +