├── .gitattributes ├── .gitignore ├── README.md ├── client ├── .bowerrc ├── .editorconfig ├── .jshintrc ├── .travis.yml ├── .yo-rc.json ├── Gruntfile.js ├── app │ ├── .buildignore │ ├── 404.html │ ├── images │ │ └── yeoman.png │ ├── index.html │ ├── robots.txt │ ├── scripts │ │ ├── app.js │ │ └── controllers │ │ │ ├── main.js │ │ │ ├── results.js │ │ │ └── vote.js │ ├── styles │ │ └── main.scss │ └── views │ │ ├── main.html │ │ ├── results.html │ │ └── vote.html ├── bower.json ├── package.json └── test │ ├── .jshintrc │ ├── karma.conf.js │ └── spec │ └── controllers │ └── main.js ├── img ├── material1.png ├── material2.png └── material3.png ├── license └── server ├── app └── models │ └── poll.js ├── config.js.example ├── package.json └── server.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | .sass-cache 5 | bower_components 6 | server/config.js 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Material Poll 2 | ### This is a open source implementation of the strawpoll.me site. [DEMO](http://materialpoll.tk) 3 | * Server built with Node, Express, Mongo and Socket.io 4 | * Client built with Yo Angular and materializecss 5 | 6 | #####Notes: if deploying to server make sure to add rewrites for html5Mode or change url within app to add hash 7 |
8 | NGINX 9 | server { 10 | server_name my-app; 11 | 12 | root /path/to/app; 13 | 14 | location / { 15 | try_files $uri $uri/ /index.html; 16 | } 17 | }18 | 19 | #### Make sure to rename config.js.example to config.js with your mongodb connection string. 20 | 21 | ##### Create Poll 22 |  23 | ##### Vote on Poll 24 |  25 | ##### See Results 26 |  27 | -------------------------------------------------------------------------------- /client/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /client/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "eqnull": true, 11 | "indent": 2, 12 | "latedef": true, 13 | "newcap": true, 14 | "noarg": true, 15 | "quotmark": "single", 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "angular": false, 23 | "$": false, 24 | "io": false, 25 | "Chart": false 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /client/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - 'iojs' 5 | - '0.12' 6 | - '0.10' 7 | before_script: 8 | - 'npm install -g bower grunt-cli' 9 | - 'bower install' 10 | -------------------------------------------------------------------------------- /client/.yo-rc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /client/Gruntfile.js: -------------------------------------------------------------------------------- 1 | // Generated on 2015-06-16 using generator-angular 0.11.1 2 | 'use strict'; 3 | 4 | // # Globbing 5 | // for performance reasons we're only matching one level down: 6 | // 'test/spec/{,*/}*.js' 7 | // use this if you want to recursively match all subfolders: 8 | // 'test/spec/**/*.js' 9 | 10 | module.exports = function (grunt) { 11 | 12 | // Load grunt tasks automatically 13 | require('load-grunt-tasks')(grunt); 14 | 15 | // Time how long tasks take. Can help when optimizing build times 16 | require('time-grunt')(grunt); 17 | 18 | // Configurable paths for the application 19 | var appConfig = { 20 | app: require('./bower.json').appPath || 'app', 21 | dist: 'dist' 22 | }; 23 | 24 | // Define the configuration for all the tasks 25 | grunt.initConfig({ 26 | 27 | // Project settings 28 | yeoman: appConfig, 29 | 30 | // Watches files for changes and runs tasks based on the changed files 31 | watch: { 32 | bower: { 33 | files: ['bower.json'], 34 | tasks: ['wiredep'] 35 | }, 36 | js: { 37 | files: ['<%= yeoman.app %>/scripts/{,*/}*.js'], 38 | tasks: ['newer:jshint:all'], 39 | options: { 40 | livereload: '<%= connect.options.livereload %>' 41 | } 42 | }, 43 | jsTest: { 44 | files: ['test/spec/{,*/}*.js'], 45 | tasks: ['newer:jshint:test', 'karma'] 46 | }, 47 | compass: { 48 | files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], 49 | tasks: ['compass:server', 'autoprefixer'] 50 | }, 51 | gruntfile: { 52 | files: ['Gruntfile.js'] 53 | }, 54 | livereload: { 55 | options: { 56 | livereload: '<%= connect.options.livereload %>' 57 | }, 58 | files: [ 59 | '<%= yeoman.app %>/{,*/}*.html', 60 | '.tmp/styles/{,*/}*.css', 61 | '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 62 | ] 63 | } 64 | }, 65 | 66 | // The actual grunt server settings 67 | connect: { 68 | options: { 69 | port: 9000, 70 | // Change this to '0.0.0.0' to access the server from outside. 71 | hostname: '0.0.0.0', 72 | livereload: 35729 73 | }, 74 | livereload: { 75 | options: { 76 | open: true, 77 | middleware: function (connect) { 78 | return [ 79 | connect.static('.tmp'), 80 | connect().use( 81 | '/bower_components', 82 | connect.static('./bower_components') 83 | ), 84 | connect().use( 85 | '/app/styles', 86 | connect.static('./app/styles') 87 | ), 88 | connect.static(appConfig.app) 89 | ]; 90 | } 91 | } 92 | }, 93 | test: { 94 | options: { 95 | port: 9001, 96 | middleware: function (connect) { 97 | return [ 98 | connect.static('.tmp'), 99 | connect.static('test'), 100 | connect().use( 101 | '/bower_components', 102 | connect.static('./bower_components') 103 | ), 104 | connect.static(appConfig.app) 105 | ]; 106 | } 107 | } 108 | }, 109 | dist: { 110 | options: { 111 | open: true, 112 | base: '<%= yeoman.dist %>' 113 | } 114 | } 115 | }, 116 | 117 | // Make sure code styles are up to par and there are no obvious mistakes 118 | jshint: { 119 | options: { 120 | jshintrc: '.jshintrc', 121 | reporter: require('jshint-stylish') 122 | }, 123 | all: { 124 | src: [ 125 | 'Gruntfile.js', 126 | '<%= yeoman.app %>/scripts/{,*/}*.js' 127 | ] 128 | }, 129 | test: { 130 | options: { 131 | jshintrc: 'test/.jshintrc' 132 | }, 133 | src: ['test/spec/{,*/}*.js'] 134 | } 135 | }, 136 | 137 | // Empties folders to start fresh 138 | clean: { 139 | dist: { 140 | files: [{ 141 | dot: true, 142 | src: [ 143 | '.tmp', 144 | '<%= yeoman.dist %>/{,*/}*', 145 | '!<%= yeoman.dist %>/.git{,*/}*' 146 | ] 147 | }] 148 | }, 149 | server: '.tmp' 150 | }, 151 | 152 | // Add vendor prefixed styles 153 | autoprefixer: { 154 | options: { 155 | browsers: ['last 1 version'] 156 | }, 157 | server: { 158 | options: { 159 | map: true, 160 | }, 161 | files: [{ 162 | expand: true, 163 | cwd: '.tmp/styles/', 164 | src: '{,*/}*.css', 165 | dest: '.tmp/styles/' 166 | }] 167 | }, 168 | dist: { 169 | files: [{ 170 | expand: true, 171 | cwd: '.tmp/styles/', 172 | src: '{,*/}*.css', 173 | dest: '.tmp/styles/' 174 | }] 175 | } 176 | }, 177 | 178 | // Automatically inject Bower components into the app 179 | wiredep: { 180 | app: { 181 | src: ['<%= yeoman.app %>/index.html'], 182 | ignorePath: /\.\.\// 183 | }, 184 | test: { 185 | devDependencies: true, 186 | src: '<%= karma.unit.configFile %>', 187 | ignorePath: /\.\.\//, 188 | fileTypes:{ 189 | js: { 190 | block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi, 191 | detect: { 192 | js: /'(.*\.js)'/gi 193 | }, 194 | replace: { 195 | js: '\'{{filePath}}\',' 196 | } 197 | } 198 | } 199 | }, 200 | sass: { 201 | src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], 202 | ignorePath: /(\.\.\/){1,2}bower_components\// 203 | } 204 | }, 205 | 206 | // Compiles Sass to CSS and generates necessary files if requested 207 | compass: { 208 | options: { 209 | sassDir: '<%= yeoman.app %>/styles', 210 | cssDir: '.tmp/styles', 211 | generatedImagesDir: '.tmp/images/generated', 212 | imagesDir: '<%= yeoman.app %>/images', 213 | javascriptsDir: '<%= yeoman.app %>/scripts', 214 | fontsDir: '<%= yeoman.app %>/styles/fonts', 215 | importPath: './bower_components', 216 | httpImagesPath: '/images', 217 | httpGeneratedImagesPath: '/images/generated', 218 | httpFontsPath: '/styles/fonts', 219 | relativeAssets: false, 220 | assetCacheBuster: false, 221 | raw: 'Sass::Script::Number.precision = 10\n' 222 | }, 223 | dist: { 224 | options: { 225 | generatedImagesDir: '<%= yeoman.dist %>/images/generated' 226 | } 227 | }, 228 | server: { 229 | options: { 230 | sourcemap: true 231 | } 232 | } 233 | }, 234 | 235 | // Renames files for browser caching purposes 236 | filerev: { 237 | dist: { 238 | src: [ 239 | '<%= yeoman.dist %>/scripts/{,*/}*.js', 240 | '<%= yeoman.dist %>/styles/{,*/}*.css', 241 | '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}', 242 | '<%= yeoman.dist %>/styles/fonts/*' 243 | ] 244 | } 245 | }, 246 | 247 | // Reads HTML for usemin blocks to enable smart builds that automatically 248 | // concat, minify and revision files. Creates configurations in memory so 249 | // additional tasks can operate on them 250 | useminPrepare: { 251 | html: '<%= yeoman.app %>/index.html', 252 | options: { 253 | dest: '<%= yeoman.dist %>', 254 | flow: { 255 | html: { 256 | steps: { 257 | js: ['concat', 'uglifyjs'], 258 | css: ['cssmin'] 259 | }, 260 | post: {} 261 | } 262 | } 263 | } 264 | }, 265 | 266 | // Performs rewrites based on filerev and the useminPrepare configuration 267 | usemin: { 268 | html: ['<%= yeoman.dist %>/{,*/}*.html'], 269 | css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], 270 | options: { 271 | assetsDirs: [ 272 | '<%= yeoman.dist %>', 273 | '<%= yeoman.dist %>/images', 274 | '<%= yeoman.dist %>/styles' 275 | ] 276 | } 277 | }, 278 | cssmin: { 279 | minify: { 280 | src: '.tmp/styles/main.css', 281 | dest: 'dist/styles/main.css' 282 | } 283 | }, 284 | 285 | // The following *-min tasks will produce minified files in the dist folder 286 | // By default, your `index.html`'s will take care of 287 | // minification. These next options are pre-configured if you do not wish 288 | // to use the Usemin blocks. 289 | // cssmin: { 290 | // dist: { 291 | // files: { 292 | // '<%= yeoman.dist %>/styles/main.css': [ 293 | // '.tmp/styles/{,*/}*.css' 294 | // ] 295 | // } 296 | // } 297 | // }, 298 | // uglify: { 299 | // dist: { 300 | // files: { 301 | // '<%= yeoman.dist %>/scripts/scripts.js': [ 302 | // '<%= yeoman.dist %>/scripts/scripts.js' 303 | // ] 304 | // } 305 | // } 306 | // }, 307 | // concat: { 308 | // dist: {} 309 | // }, 310 | 311 | imagemin: { 312 | dist: { 313 | files: [{ 314 | expand: true, 315 | cwd: '<%= yeoman.app %>/images', 316 | src: '{,*/}*.{png,jpg,jpeg,gif}', 317 | dest: '<%= yeoman.dist %>/images' 318 | }] 319 | } 320 | }, 321 | 322 | svgmin: { 323 | dist: { 324 | files: [{ 325 | expand: true, 326 | cwd: '<%= yeoman.app %>/images', 327 | src: '{,*/}*.svg', 328 | dest: '<%= yeoman.dist %>/images' 329 | }] 330 | } 331 | }, 332 | 333 | htmlmin: { 334 | dist: { 335 | options: { 336 | collapseWhitespace: true, 337 | conservativeCollapse: true, 338 | collapseBooleanAttributes: true, 339 | removeCommentsFromCDATA: true, 340 | removeOptionalTags: true 341 | }, 342 | files: [{ 343 | expand: true, 344 | cwd: '<%= yeoman.dist %>', 345 | src: ['*.html', 'views/{,*/}*.html'], 346 | dest: '<%= yeoman.dist %>' 347 | }] 348 | } 349 | }, 350 | 351 | // ng-annotate tries to make the code safe for minification automatically 352 | // by using the Angular long form for dependency injection. 353 | ngAnnotate: { 354 | dist: { 355 | files: [{ 356 | expand: true, 357 | cwd: '.tmp/concat/scripts', 358 | src: '*.js', 359 | dest: '.tmp/concat/scripts' 360 | }] 361 | } 362 | }, 363 | 364 | // Replace Google CDN references 365 | cdnify: { 366 | dist: { 367 | html: ['<%= yeoman.dist %>/*.html'] 368 | } 369 | }, 370 | 371 | // Copies remaining files to places other tasks can use 372 | copy: { 373 | dist: { 374 | files: [{ 375 | expand: true, 376 | dot: true, 377 | cwd: '<%= yeoman.app %>', 378 | dest: '<%= yeoman.dist %>', 379 | src: [ 380 | '*.{ico,png,txt}', 381 | '.htaccess', 382 | '*.html', 383 | 'views/{,*/}*.html', 384 | 'images/{,*/}*.{webp}', 385 | 'styles/fonts/{,*/}*.*' 386 | ] 387 | }, { 388 | expand: true, 389 | cwd: '.tmp/images', 390 | dest: '<%= yeoman.dist %>/images', 391 | src: ['generated/*'] 392 | }, { 393 | expand: true, 394 | cwd: '.', 395 | src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*', 396 | dest: '<%= yeoman.dist %>' 397 | }] 398 | }, 399 | styles: { 400 | expand: true, 401 | cwd: '<%= yeoman.app %>/styles', 402 | dest: '.tmp/styles/', 403 | src: '{,*/}*.css' 404 | } 405 | }, 406 | 407 | // Test settings 408 | karma: { 409 | unit: { 410 | configFile: 'test/karma.conf.js', 411 | singleRun: true 412 | } 413 | } 414 | }); 415 | 416 | 417 | grunt.registerTask('serve', 'Compile then start a connect web server', function (target) { 418 | if (target === 'dist') { 419 | return grunt.task.run(['build', 'connect:dist:keepalive']); 420 | } 421 | 422 | grunt.task.run([ 423 | 'clean:server', 424 | 'wiredep', 425 | 'compass:server', 426 | 'autoprefixer:server', 427 | 'connect:livereload', 428 | 'watch' 429 | ]); 430 | }); 431 | 432 | grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) { 433 | grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); 434 | grunt.task.run(['serve:' + target]); 435 | }); 436 | 437 | grunt.registerTask('test', [ 438 | 'clean:server', 439 | 'wiredep', 440 | 'compass', 441 | 'autoprefixer', 442 | 'connect:test', 443 | 'karma' 444 | ]); 445 | 446 | grunt.registerTask('build', [ 447 | 'clean:dist', 448 | 'wiredep', 449 | 'useminPrepare', 450 | 'compass:dist', 451 | 'imagemin', 452 | 'svgmin', 453 | 'autoprefixer', 454 | 'concat', 455 | 'ngAnnotate', 456 | 'copy:dist', 457 | 'cdnify', 458 | 'cssmin', 459 | 'uglify', 460 | 'filerev', 461 | 'usemin', 462 | 'htmlmin' 463 | ]); 464 | 465 | grunt.registerTask('default', [ 466 | 'newer:jshint', 467 | 'test', 468 | 'build' 469 | ]); 470 | }; 471 | -------------------------------------------------------------------------------- /client/app/.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee -------------------------------------------------------------------------------- /client/app/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
Sorry, but the page you were trying to view does not exist.
146 |It looks like this was the result of either:
147 |{{title}}
7 |Votes: {{option.votes}}
15 |{{title}}
7 |10 | 11 | 12 |
13 |