mirror of
https://github.com/fazo96/homework.git
synced 2025-01-10 12:14:22 +01:00
major refractor and bunch of new features
This commit is contained in:
parent
8de8f3739e
commit
dcec227896
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
@ -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.
|
32
README.md
32
README.md
@ -1,8 +1,32 @@
|
|||||||
# Homework
|
# Homework
|
||||||
New homework app rewritten using Meteor because I realized the MEAN stack was
|
Schoolwork management application for students.
|
||||||
a bad idea: meteor is just better (or at least faster to write).
|
|
||||||
|
|
||||||
**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
|
### 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.
|
||||||
|
111
app.coffee
111
app.coffee
@ -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 }
|
|
||||||
}
|
|
94
client/client.coffee
Normal file
94
client/client.coffee
Normal file
@ -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 }
|
||||||
|
}
|
@ -3,19 +3,21 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
{{> ribbon}}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1 id="title">Homework<br>
|
<h1 id="title">Homework<br>
|
||||||
<small id="small">management for students</small>
|
<small id="small">management for students</small>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="center-block" id="quicknotes">
|
<div class="center-block" id="ui-container">
|
||||||
{{#if currentUser}}
|
{{#if currentUser}}
|
||||||
{{> editor}} {{> notes}} {{> userInfo}}
|
{{> editor}} {{> notes}} {{> userInfo}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{> auth}}
|
{{> auth}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="center-block" align="center">{{> footer}}</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
@ -29,6 +31,9 @@
|
|||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
<div align="center">
|
||||||
|
<input type="text" id="newNote" class="form-control" placeholder="Add new note">
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="auth">
|
<template name="auth">
|
||||||
@ -52,10 +57,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="userInfo">
|
<template name="userInfo"><hr>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<input type="text" id="newNote" class="form-control" placeholder="Add new note">
|
<p>{{in}}</p>
|
||||||
<p>Logged in as {{in}}</p>
|
|
||||||
<button type="button" id="logout" class="btn btn-danger">Logout</button>
|
<button type="button" id="logout" class="btn btn-danger">Logout</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -87,3 +91,20 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="footer">
|
||||||
|
<hr>
|
||||||
|
<p>This app is <a href="https://en.wikipedia.org/wiki/Free_software">Free Software</a>, under the <a href="http://opensource.org/licenses/MIT">MIT License</a></p>
|
||||||
|
<p>Built by Enrico Fasoli</p>
|
||||||
|
<a class="custom-link" href="http://www.linkedin.com/profile/view?id=292450419"><i class="fa fa-linkedin fa-2x"></i></a>
|
||||||
|
<a href="http://twitter.com/fazo96"><i class="fa fa-twitter fa-2x footer-center-icon"></i></a>
|
||||||
|
<a class="custom-link" href="http://github.com/fazo96"><i class="fa fa-github fa-2x"></i></a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="ribbon">
|
||||||
|
<div class="github-fork-ribbon-wrapper right">
|
||||||
|
<div class="github-fork-ribbon">
|
||||||
|
<a href="http://github.com/fazo96/homework">Fork me on GitHub</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
142
client/ribbon.css
Normal file
142
client/ribbon.css
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
This cool github ribbon was developed by:
|
||||||
|
https://github.com/simonwhitaker
|
||||||
|
All credit for this file goes to him!
|
||||||
|
Repo for github-ribbon-css: https://github.com/simonwhitaker/github-fork-ribbon-css
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Left will inherit from right (so we don't need to duplicate code) */
|
||||||
|
.github-fork-ribbon {
|
||||||
|
/* The right and left classes determine the side we attach our banner to */
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
/* Add a bit of padding to give some substance outside the "stitching" */
|
||||||
|
padding: 2px 0;
|
||||||
|
|
||||||
|
/* Set the base colour */
|
||||||
|
background-color: #a00;
|
||||||
|
|
||||||
|
/* Set a gradient: transparent black at the top to almost-transparent black at the bottom */
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.15)));
|
||||||
|
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
||||||
|
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
||||||
|
background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
||||||
|
background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
||||||
|
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15));
|
||||||
|
|
||||||
|
/* Add a drop shadow */
|
||||||
|
-webkit-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
-moz-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
|
/* Set the font */
|
||||||
|
font: 700 13px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon a,
|
||||||
|
.github-fork-ribbon a:hover {
|
||||||
|
/* Set the text properties */
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 -1px rgba(0, 0, 0, 0.5);
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
/* Set the geometry. If you fiddle with these you'll also need
|
||||||
|
to tweak the top and right values in .github-fork-ribbon. */
|
||||||
|
width: 200px;
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
/* Set the layout properties */
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 0;
|
||||||
|
|
||||||
|
/* Add "stitching" effect */
|
||||||
|
border-width: 1px 0;
|
||||||
|
border-style: dotted;
|
||||||
|
border-color: #fff;
|
||||||
|
border-color: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
position: absolute;
|
||||||
|
overflow: hidden;
|
||||||
|
top: 0;
|
||||||
|
z-index: 9999;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.fixed {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.right {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.left-bottom {
|
||||||
|
position: fixed;
|
||||||
|
top: inherit;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.right-bottom {
|
||||||
|
position: fixed;
|
||||||
|
top: inherit;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.right .github-fork-ribbon {
|
||||||
|
top: 42px;
|
||||||
|
right: -43px;
|
||||||
|
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
-moz-transform: rotate(45deg);
|
||||||
|
-ms-transform: rotate(45deg);
|
||||||
|
-o-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.left .github-fork-ribbon {
|
||||||
|
top: 42px;
|
||||||
|
left: -43px;
|
||||||
|
|
||||||
|
-webkit-transform: rotate(-45deg);
|
||||||
|
-moz-transform: rotate(-45deg);
|
||||||
|
-ms-transform: rotate(-45deg);
|
||||||
|
-o-transform: rotate(-45deg);
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon {
|
||||||
|
top: 80px;
|
||||||
|
left: -43px;
|
||||||
|
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
-moz-transform: rotate(45deg);
|
||||||
|
-ms-transform: rotate(45deg);
|
||||||
|
-o-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon {
|
||||||
|
top: 80px;
|
||||||
|
right: -43px;
|
||||||
|
|
||||||
|
-webkit-transform: rotate(-45deg);
|
||||||
|
-moz-transform: rotate(-45deg);
|
||||||
|
-ms-transform: rotate(-45deg);
|
||||||
|
-o-transform: rotate(-45deg);
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
@ -15,6 +15,9 @@ input {
|
|||||||
clear:both;
|
clear:both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.custom-link { color: #999; }
|
||||||
|
.custom-link:hover { color: #101010;}
|
||||||
|
|
||||||
.subtitle { color: #999; }
|
.subtitle { color: #999; }
|
||||||
|
|
||||||
/* Custom Classes */
|
/* Custom Classes */
|
||||||
@ -64,7 +67,12 @@ input {
|
|||||||
|
|
||||||
/* IDs */
|
/* IDs */
|
||||||
|
|
||||||
#quicknotes {
|
.footer-center-icon {
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
#ui-container {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
18
server/server.coffee
Normal file
18
server/server.coffee
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Homework - Server Side
|
||||||
|
notes = new Meteor.Collection "notes"
|
||||||
|
|
||||||
|
Accounts.config {
|
||||||
|
sendVerificationEmail: true
|
||||||
|
loginExpirationInDays: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.publish "my-notes", ->
|
||||||
|
notes.find( { userId: @userId } ) unless not @userId
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
Accounts.validateNewUser (user) ->
|
||||||
|
if Match.test(user.email, String) and validateEmail user.email is yes
|
||||||
|
if user.password and Match.test(user.password,String) is yes and user.password.length > 7
|
||||||
|
return yes
|
||||||
|
else throw new Meteor.Error 403, "Invalid Password"
|
||||||
|
else throw new Meteor.Error 403, "Invalid Email"
|
5
server/util.coffee
Normal file
5
server/util.coffee
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Utility Stuff for Homework
|
||||||
|
|
||||||
|
validateEmail = (email) ->
|
||||||
|
re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
re.test email
|
Loading…
Reference in New Issue
Block a user