diff --git a/app/assets/images/admin/file_types/1358029801_css.png b/app/assets/images/admin/file_types/1358029801_css.png
new file mode 100644
index 0000000..42b4528
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029801_css.png differ
diff --git a/app/assets/images/admin/file_types/1358029807_docx.png b/app/assets/images/admin/file_types/1358029807_docx.png
new file mode 100644
index 0000000..7aa40bc
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029807_docx.png differ
diff --git a/app/assets/images/admin/file_types/1358029820_psd.png b/app/assets/images/admin/file_types/1358029820_psd.png
new file mode 100644
index 0000000..4cdf434
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029820_psd.png differ
diff --git a/app/assets/images/admin/file_types/1358029824_jpg.png b/app/assets/images/admin/file_types/1358029824_jpg.png
new file mode 100644
index 0000000..943858c
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029824_jpg.png differ
diff --git a/app/assets/images/admin/file_types/1358029827_generic.png b/app/assets/images/admin/file_types/1358029827_generic.png
new file mode 100644
index 0000000..b91b1be
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029827_generic.png differ
diff --git a/app/assets/images/admin/file_types/1358029830_doc.png b/app/assets/images/admin/file_types/1358029830_doc.png
new file mode 100644
index 0000000..983cc8a
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029830_doc.png differ
diff --git a/app/assets/images/admin/file_types/1358029834_aac.png b/app/assets/images/admin/file_types/1358029834_aac.png
new file mode 100644
index 0000000..4d32144
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029834_aac.png differ
diff --git a/app/assets/images/admin/file_types/1358029839_wmv.png b/app/assets/images/admin/file_types/1358029839_wmv.png
new file mode 100644
index 0000000..27d2d25
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029839_wmv.png differ
diff --git a/app/assets/images/admin/file_types/1358029845_raw.png b/app/assets/images/admin/file_types/1358029845_raw.png
new file mode 100644
index 0000000..5fd1b19
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029845_raw.png differ
diff --git a/app/assets/images/admin/file_types/1358029848_tar.png b/app/assets/images/admin/file_types/1358029848_tar.png
new file mode 100644
index 0000000..34f0d31
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029848_tar.png differ
diff --git a/app/assets/images/admin/file_types/1358029854_tiff.png b/app/assets/images/admin/file_types/1358029854_tiff.png
new file mode 100644
index 0000000..f5c07d1
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029854_tiff.png differ
diff --git a/app/assets/images/admin/file_types/1358029858_rtf.png b/app/assets/images/admin/file_types/1358029858_rtf.png
new file mode 100644
index 0000000..7fe2fe3
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029858_rtf.png differ
diff --git a/app/assets/images/admin/file_types/1358029860_rtf.png b/app/assets/images/admin/file_types/1358029860_rtf.png
new file mode 100644
index 0000000..7fe2fe3
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029860_rtf.png differ
diff --git a/app/assets/images/admin/file_types/1358029868_js.png b/app/assets/images/admin/file_types/1358029868_js.png
new file mode 100644
index 0000000..6fed77c
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029868_js.png differ
diff --git a/app/assets/images/admin/file_types/1358029872_gif.png b/app/assets/images/admin/file_types/1358029872_gif.png
new file mode 100644
index 0000000..c3940d2
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029872_gif.png differ
diff --git a/app/assets/images/admin/file_types/1358029874_aiff.png b/app/assets/images/admin/file_types/1358029874_aiff.png
new file mode 100644
index 0000000..721a436
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029874_aiff.png differ
diff --git a/app/assets/images/admin/file_types/1358029878_gzip.png b/app/assets/images/admin/file_types/1358029878_gzip.png
new file mode 100644
index 0000000..af4ece5
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029878_gzip.png differ
diff --git a/app/assets/images/admin/file_types/1358029881_ma.png b/app/assets/images/admin/file_types/1358029881_ma.png
new file mode 100644
index 0000000..fc4af76
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029881_ma.png differ
diff --git a/app/assets/images/admin/file_types/1358029885_mp.png b/app/assets/images/admin/file_types/1358029885_mp.png
new file mode 100644
index 0000000..122aa42
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029885_mp.png differ
diff --git a/app/assets/images/admin/file_types/1358029888_php.png b/app/assets/images/admin/file_types/1358029888_php.png
new file mode 100644
index 0000000..18b1e1d
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029888_php.png differ
diff --git a/app/assets/images/admin/file_types/1358029892_mpeg.png b/app/assets/images/admin/file_types/1358029892_mpeg.png
new file mode 100644
index 0000000..1e072fb
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029892_mpeg.png differ
diff --git a/app/assets/images/admin/file_types/1358029894_mov.png b/app/assets/images/admin/file_types/1358029894_mov.png
new file mode 100644
index 0000000..0d04088
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029894_mov.png differ
diff --git a/app/assets/images/admin/file_types/1358029899_html.png b/app/assets/images/admin/file_types/1358029899_html.png
new file mode 100644
index 0000000..6699269
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029899_html.png differ
diff --git a/app/assets/images/admin/file_types/1358029903_avi.png b/app/assets/images/admin/file_types/1358029903_avi.png
new file mode 100644
index 0000000..233252f
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029903_avi.png differ
diff --git a/app/assets/images/admin/file_types/1358029906_txt.png b/app/assets/images/admin/file_types/1358029906_txt.png
new file mode 100644
index 0000000..98058ea
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029906_txt.png differ
diff --git a/app/assets/images/admin/file_types/1358029912_wav.png b/app/assets/images/admin/file_types/1358029912_wav.png
new file mode 100644
index 0000000..07bd3b4
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029912_wav.png differ
diff --git a/app/assets/images/admin/file_types/1358029916_generic.png b/app/assets/images/admin/file_types/1358029916_generic.png
new file mode 100644
index 0000000..b91b1be
Binary files /dev/null and b/app/assets/images/admin/file_types/1358029916_generic.png differ
diff --git a/app/assets/images/admin/file_types/_blank.png b/app/assets/images/admin/file_types/_blank.png
new file mode 100755
index 0000000..ceebb42
Binary files /dev/null and b/app/assets/images/admin/file_types/_blank.png differ
diff --git a/app/assets/images/admin/file_types/_page.png b/app/assets/images/admin/file_types/_page.png
new file mode 100755
index 0000000..349e29f
Binary files /dev/null and b/app/assets/images/admin/file_types/_page.png differ
diff --git a/app/assets/images/admin/file_types/aac.png b/app/assets/images/admin/file_types/aac.png
new file mode 100755
index 0000000..a0720ca
Binary files /dev/null and b/app/assets/images/admin/file_types/aac.png differ
diff --git a/app/assets/images/admin/file_types/ai.png b/app/assets/images/admin/file_types/ai.png
new file mode 100644
index 0000000..f28c86a
Binary files /dev/null and b/app/assets/images/admin/file_types/ai.png differ
diff --git a/app/assets/images/admin/file_types/bmp.png b/app/assets/images/admin/file_types/bmp.png
new file mode 100644
index 0000000..bb852d2
Binary files /dev/null and b/app/assets/images/admin/file_types/bmp.png differ
diff --git a/app/assets/images/admin/file_types/eps.png b/app/assets/images/admin/file_types/eps.png
new file mode 100644
index 0000000..26ad468
Binary files /dev/null and b/app/assets/images/admin/file_types/eps.png differ
diff --git a/app/assets/images/admin/file_types/gif.png b/app/assets/images/admin/file_types/gif.png
new file mode 100644
index 0000000..c02d274
Binary files /dev/null and b/app/assets/images/admin/file_types/gif.png differ
diff --git a/app/assets/images/admin/file_types/icns.png b/app/assets/images/admin/file_types/icns.png
new file mode 100644
index 0000000..a2a36a6
Binary files /dev/null and b/app/assets/images/admin/file_types/icns.png differ
diff --git a/app/assets/images/admin/file_types/ico.png b/app/assets/images/admin/file_types/ico.png
new file mode 100644
index 0000000..7b3e4ca
Binary files /dev/null and b/app/assets/images/admin/file_types/ico.png differ
diff --git a/app/assets/images/admin/file_types/jpeg.png b/app/assets/images/admin/file_types/jpeg.png
new file mode 100644
index 0000000..a5c596e
Binary files /dev/null and b/app/assets/images/admin/file_types/jpeg.png differ
diff --git a/app/assets/images/admin/file_types/jpg.png b/app/assets/images/admin/file_types/jpg.png
new file mode 100644
index 0000000..a5c596e
Binary files /dev/null and b/app/assets/images/admin/file_types/jpg.png differ
diff --git a/app/assets/images/admin/file_types/key.png b/app/assets/images/admin/file_types/key.png
new file mode 100644
index 0000000..d2f6a06
Binary files /dev/null and b/app/assets/images/admin/file_types/key.png differ
diff --git a/app/assets/images/admin/file_types/kth.png b/app/assets/images/admin/file_types/kth.png
new file mode 100644
index 0000000..28acd08
Binary files /dev/null and b/app/assets/images/admin/file_types/kth.png differ
diff --git a/app/assets/images/admin/file_types/m4v.png b/app/assets/images/admin/file_types/m4v.png
new file mode 100644
index 0000000..ede0b74
Binary files /dev/null and b/app/assets/images/admin/file_types/m4v.png differ
diff --git a/app/assets/images/admin/file_types/md.png b/app/assets/images/admin/file_types/md.png
new file mode 100644
index 0000000..f931895
Binary files /dev/null and b/app/assets/images/admin/file_types/md.png differ
diff --git a/app/assets/images/admin/file_types/mpg.png b/app/assets/images/admin/file_types/mpg.png
new file mode 100644
index 0000000..b1582c6
Binary files /dev/null and b/app/assets/images/admin/file_types/mpg.png differ
diff --git a/app/assets/images/admin/file_types/nmbtemplate.png b/app/assets/images/admin/file_types/nmbtemplate.png
new file mode 100644
index 0000000..3daa184
Binary files /dev/null and b/app/assets/images/admin/file_types/nmbtemplate.png differ
diff --git a/app/assets/images/admin/file_types/numbers.png b/app/assets/images/admin/file_types/numbers.png
new file mode 100644
index 0000000..d3d4332
Binary files /dev/null and b/app/assets/images/admin/file_types/numbers.png differ
diff --git a/app/assets/images/admin/file_types/odf.png b/app/assets/images/admin/file_types/odf.png
new file mode 100755
index 0000000..4739952
Binary files /dev/null and b/app/assets/images/admin/file_types/odf.png differ
diff --git a/app/assets/images/admin/file_types/ods.png b/app/assets/images/admin/file_types/ods.png
new file mode 100755
index 0000000..5f09b0c
Binary files /dev/null and b/app/assets/images/admin/file_types/ods.png differ
diff --git a/app/assets/images/admin/file_types/odt.png b/app/assets/images/admin/file_types/odt.png
new file mode 100755
index 0000000..607bae5
Binary files /dev/null and b/app/assets/images/admin/file_types/odt.png differ
diff --git a/app/assets/images/admin/file_types/otp.png b/app/assets/images/admin/file_types/otp.png
new file mode 100755
index 0000000..655bc83
Binary files /dev/null and b/app/assets/images/admin/file_types/otp.png differ
diff --git a/app/assets/images/admin/file_types/ots.png b/app/assets/images/admin/file_types/ots.png
new file mode 100755
index 0000000..c59ad95
Binary files /dev/null and b/app/assets/images/admin/file_types/ots.png differ
diff --git a/app/assets/images/admin/file_types/ott.png b/app/assets/images/admin/file_types/ott.png
new file mode 100755
index 0000000..18dd9fa
Binary files /dev/null and b/app/assets/images/admin/file_types/ott.png differ
diff --git a/app/assets/images/admin/file_types/pages.png b/app/assets/images/admin/file_types/pages.png
new file mode 100644
index 0000000..1317892
Binary files /dev/null and b/app/assets/images/admin/file_types/pages.png differ
diff --git a/app/assets/images/admin/file_types/pdf.png b/app/assets/images/admin/file_types/pdf.png
new file mode 100644
index 0000000..098355b
Binary files /dev/null and b/app/assets/images/admin/file_types/pdf.png differ
diff --git a/app/assets/images/admin/file_types/php.png b/app/assets/images/admin/file_types/php.png
new file mode 100755
index 0000000..144b543
Binary files /dev/null and b/app/assets/images/admin/file_types/php.png differ
diff --git a/app/assets/images/admin/file_types/png.png b/app/assets/images/admin/file_types/png.png
new file mode 100644
index 0000000..b9876ba
Binary files /dev/null and b/app/assets/images/admin/file_types/png.png differ
diff --git a/app/assets/images/admin/file_types/psd.png b/app/assets/images/admin/file_types/psd.png
new file mode 100644
index 0000000..5ae881d
Binary files /dev/null and b/app/assets/images/admin/file_types/psd.png differ
diff --git a/app/assets/images/admin/file_types/sql.png b/app/assets/images/admin/file_types/sql.png
new file mode 100644
index 0000000..3f53116
Binary files /dev/null and b/app/assets/images/admin/file_types/sql.png differ
diff --git a/app/assets/images/admin/file_types/tar.gz.png b/app/assets/images/admin/file_types/tar.gz.png
new file mode 100644
index 0000000..d9deafa
Binary files /dev/null and b/app/assets/images/admin/file_types/tar.gz.png differ
diff --git a/app/assets/images/admin/file_types/tar.png b/app/assets/images/admin/file_types/tar.png
new file mode 100644
index 0000000..d9deafa
Binary files /dev/null and b/app/assets/images/admin/file_types/tar.png differ
diff --git a/app/assets/images/admin/file_types/template.png b/app/assets/images/admin/file_types/template.png
new file mode 100644
index 0000000..e34f334
Binary files /dev/null and b/app/assets/images/admin/file_types/template.png differ
diff --git a/app/assets/images/admin/file_types/tiff.png b/app/assets/images/admin/file_types/tiff.png
new file mode 100644
index 0000000..f84bfcd
Binary files /dev/null and b/app/assets/images/admin/file_types/tiff.png differ
diff --git a/app/assets/images/admin/file_types/zip.png b/app/assets/images/admin/file_types/zip.png
new file mode 100644
index 0000000..d9deafa
Binary files /dev/null and b/app/assets/images/admin/file_types/zip.png differ
diff --git a/app/assets/javascripts/admin copy.coffee b/app/assets/javascripts/admin copy.coffee
new file mode 100644
index 0000000..2455e9b
--- /dev/null
+++ b/app/assets/javascripts/admin copy.coffee
@@ -0,0 +1,36 @@
+
+#= require jquery
+#= require jquery_ujs
+# require turbolinks
+
+#= require bootstrap
+
+$(document).ready ->
+
+ $(document).on 'click', 'input.datepicker', ->
+ $(this).datetimepicker(
+ language: 'fr'
+ pickTime: false
+ ).focus();
+
+ $(document).on 'click', 'input.datetimepicker', ->
+ $(this).datetimepicker(
+ use24hours: true
+ format: 'DD/MM/YYYY hh:mm'
+ minuteStepping:15
+ language: 'fr'
+ ).focus();
+
+
+ $(document).on 'click', 'input.timepicker', ->
+ $(this).datetimepicker(
+ use24hours: true
+ format: 'DD/MM/YYYY hh:mm'
+ minuteStepping:15
+ pickDate: false
+ language: 'fr'
+ ).focus();
+
+
+
+
diff --git a/app/assets/javascripts/admin.coffee b/app/assets/javascripts/admin.coffee
index b9ec9cc..de53fc0 100644
--- a/app/assets/javascripts/admin.coffee
+++ b/app/assets/javascripts/admin.coffee
@@ -27,6 +27,8 @@
#= require nested_fields
+#= require_tree ./note_files
+
$(document).ready ->
$(document).on 'click', 'input.datepicker', ->
diff --git a/app/assets/javascripts/connexion.coffee b/app/assets/javascripts/connexion.coffee
new file mode 100644
index 0000000..c0f46fb
--- /dev/null
+++ b/app/assets/javascripts/connexion.coffee
@@ -0,0 +1,20 @@
+#= require jquery
+
+#= require bootstrap
+
+#= require ./shared/jquery.backstretch.js
+
+
+place = ->
+ margin = ($(window).height() - ($(".form-signin").outerHeight()+60) )/ 2
+
+ $(".form-signin").css("margin-top" : margin+"px")
+
+
+$(document).ready ->
+ place();
+ $(".form-signin").hide()
+ $(".form-signin").css("opacity",1 )
+ $(".form-signin").fadeIn(1500)
+ $(window).on "resize", ->
+ place();
\ No newline at end of file
diff --git a/app/assets/javascripts/note_files/ajquery.ui.widget.js b/app/assets/javascripts/note_files/ajquery.ui.widget.js
new file mode 100755
index 0000000..886aff6
--- /dev/null
+++ b/app/assets/javascripts/note_files/ajquery.ui.widget.js
@@ -0,0 +1,528 @@
+/*
+ * jQuery UI Widget 1.9.1+amd
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * http://api.jqueryui.com/jQuery.widget/
+ */
+
+(function (factory) {
+ if (typeof define === "function" && define.amd) {
+ // Register as an anonymous AMD module:
+ define(["jquery"], factory);
+ } else {
+ // Browser globals:
+ factory(jQuery);
+ }
+}(function( $, undefined ) {
+
+var uuid = 0,
+ slice = Array.prototype.slice,
+ _cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ _cleanData( elems );
+};
+
+$.widget = function( name, base, prototype ) {
+ var fullName, existingConstructor, constructor, basePrototype,
+ namespace = name.split( "." )[ 0 ];
+
+ name = name.split( "." )[ 1 ];
+ fullName = namespace + "-" + name;
+
+ if ( !prototype ) {
+ prototype = base;
+ base = $.Widget;
+ }
+
+ // create selector for plugin
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+ return !!$.data( elem, fullName );
+ };
+
+ $[ namespace ] = $[ namespace ] || {};
+ existingConstructor = $[ namespace ][ name ];
+ constructor = $[ namespace ][ name ] = function( options, element ) {
+ // allow instantiation without "new" keyword
+ if ( !this._createWidget ) {
+ return new constructor( options, element );
+ }
+
+ // allow instantiation without initializing for simple inheritance
+ // must use "new" keyword (the code above always passes args)
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+ };
+ // extend with the existing constructor to carry over any static properties
+ $.extend( constructor, existingConstructor, {
+ version: prototype.version,
+ // copy the object used to create the prototype in case we need to
+ // redefine the widget later
+ _proto: $.extend( {}, prototype ),
+ // track widgets that inherit from this widget in case this widget is
+ // redefined after a widget inherits from it
+ _childConstructors: []
+ });
+
+ basePrototype = new base();
+ // we need to make the options hash a property directly on the new instance
+ // otherwise we'll modify the options hash on the prototype that we're
+ // inheriting from
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
+ $.each( prototype, function( prop, value ) {
+ if ( $.isFunction( value ) ) {
+ prototype[ prop ] = (function() {
+ var _super = function() {
+ return base.prototype[ prop ].apply( this, arguments );
+ },
+ _superApply = function( args ) {
+ return base.prototype[ prop ].apply( this, args );
+ };
+ return function() {
+ var __super = this._super,
+ __superApply = this._superApply,
+ returnValue;
+
+ this._super = _super;
+ this._superApply = _superApply;
+
+ returnValue = value.apply( this, arguments );
+
+ this._super = __super;
+ this._superApply = __superApply;
+
+ return returnValue;
+ };
+ })();
+ }
+ });
+ constructor.prototype = $.widget.extend( basePrototype, {
+ // TODO: remove support for widgetEventPrefix
+ // always use the name + a colon as the prefix, e.g., draggable:start
+ // don't prefix for widgets that aren't DOM-based
+ widgetEventPrefix: basePrototype.widgetEventPrefix || name
+ }, prototype, {
+ constructor: constructor,
+ namespace: namespace,
+ widgetName: name,
+ // TODO remove widgetBaseClass, see #8155
+ widgetBaseClass: fullName,
+ widgetFullName: fullName
+ });
+
+ // If this widget is being redefined then we need to find all widgets that
+ // are inheriting from it and redefine all of them so that they inherit from
+ // the new version of this widget. We're essentially trying to replace one
+ // level in the prototype chain.
+ if ( existingConstructor ) {
+ $.each( existingConstructor._childConstructors, function( i, child ) {
+ var childPrototype = child.prototype;
+
+ // redefine the child widget using the same prototype that was
+ // originally used, but inherit from the new version of the base
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+ });
+ // remove the list of existing child constructors from the old constructor
+ // so the old child constructors can be garbage collected
+ delete existingConstructor._childConstructors;
+ } else {
+ base._childConstructors.push( constructor );
+ }
+
+ $.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+ var input = slice.call( arguments, 1 ),
+ inputIndex = 0,
+ inputLength = input.length,
+ key,
+ value;
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
+ for ( key in input[ inputIndex ] ) {
+ value = input[ inputIndex ][ key ];
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+ // Clone objects
+ if ( $.isPlainObject( value ) ) {
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
+ $.widget.extend( {}, target[ key ], value ) :
+ // Don't extend strings, arrays, etc. with objects
+ $.widget.extend( {}, value );
+ // Copy everything else by reference
+ } else {
+ target[ key ] = value;
+ }
+ }
+ }
+ }
+ return target;
+};
+
+$.widget.bridge = function( name, object ) {
+ var fullName = object.prototype.widgetFullName;
+ $.fn[ name ] = function( options ) {
+ var isMethodCall = typeof options === "string",
+ args = slice.call( arguments, 1 ),
+ returnValue = this;
+
+ // allow multiple hashes to be passed on init
+ options = !isMethodCall && args.length ?
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
+ options;
+
+ if ( isMethodCall ) {
+ this.each(function() {
+ var methodValue,
+ instance = $.data( this, fullName );
+ if ( !instance ) {
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
+ "attempted to call method '" + options + "'" );
+ }
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+ }
+ methodValue = instance[ options ].apply( instance, args );
+ if ( methodValue !== instance && methodValue !== undefined ) {
+ returnValue = methodValue && methodValue.jquery ?
+ returnValue.pushStack( methodValue.get() ) :
+ methodValue;
+ return false;
+ }
+ });
+ } else {
+ this.each(function() {
+ var instance = $.data( this, fullName );
+ if ( instance ) {
+ instance.option( options || {} )._init();
+ } else {
+ new object( options, this );
+ }
+ });
+ }
+
+ return returnValue;
+ };
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+ widgetName: "widget",
+ widgetEventPrefix: "",
+ defaultElement: "
",
+ options: {
+ disabled: false,
+
+ // callbacks
+ create: null
+ },
+ _createWidget: function( options, element ) {
+ element = $( element || this.defaultElement || this )[ 0 ];
+ this.element = $( element );
+ this.uuid = uuid++;
+ this.eventNamespace = "." + this.widgetName + this.uuid;
+ this.options = $.widget.extend( {},
+ this.options,
+ this._getCreateOptions(),
+ options );
+
+ this.bindings = $();
+ this.hoverable = $();
+ this.focusable = $();
+
+ if ( element !== this ) {
+ // 1.9 BC for #7810
+ // TODO remove dual storage
+ $.data( element, this.widgetName, this );
+ $.data( element, this.widgetFullName, this );
+ this._on( this.element, {
+ remove: function( event ) {
+ if ( event.target === element ) {
+ this.destroy();
+ }
+ }
+ });
+ this.document = $( element.style ?
+ // element within the document
+ element.ownerDocument :
+ // element is window or document
+ element.document || element );
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+ }
+
+ this._create();
+ this._trigger( "create", null, this._getCreateEventData() );
+ this._init();
+ },
+ _getCreateOptions: $.noop,
+ _getCreateEventData: $.noop,
+ _create: $.noop,
+ _init: $.noop,
+
+ destroy: function() {
+ this._destroy();
+ // we can probably remove the unbind calls in 2.0
+ // all event bindings should go through this._on()
+ this.element
+ .unbind( this.eventNamespace )
+ // 1.9 BC for #7810
+ // TODO remove dual storage
+ .removeData( this.widgetName )
+ .removeData( this.widgetFullName )
+ // support: jquery <1.6.3
+ // http://bugs.jquery.com/ticket/9413
+ .removeData( $.camelCase( this.widgetFullName ) );
+ this.widget()
+ .unbind( this.eventNamespace )
+ .removeAttr( "aria-disabled" )
+ .removeClass(
+ this.widgetFullName + "-disabled " +
+ "ui-state-disabled" );
+
+ // clean up events and states
+ this.bindings.unbind( this.eventNamespace );
+ this.hoverable.removeClass( "ui-state-hover" );
+ this.focusable.removeClass( "ui-state-focus" );
+ },
+ _destroy: $.noop,
+
+ widget: function() {
+ return this.element;
+ },
+
+ option: function( key, value ) {
+ var options = key,
+ parts,
+ curOption,
+ i;
+
+ if ( arguments.length === 0 ) {
+ // don't return a reference to the internal hash
+ return $.widget.extend( {}, this.options );
+ }
+
+ if ( typeof key === "string" ) {
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+ options = {};
+ parts = key.split( "." );
+ key = parts.shift();
+ if ( parts.length ) {
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+ for ( i = 0; i < parts.length - 1; i++ ) {
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+ curOption = curOption[ parts[ i ] ];
+ }
+ key = parts.pop();
+ if ( value === undefined ) {
+ return curOption[ key ] === undefined ? null : curOption[ key ];
+ }
+ curOption[ key ] = value;
+ } else {
+ if ( value === undefined ) {
+ return this.options[ key ] === undefined ? null : this.options[ key ];
+ }
+ options[ key ] = value;
+ }
+ }
+
+ this._setOptions( options );
+
+ return this;
+ },
+ _setOptions: function( options ) {
+ var key;
+
+ for ( key in options ) {
+ this._setOption( key, options[ key ] );
+ }
+
+ return this;
+ },
+ _setOption: function( key, value ) {
+ this.options[ key ] = value;
+
+ if ( key === "disabled" ) {
+ this.widget()
+ .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
+ .attr( "aria-disabled", value );
+ this.hoverable.removeClass( "ui-state-hover" );
+ this.focusable.removeClass( "ui-state-focus" );
+ }
+
+ return this;
+ },
+
+ enable: function() {
+ return this._setOption( "disabled", false );
+ },
+ disable: function() {
+ return this._setOption( "disabled", true );
+ },
+
+ _on: function( element, handlers ) {
+ var delegateElement,
+ instance = this;
+ // no element argument, shuffle and use this.element
+ if ( !handlers ) {
+ handlers = element;
+ element = this.element;
+ delegateElement = this.widget();
+ } else {
+ // accept selectors, DOM elements
+ element = delegateElement = $( element );
+ this.bindings = this.bindings.add( element );
+ }
+
+ $.each( handlers, function( event, handler ) {
+ function handlerProxy() {
+ // allow widgets to customize the disabled handling
+ // - disabled as an array instead of boolean
+ // - disabled class as method for disabling individual parts
+ if ( instance.options.disabled === true ||
+ $( this ).hasClass( "ui-state-disabled" ) ) {
+ return;
+ }
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
+ .apply( instance, arguments );
+ }
+
+ // copy the guid so direct unbinding works
+ if ( typeof handler !== "string" ) {
+ handlerProxy.guid = handler.guid =
+ handler.guid || handlerProxy.guid || $.guid++;
+ }
+
+ var match = event.match( /^(\w+)\s*(.*)$/ ),
+ eventName = match[1] + instance.eventNamespace,
+ selector = match[2];
+ if ( selector ) {
+ delegateElement.delegate( selector, eventName, handlerProxy );
+ } else {
+ element.bind( eventName, handlerProxy );
+ }
+ });
+ },
+
+ _off: function( element, eventName ) {
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+ element.unbind( eventName ).undelegate( eventName );
+ },
+
+ _delay: function( handler, delay ) {
+ function handlerProxy() {
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
+ .apply( instance, arguments );
+ }
+ var instance = this;
+ return setTimeout( handlerProxy, delay || 0 );
+ },
+
+ _hoverable: function( element ) {
+ this.hoverable = this.hoverable.add( element );
+ this._on( element, {
+ mouseenter: function( event ) {
+ $( event.currentTarget ).addClass( "ui-state-hover" );
+ },
+ mouseleave: function( event ) {
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
+ }
+ });
+ },
+
+ _focusable: function( element ) {
+ this.focusable = this.focusable.add( element );
+ this._on( element, {
+ focusin: function( event ) {
+ $( event.currentTarget ).addClass( "ui-state-focus" );
+ },
+ focusout: function( event ) {
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
+ }
+ });
+ },
+
+ _trigger: function( type, event, data ) {
+ var prop, orig,
+ callback = this.options[ type ];
+
+ data = data || {};
+ event = $.Event( event );
+ event.type = ( type === this.widgetEventPrefix ?
+ type :
+ this.widgetEventPrefix + type ).toLowerCase();
+ // the original event may come from any element
+ // so we need to reset the target on the new event
+ event.target = this.element[ 0 ];
+
+ // copy original event properties over to the new event
+ orig = event.originalEvent;
+ if ( orig ) {
+ for ( prop in orig ) {
+ if ( !( prop in event ) ) {
+ event[ prop ] = orig[ prop ];
+ }
+ }
+ }
+
+ this.element.trigger( event, data );
+ return !( $.isFunction( callback ) &&
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+ event.isDefaultPrevented() );
+ }
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+ if ( typeof options === "string" ) {
+ options = { effect: options };
+ }
+ var hasOptions,
+ effectName = !options ?
+ method :
+ options === true || typeof options === "number" ?
+ defaultEffect :
+ options.effect || defaultEffect;
+ options = options || {};
+ if ( typeof options === "number" ) {
+ options = { duration: options };
+ }
+ hasOptions = !$.isEmptyObject( options );
+ options.complete = callback;
+ if ( options.delay ) {
+ element.delay( options.delay );
+ }
+ if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
+ element[ method ]( options );
+ } else if ( effectName !== method && element[ effectName ] ) {
+ element[ effectName ]( options.duration, options.easing, callback );
+ } else {
+ element.queue(function( next ) {
+ $( this )[ method ]();
+ if ( callback ) {
+ callback.call( element[ 0 ] );
+ }
+ next();
+ });
+ }
+ };
+});
+
+// DEPRECATED
+if ( $.uiBackCompat !== false ) {
+ $.Widget.prototype._getCreateOptions = function() {
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+ };
+}
+
+}));
diff --git a/app/assets/javascripts/note_files/jquery.fileupload.js b/app/assets/javascripts/note_files/jquery.fileupload.js
new file mode 100755
index 0000000..bc96a07
--- /dev/null
+++ b/app/assets/javascripts/note_files/jquery.fileupload.js
@@ -0,0 +1,1113 @@
+/*
+ * jQuery File Upload Plugin 5.19.7
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+/*jslint nomen: true, unparam: true, regexp: true */
+/*global define, window, document, File, Blob, FormData, location */
+
+(function (factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ // Register as an anonymous AMD module:
+ define([
+ 'jquery',
+ 'jquery.ui.widget'
+ ], factory);
+ } else {
+ // Browser globals:
+ factory(window.jQuery);
+ }
+}(function ($) {
+ 'use strict';
+
+ // The FileReader API is not actually used, but works as feature detection,
+ // as e.g. Safari supports XHR file uploads via the FormData API,
+ // but not non-multipart XHR file uploads:
+ $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
+ $.support.xhrFormDataFileUpload = !!window.FormData;
+
+ // The fileupload widget listens for change events on file input fields defined
+ // via fileInput setting and paste or drop events of the given dropZone.
+ // In addition to the default jQuery Widget methods, the fileupload widget
+ // exposes the "add" and "send" methods, to add or directly send files using
+ // the fileupload API.
+ // By default, files added via file input selection, paste, drag & drop or
+ // "add" method are uploaded immediately, but it is possible to override
+ // the "add" callback option to queue file uploads.
+ $.widget('blueimp.fileupload', {
+
+ options: {
+ // The drop target element(s), by the default the complete document.
+ // Set to null to disable drag & drop support:
+ dropZone: $(document),
+ // The paste target element(s), by the default the complete document.
+ // Set to null to disable paste support:
+ pasteZone: $(document),
+ // The file input field(s), that are listened to for change events.
+ // If undefined, it is set to the file input fields inside
+ // of the widget element on plugin initialization.
+ // Set to null to disable the change listener.
+ fileInput: undefined,
+ // By default, the file input field is replaced with a clone after
+ // each input field change event. This is required for iframe transport
+ // queues and allows change events to be fired for the same file
+ // selection, but can be disabled by setting the following option to false:
+ replaceFileInput: true,
+ // The parameter name for the file form data (the request argument name).
+ // If undefined or empty, the name property of the file input field is
+ // used, or "files[]" if the file input name property is also empty,
+ // can be a string or an array of strings:
+ paramName: undefined,
+ // By default, each file of a selection is uploaded using an individual
+ // request for XHR type uploads. Set to false to upload file
+ // selections in one request each:
+ singleFileUploads: true,
+ // To limit the number of files uploaded with one XHR request,
+ // set the following option to an integer greater than 0:
+ limitMultiFileUploads: undefined,
+ // Set the following option to true to issue all file upload requests
+ // in a sequential order:
+ sequentialUploads: false,
+ // To limit the number of concurrent uploads,
+ // set the following option to an integer greater than 0:
+ limitConcurrentUploads: undefined,
+ // Set the following option to true to force iframe transport uploads:
+ forceIframeTransport: false,
+ // Set the following option to the location of a redirect url on the
+ // origin server, for cross-domain iframe transport uploads:
+ redirect: undefined,
+ // The parameter name for the redirect url, sent as part of the form
+ // data and set to 'redirect' if this option is empty:
+ redirectParamName: undefined,
+ // Set the following option to the location of a postMessage window,
+ // to enable postMessage transport uploads:
+ postMessage: undefined,
+ // By default, XHR file uploads are sent as multipart/form-data.
+ // The iframe transport is always using multipart/form-data.
+ // Set to false to enable non-multipart XHR uploads:
+ multipart: true,
+ // To upload large files in smaller chunks, set the following option
+ // to a preferred maximum chunk size. If set to 0, null or undefined,
+ // or the browser does not support the required Blob API, files will
+ // be uploaded as a whole.
+ maxChunkSize: undefined,
+ // When a non-multipart upload or a chunked multipart upload has been
+ // aborted, this option can be used to resume the upload by setting
+ // it to the size of the already uploaded bytes. This option is most
+ // useful when modifying the options object inside of the "add" or
+ // "send" callbacks, as the options are cloned for each file upload.
+ uploadedBytes: undefined,
+ // By default, failed (abort or error) file uploads are removed from the
+ // global progress calculation. Set the following option to false to
+ // prevent recalculating the global progress data:
+ recalculateProgress: true,
+ // Interval in milliseconds to calculate and trigger progress events:
+ progressInterval: 100,
+ // Interval in milliseconds to calculate progress bitrate:
+ bitrateInterval: 500,
+
+ // Additional form data to be sent along with the file uploads can be set
+ // using this option, which accepts an array of objects with name and
+ // value properties, a function returning such an array, a FormData
+ // object (for XHR file uploads), or a simple object.
+ // The form of the first fileInput is given as parameter to the function:
+ formData: function (form) {
+ return form.serializeArray();
+ },
+
+ // The add callback is invoked as soon as files are added to the fileupload
+ // widget (via file input selection, drag & drop, paste or add API call).
+ // If the singleFileUploads option is enabled, this callback will be
+ // called once for each file in the selection for XHR file uplaods, else
+ // once for each file selection.
+ // The upload starts when the submit method is invoked on the data parameter.
+ // The data object contains a files property holding the added files
+ // and allows to override plugin options as well as define ajax settings.
+ // Listeners for this callback can also be bound the following way:
+ // .bind('fileuploadadd', func);
+ // data.submit() returns a Promise object and allows to attach additional
+ // handlers using jQuery's Deferred callbacks:
+ // data.submit().done(func).fail(func).always(func);
+ add: function (e, data) {
+ data.submit();
+ },
+
+ // Other callbacks:
+ // Callback for the submit event of each file upload:
+ // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
+ // Callback for the start of each file upload request:
+ // send: function (e, data) {}, // .bind('fileuploadsend', func);
+ // Callback for successful uploads:
+ // done: function (e, data) {}, // .bind('fileuploaddone', func);
+ // Callback for failed (abort or error) uploads:
+ // fail: function (e, data) {}, // .bind('fileuploadfail', func);
+ // Callback for completed (success, abort or error) requests:
+ // always: function (e, data) {}, // .bind('fileuploadalways', func);
+ // Callback for upload progress events:
+ // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
+ // Callback for global upload progress events:
+ // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
+ // Callback for uploads start, equivalent to the global ajaxStart event:
+ // start: function (e) {}, // .bind('fileuploadstart', func);
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
+ // stop: function (e) {}, // .bind('fileuploadstop', func);
+ // Callback for change events of the fileInput(s):
+ // change: function (e, data) {}, // .bind('fileuploadchange', func);
+ // Callback for paste events to the pasteZone(s):
+ // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
+ // Callback for drop events of the dropZone(s):
+ // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
+ // Callback for dragover events of the dropZone(s):
+ // dragover: function (e) {}, // .bind('fileuploaddragover', func);
+
+ // The plugin options are used as settings object for the ajax calls.
+ // The following are jQuery ajax settings required for the file uploads:
+ processData: false,
+ contentType: false,
+ cache: false
+ },
+
+ // A list of options that require a refresh after assigning a new value:
+ _refreshOptionsList: [
+ 'fileInput',
+ 'dropZone',
+ 'pasteZone',
+ 'multipart',
+ 'forceIframeTransport'
+ ],
+
+ _BitrateTimer: function () {
+ this.timestamp = +(new Date());
+ this.loaded = 0;
+ this.bitrate = 0;
+ this.getBitrate = function (now, loaded, interval) {
+ var timeDiff = now - this.timestamp;
+ if (!this.bitrate || !interval || timeDiff > interval) {
+ this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
+ this.loaded = loaded;
+ this.timestamp = now;
+ }
+ return this.bitrate;
+ };
+ },
+
+ _isXHRUpload: function (options) {
+ return !options.forceIframeTransport &&
+ ((!options.multipart && $.support.xhrFileUpload) ||
+ $.support.xhrFormDataFileUpload);
+ },
+
+ _getFormData: function (options) {
+ var formData;
+ if (typeof options.formData === 'function') {
+ return options.formData(options.form);
+ }
+ if ($.isArray(options.formData)) {
+ return options.formData;
+ }
+ if (options.formData) {
+ formData = [];
+ $.each(options.formData, function (name, value) {
+ formData.push({name: name, value: value});
+ });
+ return formData;
+ }
+ return [];
+ },
+
+ _getTotal: function (files) {
+ var total = 0;
+ $.each(files, function (index, file) {
+ total += file.size || 1;
+ });
+ return total;
+ },
+
+ _onProgress: function (e, data) {
+ if (e.lengthComputable) {
+ var now = +(new Date()),
+ total,
+ loaded;
+ if (data._time && data.progressInterval &&
+ (now - data._time < data.progressInterval) &&
+ e.loaded !== e.total) {
+ return;
+ }
+ data._time = now;
+ total = data.total || this._getTotal(data.files);
+ loaded = parseInt(
+ e.loaded / e.total * (data.chunkSize || total),
+ 10
+ ) + (data.uploadedBytes || 0);
+ this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
+ data.lengthComputable = true;
+ data.loaded = loaded;
+ data.total = total;
+ data.bitrate = data._bitrateTimer.getBitrate(
+ now,
+ loaded,
+ data.bitrateInterval
+ );
+ // Trigger a custom progress event with a total data property set
+ // to the file size(s) of the current upload and a loaded data
+ // property calculated accordingly:
+ this._trigger('progress', e, data);
+ // Trigger a global progress event for all current file uploads,
+ // including ajax calls queued for sequential file uploads:
+ this._trigger('progressall', e, {
+ lengthComputable: true,
+ loaded: this._loaded,
+ total: this._total,
+ bitrate: this._bitrateTimer.getBitrate(
+ now,
+ this._loaded,
+ data.bitrateInterval
+ )
+ });
+ }
+ },
+
+ _initProgressListener: function (options) {
+ var that = this,
+ xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
+ // Accesss to the native XHR object is required to add event listeners
+ // for the upload progress event:
+ if (xhr.upload) {
+ $(xhr.upload).bind('progress', function (e) {
+ var oe = e.originalEvent;
+ // Make sure the progress event properties get copied over:
+ e.lengthComputable = oe.lengthComputable;
+ e.loaded = oe.loaded;
+ e.total = oe.total;
+ that._onProgress(e, options);
+ });
+ options.xhr = function () {
+ return xhr;
+ };
+ }
+ },
+
+ _initXHRData: function (options) {
+ var formData,
+ file = options.files[0],
+ // Ignore non-multipart setting if not supported:
+ multipart = options.multipart || !$.support.xhrFileUpload,
+ paramName = options.paramName[0];
+ options.headers = options.headers || {};
+ if (options.contentRange) {
+ options.headers['Content-Range'] = options.contentRange;
+ }
+ if (!multipart) {
+ options.headers['Content-Disposition'] = 'attachment; filename="' +
+ encodeURI(file.name) + '"';
+ options.contentType = file.type;
+ options.data = options.blob || file;
+ } else if ($.support.xhrFormDataFileUpload) {
+ if (options.postMessage) {
+ // window.postMessage does not allow sending FormData
+ // objects, so we just add the File/Blob objects to
+ // the formData array and let the postMessage window
+ // create the FormData object out of this array:
+ formData = this._getFormData(options);
+ if (options.blob) {
+ formData.push({
+ name: paramName,
+ value: options.blob
+ });
+ } else {
+ $.each(options.files, function (index, file) {
+ formData.push({
+ name: options.paramName[index] || paramName,
+ value: file
+ });
+ });
+ }
+ } else {
+ if (options.formData instanceof FormData) {
+ formData = options.formData;
+ } else {
+ formData = new FormData();
+ $.each(this._getFormData(options), function (index, field) {
+ formData.append(field.name, field.value);
+ });
+ }
+ if (options.blob) {
+ options.headers['Content-Disposition'] = 'attachment; filename="' +
+ encodeURI(file.name) + '"';
+ formData.append(paramName, options.blob, file.name);
+ } else {
+ $.each(options.files, function (index, file) {
+ // Files are also Blob instances, but some browsers
+ // (Firefox 3.6) support the File API but not Blobs.
+ // This check allows the tests to run with
+ // dummy objects:
+ if ((window.Blob && file instanceof Blob) ||
+ (window.File && file instanceof File)) {
+ formData.append(
+ options.paramName[index] || paramName,
+ file,
+ file.name
+ );
+ }
+ });
+ }
+ }
+ options.data = formData;
+ }
+ // Blob reference is not needed anymore, free memory:
+ options.blob = null;
+ },
+
+ _initIframeSettings: function (options) {
+ // Setting the dataType to iframe enables the iframe transport:
+ options.dataType = 'iframe ' + (options.dataType || '');
+ // The iframe transport accepts a serialized array as form data:
+ options.formData = this._getFormData(options);
+ // Add redirect url to form data on cross-domain uploads:
+ if (options.redirect && $('
').prop('href', options.url)
+ .prop('host') !== location.host) {
+ options.formData.push({
+ name: options.redirectParamName || 'redirect',
+ value: options.redirect
+ });
+ }
+ },
+
+ _initDataSettings: function (options) {
+ if (this._isXHRUpload(options)) {
+ if (!this._chunkedUpload(options, true)) {
+ if (!options.data) {
+ this._initXHRData(options);
+ }
+ this._initProgressListener(options);
+ }
+ if (options.postMessage) {
+ // Setting the dataType to postmessage enables the
+ // postMessage transport:
+ options.dataType = 'postmessage ' + (options.dataType || '');
+ }
+ } else {
+ this._initIframeSettings(options, 'iframe');
+ }
+ },
+
+ _getParamName: function (options) {
+ var fileInput = $(options.fileInput),
+ paramName = options.paramName;
+ if (!paramName) {
+ paramName = [];
+ fileInput.each(function () {
+ var input = $(this),
+ name = input.prop('name') || 'files[]',
+ i = (input.prop('files') || [1]).length;
+ while (i) {
+ paramName.push(name);
+ i -= 1;
+ }
+ });
+ if (!paramName.length) {
+ paramName = [fileInput.prop('name') || 'files[]'];
+ }
+ } else if (!$.isArray(paramName)) {
+ paramName = [paramName];
+ }
+ return paramName;
+ },
+
+ _initFormSettings: function (options) {
+ // Retrieve missing options from the input field and the
+ // associated form, if available:
+ if (!options.form || !options.form.length) {
+ options.form = $(options.fileInput.prop('form'));
+ // If the given file input doesn't have an associated form,
+ // use the default widget file input's form:
+ if (!options.form.length) {
+ options.form = $(this.options.fileInput.prop('form'));
+ }
+ }
+ options.paramName = this._getParamName(options);
+ if (!options.url) {
+ options.url = options.form.prop('action') || location.href;
+ }
+ // The HTTP request method must be "POST" or "PUT":
+ options.type = (options.type || options.form.prop('method') || '')
+ .toUpperCase();
+ if (options.type !== 'POST' && options.type !== 'PUT') {
+ options.type = 'POST';
+ }
+ if (!options.formAcceptCharset) {
+ options.formAcceptCharset = options.form.attr('accept-charset');
+ }
+ },
+
+ _getAJAXSettings: function (data) {
+ var options = $.extend({}, this.options, data);
+ this._initFormSettings(options);
+ this._initDataSettings(options);
+ return options;
+ },
+
+ // Maps jqXHR callbacks to the equivalent
+ // methods of the given Promise object:
+ _enhancePromise: function (promise) {
+ promise.success = promise.done;
+ promise.error = promise.fail;
+ promise.complete = promise.always;
+ return promise;
+ },
+
+ // Creates and returns a Promise object enhanced with
+ // the jqXHR methods abort, success, error and complete:
+ _getXHRPromise: function (resolveOrReject, context, args) {
+ var dfd = $.Deferred(),
+ promise = dfd.promise();
+ context = context || this.options.context || promise;
+ if (resolveOrReject === true) {
+ dfd.resolveWith(context, args);
+ } else if (resolveOrReject === false) {
+ dfd.rejectWith(context, args);
+ }
+ promise.abort = dfd.promise;
+ return this._enhancePromise(promise);
+ },
+
+ // Parses the Range header from the server response
+ // and returns the uploaded bytes:
+ _getUploadedBytes: function (jqXHR) {
+ var range = jqXHR.getResponseHeader('Range'),
+ parts = range && range.split('-'),
+ upperBytesPos = parts && parts.length > 1 &&
+ parseInt(parts[1], 10);
+ return upperBytesPos && upperBytesPos + 1;
+ },
+
+ // Uploads a file in multiple, sequential requests
+ // by splitting the file up in multiple blob chunks.
+ // If the second parameter is true, only tests if the file
+ // should be uploaded in chunks, but does not invoke any
+ // upload requests:
+ _chunkedUpload: function (options, testOnly) {
+ var that = this,
+ file = options.files[0],
+ fs = file.size,
+ ub = options.uploadedBytes = options.uploadedBytes || 0,
+ mcs = options.maxChunkSize || fs,
+ slice = file.slice || file.webkitSlice || file.mozSlice,
+ dfd = $.Deferred(),
+ promise = dfd.promise(),
+ jqXHR,
+ upload;
+ if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
+ options.data) {
+ return false;
+ }
+ if (testOnly) {
+ return true;
+ }
+ if (ub >= fs) {
+ file.error = 'Uploaded bytes exceed file size';
+ return this._getXHRPromise(
+ false,
+ options.context,
+ [null, 'error', file.error]
+ );
+ }
+ // The chunk upload method:
+ upload = function (i) {
+ // Clone the options object for each chunk upload:
+ var o = $.extend({}, options);
+ o.blob = slice.call(
+ file,
+ ub,
+ ub + mcs,
+ file.type
+ );
+ // Store the current chunk size, as the blob itself
+ // will be dereferenced after data processing:
+ o.chunkSize = o.blob.size;
+ // Expose the chunk bytes position range:
+ o.contentRange = 'bytes ' + ub + '-' +
+ (ub + o.chunkSize - 1) + '/' + fs;
+ // Process the upload data (the blob and potential form data):
+ that._initXHRData(o);
+ // Add progress listeners for this chunk upload:
+ that._initProgressListener(o);
+ jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
+ .done(function (result, textStatus, jqXHR) {
+ ub = that._getUploadedBytes(jqXHR) ||
+ (ub + o.chunkSize);
+ // Create a progress event if upload is done and
+ // no progress event has been invoked for this chunk:
+ if (!o.loaded) {
+ that._onProgress($.Event('progress', {
+ lengthComputable: true,
+ loaded: ub - o.uploadedBytes,
+ total: ub - o.uploadedBytes
+ }), o);
+ }
+ options.uploadedBytes = o.uploadedBytes = ub;
+ if (ub < fs) {
+ // File upload not yet complete,
+ // continue with the next chunk:
+ upload();
+ } else {
+ dfd.resolveWith(
+ o.context,
+ [result, textStatus, jqXHR]
+ );
+ }
+ })
+ .fail(function (jqXHR, textStatus, errorThrown) {
+ dfd.rejectWith(
+ o.context,
+ [jqXHR, textStatus, errorThrown]
+ );
+ });
+ };
+ this._enhancePromise(promise);
+ promise.abort = function () {
+ return jqXHR.abort();
+ };
+ upload();
+ return promise;
+ },
+
+ _beforeSend: function (e, data) {
+ if (this._active === 0) {
+ // the start callback is triggered when an upload starts
+ // and no other uploads are currently running,
+ // equivalent to the global ajaxStart event:
+ this._trigger('start');
+ // Set timer for global bitrate progress calculation:
+ this._bitrateTimer = new this._BitrateTimer();
+ }
+ this._active += 1;
+ // Initialize the global progress values:
+ this._loaded += data.uploadedBytes || 0;
+ this._total += this._getTotal(data.files);
+ },
+
+ _onDone: function (result, textStatus, jqXHR, options) {
+ if (!this._isXHRUpload(options)) {
+ // Create a progress event for each iframe load:
+ this._onProgress($.Event('progress', {
+ lengthComputable: true,
+ loaded: 1,
+ total: 1
+ }), options);
+ }
+ options.result = result;
+ options.textStatus = textStatus;
+ options.jqXHR = jqXHR;
+ this._trigger('done', null, options);
+ },
+
+ _onFail: function (jqXHR, textStatus, errorThrown, options) {
+ options.jqXHR = jqXHR;
+ options.textStatus = textStatus;
+ options.errorThrown = errorThrown;
+ this._trigger('fail', null, options);
+ if (options.recalculateProgress) {
+ // Remove the failed (error or abort) file upload from
+ // the global progress calculation:
+ this._loaded -= options.loaded || options.uploadedBytes || 0;
+ this._total -= options.total || this._getTotal(options.files);
+ }
+ },
+
+ _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
+ this._active -= 1;
+ options.textStatus = textStatus;
+ if (jqXHRorError && jqXHRorError.always) {
+ options.jqXHR = jqXHRorError;
+ options.result = jqXHRorResult;
+ } else {
+ options.jqXHR = jqXHRorResult;
+ options.errorThrown = jqXHRorError;
+ }
+ this._trigger('always', null, options);
+ if (this._active === 0) {
+ // The stop callback is triggered when all uploads have
+ // been completed, equivalent to the global ajaxStop event:
+ this._trigger('stop');
+ // Reset the global progress values:
+ this._loaded = this._total = 0;
+ this._bitrateTimer = null;
+ }
+ },
+
+ _onSend: function (e, data) {
+ var that = this,
+ jqXHR,
+ aborted,
+ slot,
+ pipe,
+ options = that._getAJAXSettings(data),
+ send = function () {
+ that._sending += 1;
+ // Set timer for bitrate progress calculation:
+ options._bitrateTimer = new that._BitrateTimer();
+ jqXHR = jqXHR || (
+ ((aborted || that._trigger('send', e, options) === false) &&
+ that._getXHRPromise(false, options.context, aborted)) ||
+ that._chunkedUpload(options) || $.ajax(options)
+ ).done(function (result, textStatus, jqXHR) {
+ that._onDone(result, textStatus, jqXHR, options);
+ }).fail(function (jqXHR, textStatus, errorThrown) {
+ that._onFail(jqXHR, textStatus, errorThrown, options);
+ }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
+ that._sending -= 1;
+ that._onAlways(
+ jqXHRorResult,
+ textStatus,
+ jqXHRorError,
+ options
+ );
+ if (options.limitConcurrentUploads &&
+ options.limitConcurrentUploads > that._sending) {
+ // Start the next queued upload,
+ // that has not been aborted:
+ var nextSlot = that._slots.shift(),
+ isPending;
+ while (nextSlot) {
+ // jQuery 1.6 doesn't provide .state(),
+ // while jQuery 1.8+ removed .isRejected():
+ isPending = nextSlot.state ?
+ nextSlot.state() === 'pending' :
+ !nextSlot.isRejected();
+ if (isPending) {
+ nextSlot.resolve();
+ break;
+ }
+ nextSlot = that._slots.shift();
+ }
+ }
+ });
+ return jqXHR;
+ };
+ this._beforeSend(e, options);
+ if (this.options.sequentialUploads ||
+ (this.options.limitConcurrentUploads &&
+ this.options.limitConcurrentUploads <= this._sending)) {
+ if (this.options.limitConcurrentUploads > 1) {
+ slot = $.Deferred();
+ this._slots.push(slot);
+ pipe = slot.pipe(send);
+ } else {
+ pipe = (this._sequence = this._sequence.pipe(send, send));
+ }
+ // Return the piped Promise object, enhanced with an abort method,
+ // which is delegated to the jqXHR object of the current upload,
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
+ pipe.abort = function () {
+ aborted = [undefined, 'abort', 'abort'];
+ if (!jqXHR) {
+ if (slot) {
+ slot.rejectWith(options.context, aborted);
+ }
+ return send();
+ }
+ return jqXHR.abort();
+ };
+ return this._enhancePromise(pipe);
+ }
+ return send();
+ },
+
+ _onAdd: function (e, data) {
+ var that = this,
+ result = true,
+ options = $.extend({}, this.options, data),
+ limit = options.limitMultiFileUploads,
+ paramName = this._getParamName(options),
+ paramNameSet,
+ paramNameSlice,
+ fileSet,
+ i;
+ if (!(options.singleFileUploads || limit) ||
+ !this._isXHRUpload(options)) {
+ fileSet = [data.files];
+ paramNameSet = [paramName];
+ } else if (!options.singleFileUploads && limit) {
+ fileSet = [];
+ paramNameSet = [];
+ for (i = 0; i < data.files.length; i += limit) {
+ fileSet.push(data.files.slice(i, i + limit));
+ paramNameSlice = paramName.slice(i, i + limit);
+ if (!paramNameSlice.length) {
+ paramNameSlice = paramName;
+ }
+ paramNameSet.push(paramNameSlice);
+ }
+ } else {
+ paramNameSet = paramName;
+ }
+ data.originalFiles = data.files;
+ $.each(fileSet || data.files, function (index, element) {
+ var newData = $.extend({}, data);
+ newData.files = fileSet ? element : [element];
+ newData.paramName = paramNameSet[index];
+ newData.submit = function () {
+ newData.jqXHR = this.jqXHR =
+ (that._trigger('submit', e, this) !== false) &&
+ that._onSend(e, this);
+ return this.jqXHR;
+ };
+ result = that._trigger('add', e, newData);
+ return result;
+ });
+ return result;
+ },
+
+ _replaceFileInput: function (input) {
+ var inputClone = input.clone(true);
+ $('
').append(inputClone)[0].reset();
+ // Detaching allows to insert the fileInput on another form
+ // without loosing the file input value:
+ input.after(inputClone).detach();
+ // Avoid memory leaks with the detached file input:
+ $.cleanData(input.unbind('remove'));
+ // Replace the original file input element in the fileInput
+ // elements set with the clone, which has been copied including
+ // event handlers:
+ this.options.fileInput = this.options.fileInput.map(function (i, el) {
+ if (el === input[0]) {
+ return inputClone[0];
+ }
+ return el;
+ });
+ // If the widget has been initialized on the file input itself,
+ // override this.element with the file input clone:
+ if (input[0] === this.element[0]) {
+ this.element = inputClone;
+ }
+ },
+
+ _handleFileTreeEntry: function (entry, path) {
+ var that = this,
+ dfd = $.Deferred(),
+ errorHandler = function (e) {
+ if (e && !e.entry) {
+ e.entry = entry;
+ }
+ // Since $.when returns immediately if one
+ // Deferred is rejected, we use resolve instead.
+ // This allows valid files and invalid items
+ // to be returned together in one set:
+ dfd.resolve([e]);
+ },
+ dirReader;
+ path = path || '';
+ if (entry.isFile) {
+ if (entry._file) {
+ // Workaround for Chrome bug #149735
+ entry._file.relativePath = path;
+ dfd.resolve(entry._file);
+ } else {
+ entry.file(function (file) {
+ file.relativePath = path;
+ dfd.resolve(file);
+ }, errorHandler);
+ }
+ } else if (entry.isDirectory) {
+ dirReader = entry.createReader();
+ dirReader.readEntries(function (entries) {
+ that._handleFileTreeEntries(
+ entries,
+ path + entry.name + '/'
+ ).done(function (files) {
+ dfd.resolve(files);
+ }).fail(errorHandler);
+ }, errorHandler);
+ } else {
+ // Return an empy list for file system items
+ // other than files or directories:
+ dfd.resolve([]);
+ }
+ return dfd.promise();
+ },
+
+ _handleFileTreeEntries: function (entries, path) {
+ var that = this;
+ return $.when.apply(
+ $,
+ $.map(entries, function (entry) {
+ return that._handleFileTreeEntry(entry, path);
+ })
+ ).pipe(function () {
+ return Array.prototype.concat.apply(
+ [],
+ arguments
+ );
+ });
+ },
+
+ _getDroppedFiles: function (dataTransfer) {
+ dataTransfer = dataTransfer || {};
+ var items = dataTransfer.items;
+ if (items && items.length && (items[0].webkitGetAsEntry ||
+ items[0].getAsEntry)) {
+ return this._handleFileTreeEntries(
+ $.map(items, function (item) {
+ var entry;
+ if (item.webkitGetAsEntry) {
+ entry = item.webkitGetAsEntry();
+ if (entry) {
+ // Workaround for Chrome bug #149735:
+ entry._file = item.getAsFile();
+ }
+ return entry;
+ }
+ return item.getAsEntry();
+ })
+ );
+ }
+ return $.Deferred().resolve(
+ $.makeArray(dataTransfer.files)
+ ).promise();
+ },
+
+ _getSingleFileInputFiles: function (fileInput) {
+ fileInput = $(fileInput);
+ var entries = fileInput.prop('webkitEntries') ||
+ fileInput.prop('entries'),
+ files,
+ value;
+ if (entries && entries.length) {
+ return this._handleFileTreeEntries(entries);
+ }
+ files = $.makeArray(fileInput.prop('files'));
+ if (!files.length) {
+ value = fileInput.prop('value');
+ if (!value) {
+ return $.Deferred().resolve([]).promise();
+ }
+ // If the files property is not available, the browser does not
+ // support the File API and we add a pseudo File object with
+ // the input value as name with path information removed:
+ files = [{name: value.replace(/^.*\\/, '')}];
+ } else if (files[0].name === undefined && files[0].fileName) {
+ // File normalization for Safari 4 and Firefox 3:
+ $.each(files, function (index, file) {
+ file.name = file.fileName;
+ file.size = file.fileSize;
+ });
+ }
+ return $.Deferred().resolve(files).promise();
+ },
+
+ _getFileInputFiles: function (fileInput) {
+ if (!(fileInput instanceof $) || fileInput.length === 1) {
+ return this._getSingleFileInputFiles(fileInput);
+ }
+ return $.when.apply(
+ $,
+ $.map(fileInput, this._getSingleFileInputFiles)
+ ).pipe(function () {
+ return Array.prototype.concat.apply(
+ [],
+ arguments
+ );
+ });
+ },
+
+ _onChange: function (e) {
+ var that = this,
+ data = {
+ fileInput: $(e.target),
+ form: $(e.target.form)
+ };
+ this._getFileInputFiles(data.fileInput).always(function (files) {
+ data.files = files;
+ if (that.options.replaceFileInput) {
+ that._replaceFileInput(data.fileInput);
+ }
+ if (that._trigger('change', e, data) !== false) {
+ that._onAdd(e, data);
+ }
+ });
+ },
+
+ _onPaste: function (e) {
+ var cbd = e.originalEvent.clipboardData,
+ items = (cbd && cbd.items) || [],
+ data = {files: []};
+ $.each(items, function (index, item) {
+ var file = item.getAsFile && item.getAsFile();
+ if (file) {
+ data.files.push(file);
+ }
+ });
+ if (this._trigger('paste', e, data) === false ||
+ this._onAdd(e, data) === false) {
+ return false;
+ }
+ },
+
+ _onDrop: function (e) {
+ var that = this,
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
+ data = {};
+ if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
+ e.preventDefault();
+ }
+ this._getDroppedFiles(dataTransfer).always(function (files) {
+ data.files = files;
+ if (that._trigger('drop', e, data) !== false) {
+ that._onAdd(e, data);
+ }
+ });
+ },
+
+ _onDragOver: function (e) {
+ var dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
+ if (this._trigger('dragover', e) === false) {
+ return false;
+ }
+ if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1) {
+ dataTransfer.dropEffect = 'copy';
+ e.preventDefault();
+ }
+ },
+
+ _initEventHandlers: function () {
+ if (this._isXHRUpload(this.options)) {
+ this._on(this.options.dropZone, {
+ dragover: this._onDragOver,
+ drop: this._onDrop
+ });
+ this._on(this.options.pasteZone, {
+ paste: this._onPaste
+ });
+ }
+ this._on(this.options.fileInput, {
+ change: this._onChange
+ });
+ },
+
+ _destroyEventHandlers: function () {
+ this._off(this.options.dropZone, 'dragover drop');
+ this._off(this.options.pasteZone, 'paste');
+ this._off(this.options.fileInput, 'change');
+ },
+
+ _setOption: function (key, value) {
+ var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
+ if (refresh) {
+ this._destroyEventHandlers();
+ }
+ this._super(key, value);
+ if (refresh) {
+ this._initSpecialOptions();
+ this._initEventHandlers();
+ }
+ },
+
+ _initSpecialOptions: function () {
+ var options = this.options;
+ if (options.fileInput === undefined) {
+ options.fileInput = this.element.is('input[type="file"]') ?
+ this.element : this.element.find('input[type="file"]');
+ } else if (!(options.fileInput instanceof $)) {
+ options.fileInput = $(options.fileInput);
+ }
+ if (!(options.dropZone instanceof $)) {
+ options.dropZone = $(options.dropZone);
+ }
+ if (!(options.pasteZone instanceof $)) {
+ options.pasteZone = $(options.pasteZone);
+ }
+ },
+
+ _create: function () {
+ var options = this.options;
+ // Initialize options set via HTML5 data-attributes:
+ $.extend(options, $(this.element[0].cloneNode(false)).data());
+ this._initSpecialOptions();
+ this._slots = [];
+ this._sequence = this._getXHRPromise(true);
+ this._sending = this._active = this._loaded = this._total = 0;
+ this._initEventHandlers();
+ },
+
+ _destroy: function () {
+ this._destroyEventHandlers();
+ },
+
+ // This method is exposed to the widget API and allows adding files
+ // using the fileupload API. The data parameter accepts an object which
+ // must have a files property and can contain additional options:
+ // .fileupload('add', {files: filesList});
+ add: function (data) {
+ var that = this;
+ if (!data || this.options.disabled) {
+ return;
+ }
+ if (data.fileInput && !data.files) {
+ this._getFileInputFiles(data.fileInput).always(function (files) {
+ data.files = files;
+ that._onAdd(null, data);
+ });
+ } else {
+ data.files = $.makeArray(data.files);
+ this._onAdd(null, data);
+ }
+ },
+
+ // This method is exposed to the widget API and allows sending files
+ // using the fileupload API. The data parameter accepts an object which
+ // must have a files or fileInput property and can contain additional options:
+ // .fileupload('send', {files: filesList});
+ // The method returns a Promise object for the file upload call.
+ send: function (data) {
+ if (data && !this.options.disabled) {
+ if (data.fileInput && !data.files) {
+ var that = this,
+ dfd = $.Deferred(),
+ promise = dfd.promise(),
+ jqXHR,
+ aborted;
+ promise.abort = function () {
+ aborted = true;
+ if (jqXHR) {
+ return jqXHR.abort();
+ }
+ dfd.reject(null, 'abort', 'abort');
+ return promise;
+ };
+ this._getFileInputFiles(data.fileInput).always(
+ function (files) {
+ if (aborted) {
+ return;
+ }
+ data.files = files;
+ jqXHR = that._onSend(null, data).then(
+ function (result, textStatus, jqXHR) {
+ dfd.resolve(result, textStatus, jqXHR);
+ },
+ function (jqXHR, textStatus, errorThrown) {
+ dfd.reject(jqXHR, textStatus, errorThrown);
+ }
+ );
+ }
+ );
+ return this._enhancePromise(promise);
+ }
+ data.files = $.makeArray(data.files);
+ if (data.files.length) {
+ return this._onSend(null, data);
+ }
+ }
+ return this._getXHRPromise(false, data && data.context);
+ }
+
+ });
+
+}));
diff --git a/app/assets/javascripts/note_files/note_files.js b/app/assets/javascripts/note_files/note_files.js
new file mode 100644
index 0000000..f4113fd
--- /dev/null
+++ b/app/assets/javascripts/note_files/note_files.js
@@ -0,0 +1,53 @@
+
+function init_note_upload_fields(note_id){
+ drop = $('#note_'+note_id+' .fileupload').closest(".bottom")
+
+ $('#note_'+note_id+' .fileupload').fileupload({
+ url: $(this).attr("action"),
+ dropZone: drop,
+ autoUpload: true,
+ progressall: function (e, data) {
+ var progress = parseInt(data.loaded / data.total * 100, 10);
+ if(progress == 100){
+ $(this).find('.progress').html('traitement en cours.');
+ }
+ else{
+ $(this).find('.progress').html(progress + '% téléchargé.');}
+ },
+ always: function (e, data) {
+ $(this).find('.progress').html("");
+ },
+
+ drop: function (e, data) {
+
+ $('#note_'+note_id+' .fileupload').closest(".bottom").css("background", "rgb(255, 255, 204)");
+ }
+ });
+
+
+ $(".note .bottom").bind('dragover', function (e) {
+ $(this).css("background", "#B7DF63");
+
+ });
+
+ $(".note .bottom").bind('dragleave', function (e) {
+ $(this).css("background", "rgb(255, 255, 204)");
+
+ });
+
+
+
+
+
+}
+
+
+$(document).ready(function () {
+
+ $("body").on("click", ".note .add_files",function(){
+
+ $(this).next('input').click();
+ return false;
+ });
+
+});
diff --git a/app/assets/javascripts/shared/jquery.backstretch.js b/app/assets/javascripts/shared/jquery.backstretch.js
new file mode 100644
index 0000000..e346903
--- /dev/null
+++ b/app/assets/javascripts/shared/jquery.backstretch.js
@@ -0,0 +1,364 @@
+/*
+ * Backstretch
+ * http://srobbin.com/jquery-plugins/backstretch/
+ *
+ * Copyright (c) 2012 Scott Robbin
+ * Licensed under the MIT license.
+ */
+
+;(function ($, window, undefined) {
+ 'use strict';
+
+ /* PLUGIN DEFINITION
+ * ========================= */
+
+ $.fn.backstretch = function (images, options) {
+ // We need at least one image
+ if (images === undefined || images.length === 0) {
+ $.error("No images were supplied for Backstretch");
+ }
+
+ /*
+ * Scroll the page one pixel to get the right window height on iOS
+ * Pretty harmless for everyone else
+ */
+ if ($(window).scrollTop() === 0 ) {
+ window.scrollTo(0, 0);
+ }
+
+ return this.each(function () {
+ var $this = $(this)
+ , obj = $this.data('backstretch');
+
+ // If we've already attached Backstretch to this element, remove the old instance.
+ if (obj) {
+ // Merge the old options with the new
+ options = $.extend(obj.options, options);
+
+ // Remove the old instance
+ obj.destroy(true);
+ }
+
+ obj = new Backstretch(this, images, options);
+ $this.data('backstretch', obj);
+ });
+ };
+
+ // If no element is supplied, we'll attach to body
+ $.backstretch = function (images, options) {
+ // Return the instance
+ return $('body')
+ .backstretch(images, options)
+ .data('backstretch');
+ };
+
+ // Custom selector
+ $.expr[':'].backstretch = function(elem) {
+ return $(elem).data('backstretch') !== undefined;
+ };
+
+ /* DEFAULTS
+ * ========================= */
+
+ $.fn.backstretch.defaults = {
+ centeredX: true // Should we center the image on the X axis?
+ , centeredY: true // Should we center the image on the Y axis?
+ , duration: 5000 // Amount of time in between slides (if slideshow)
+ , fade: 0 // Speed of fade transition between slides
+ };
+
+ /* STYLES
+ *
+ * Baked-in styles that we'll apply to our elements.
+ * In an effort to keep the plugin simple, these are not exposed as options.
+ * That said, anyone can override these in their own stylesheet.
+ * ========================= */
+ var styles = {
+ wrap: {
+ left: 0
+ , top: 0
+ , overflow: 'hidden'
+ , margin: 0
+ , padding: 0
+ , height: '100%'
+ , width: '100%'
+ , zIndex: -999999
+ }
+ , img: {
+ position: 'absolute'
+ , display: 'none'
+ , margin: 0
+ , padding: 0
+ , border: 'none'
+ , width: 'auto'
+ , height: 'auto'
+ , maxWidth: 'none'
+ , zIndex: -999999
+ }
+ };
+
+ /* CLASS DEFINITION
+ * ========================= */
+ var Backstretch = function (container, images, options) {
+ this.options = $.extend({}, $.fn.backstretch.defaults, options || {});
+
+ /* In its simplest form, we allow Backstretch to be called on an image path.
+ * e.g. $.backstretch('/path/to/image.jpg')
+ * So, we need to turn this back into an array.
+ */
+ this.images = $.isArray(images) ? images : [images];
+
+ // Preload images
+ $.each(this.images, function () {
+ $('
![]()
')[0].src = this;
+ });
+
+ // Convenience reference to know if the container is body.
+ this.isBody = container === document.body;
+
+ /* We're keeping track of a few different elements
+ *
+ * Container: the element that Backstretch was called on.
+ * Wrap: a DIV that we place the image into, so we can hide the overflow.
+ * Root: Convenience reference to help calculate the correct height.
+ */
+ this.$container = $(container);
+ this.$root = this.isBody ? supportsFixedPosition ? $(window) : $(document) : this.$container;
+
+ // Don't create a new wrap if one already exists (from a previous instance of Backstretch)
+ var $existing = this.$container.children(".backstretch").first();
+ this.$wrap = $existing.length ? $existing : $('
').css(styles.wrap).appendTo(this.$container);
+
+ // Non-body elements need some style adjustments
+ if (!this.isBody) {
+ // If the container is statically positioned, we need to make it relative,
+ // and if no zIndex is defined, we should set it to zero.
+ var position = this.$container.css('position')
+ , zIndex = this.$container.css('zIndex');
+
+ this.$container.css({
+ position: position === 'static' ? 'relative' : position
+ , zIndex: zIndex === 'auto' ? 0 : zIndex
+ , background: 'none'
+ });
+
+ // Needs a higher z-index
+ this.$wrap.css({zIndex: -999998});
+ }
+
+ // Fixed or absolute positioning?
+ this.$wrap.css({
+ position: this.isBody && supportsFixedPosition ? 'fixed' : 'absolute'
+ });
+
+ // Set the first image
+ this.index = 0;
+ this.show(this.index);
+
+ // Listen for resize
+ $(window).on('resize.backstretch', $.proxy(this.resize, this))
+ .on('orientationchange.backstretch', $.proxy(function () {
+ // Need to do this in order to get the right window height
+ if (this.isBody && window.pageYOffset === 0) {
+ window.scrollTo(0, 1);
+ this.resize();
+ }
+ }, this));
+ };
+
+ /* PUBLIC METHODS
+ * ========================= */
+ Backstretch.prototype = {
+ resize: function () {
+ try {
+ var bgCSS = {left: 0, top: 0}
+ , rootWidth = this.isBody ? this.$root.width() : this.$root.innerWidth()
+ , bgWidth = rootWidth
+ , rootHeight = this.isBody ? ( window.innerHeight ? window.innerHeight : this.$root.height() ) : this.$root.innerHeight()
+ , bgHeight = bgWidth / this.$img.data('ratio')
+ , bgOffset;
+
+ // Make adjustments based on image ratio
+ if (bgHeight >= rootHeight) {
+ bgOffset = (bgHeight - rootHeight) / 2;
+ if(this.options.centeredY) {
+ bgCSS.top = '-' + bgOffset + 'px';
+ }
+ } else {
+ bgHeight = rootHeight;
+ bgWidth = bgHeight * this.$img.data('ratio');
+ bgOffset = (bgWidth - rootWidth) / 2;
+ if(this.options.centeredX) {
+ bgCSS.left = '-' + bgOffset + 'px';
+ }
+ }
+
+ this.$wrap.css({width: rootWidth, height: rootHeight})
+ .find('img:not(.deleteable)').css({width: bgWidth, height: bgHeight}).css(bgCSS);
+ } catch(err) {
+ // IE7 seems to trigger resize before the image is loaded.
+ // This try/catch block is a hack to let it fail gracefully.
+ }
+
+ return this;
+ }
+
+ // Show the slide at a certain position
+ , show: function (index) {
+ // Validate index
+ if (Math.abs(index) > this.images.length - 1) {
+ return;
+ } else {
+ this.index = index;
+ }
+
+ // Vars
+ var self = this
+ , oldImage = self.$wrap.find('img').addClass('deleteable')
+ , evt = $.Event('backstretch.show', {
+ relatedTarget: self.$container[0]
+ });
+
+ // Pause the slideshow
+ clearInterval(self.interval);
+
+ // New image
+ self.$img = $('
![]()
')
+ .css(styles.img)
+ .bind('load', function (e) {
+ var imgWidth = this.width || $(e.target).width()
+ , imgHeight = this.height || $(e.target).height();
+
+ // Save the ratio
+ $(this).data('ratio', imgWidth / imgHeight);
+
+ // Show the image, then delete the old one
+ // "speed" option has been deprecated, but we want backwards compatibilty
+ $(this).fadeIn(self.options.speed || self.options.fade, function () {
+ oldImage.remove();
+
+ // Resume the slideshow
+ if (!self.paused) {
+ self.cycle();
+ }
+
+ // Trigger the event
+ self.$container.trigger(evt, self);
+ });
+
+ // Resize
+ self.resize();
+ })
+ .appendTo(self.$wrap);
+
+ // Hack for IE img onload event
+ self.$img.attr('src', self.images[index]);
+ return self;
+ }
+
+ , next: function () {
+ // Next slide
+ return this.show(this.index < this.images.length - 1 ? this.index + 1 : 0);
+ }
+
+ , prev: function () {
+ // Previous slide
+ return this.show(this.index === 0 ? this.images.length - 1 : this.index - 1);
+ }
+
+ , pause: function () {
+ // Pause the slideshow
+ this.paused = true;
+ return this;
+ }
+
+ , resume: function () {
+ // Resume the slideshow
+ this.paused = false;
+ this.next();
+ return this;
+ }
+
+ , cycle: function () {
+ // Start/resume the slideshow
+ if(this.images.length > 1) {
+ // Clear the interval, just in case
+ clearInterval(this.interval);
+
+ this.interval = setInterval($.proxy(function () {
+ // Check for paused slideshow
+ if (!this.paused) {
+ this.next();
+ }
+ }, this), this.options.duration);
+ }
+ return this;
+ }
+
+ , destroy: function (preserveBackground) {
+ // Stop the resize events
+ $(window).off('resize.backstretch orientationchange.backstretch');
+
+ // Clear the interval
+ clearInterval(this.interval);
+
+ // Remove Backstretch
+ if(!preserveBackground) {
+ this.$wrap.remove();
+ }
+ this.$container.removeData('backstretch');
+ }
+ };
+
+ /* SUPPORTS FIXED POSITION?
+ *
+ * Based on code from jQuery Mobile 1.1.0
+ * http://jquerymobile.com/
+ *
+ * In a nutshell, we need to figure out if fixed positioning is supported.
+ * Unfortunately, this is very difficult to do on iOS, and usually involves
+ * injecting content, scrolling the page, etc.. It's ugly.
+ * jQuery Mobile uses this workaround. It's not ideal, but works.
+ *
+ * Modified to detect IE6
+ * ========================= */
+
+ var supportsFixedPosition = (function () {
+ var ua = navigator.userAgent
+ , platform = navigator.platform
+ // Rendering engine is Webkit, and capture major version
+ , wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ )
+ , wkversion = !!wkmatch && wkmatch[ 1 ]
+ , ffmatch = ua.match( /Fennec\/([0-9]+)/ )
+ , ffversion = !!ffmatch && ffmatch[ 1 ]
+ , operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ )
+ , omversion = !!operammobilematch && operammobilematch[ 1 ]
+ , iematch = ua.match( /MSIE ([0-9]+)/ )
+ , ieversion = !!iematch && iematch[ 1 ];
+
+ return !(
+ // iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
+ ((platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1 || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534) ||
+
+ // Opera Mini
+ (window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]") ||
+ (operammobilematch && omversion < 7458) ||
+
+ //Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
+ (ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533) ||
+
+ // Firefox Mobile before 6.0 -
+ (ffversion && ffversion < 6) ||
+
+ // WebOS less than 3
+ ("palmGetResource" in window && wkversion && wkversion < 534) ||
+
+ // MeeGo
+ (ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1) ||
+
+ // IE6
+ (ieversion && ieversion <= 6)
+ );
+ }());
+
+}(jQuery, window));
\ No newline at end of file
diff --git a/app/assets/javascripts/student.coffee b/app/assets/javascripts/student.coffee
new file mode 100644
index 0000000..0b3a8d7
--- /dev/null
+++ b/app/assets/javascripts/student.coffee
@@ -0,0 +1,32 @@
+#= require jquery
+#= require jquery_ujs
+
+#= require bootstrap
+
+#= require ./shared/jquery.backstretch.js
+
+@flash_delay = ->
+ $("#flashs").find(".alert").each ->
+
+ if !$(this).hasClass("delay")
+ $(this).addClass("delay")
+ $(this).delay(3000).fadeOut();
+
+$ ->
+ flash_delay();
+
+ $.backstretch("/login_background5.jpg")
+
+place = ->
+ margin = ($(window).height() - ($(".form-signin").outerHeight()+60) )/ 2
+
+ $(".form-signin").css("margin-top" : margin+"px")
+
+
+$(document).ready ->
+ place();
+ $(".form-signin").hide()
+ $(".form-signin").css("opacity",1 )
+ $(".form-signin").fadeIn(1500)
+ $(window).on "resize", ->
+ place();
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin.css.scss b/app/assets/stylesheets/admin.css.scss
index 8505616..59ad8a1 100644
--- a/app/assets/stylesheets/admin.css.scss
+++ b/app/assets/stylesheets/admin.css.scss
@@ -9,6 +9,13 @@
@import "redactor";
@import "pane_hover";
@import "vendor/select2";
+
+@import "admin/topics";
+
+#admin_navbar{
+border-radius:0px;
+
+}
span.preview{
img{
max-width:125px;
diff --git a/app/assets/stylesheets/admin/topics.scss b/app/assets/stylesheets/admin/topics.scss
new file mode 100644
index 0000000..27d5ce4
--- /dev/null
+++ b/app/assets/stylesheets/admin/topics.scss
@@ -0,0 +1,293 @@
+
+#topic_app_index{
+
+ position:absolute;
+ top:40px;
+ left:0px;
+ right:0px;
+ bottom:0px;
+ background:white;
+
+
+ #left{
+ background:rgba(0,0,0,0.8);
+ position:absolute;
+ top:0px;
+ left:0px;
+ width:300px;
+ bottom:0px;
+
+ }
+
+ #topic_show{
+ position:absolute;
+ top:0px;
+ left:300px;
+ right:0px;
+ bottom:0px;
+ background:rgba(250,250,250,0.9);
+
+ overflow:auto;
+
+ }
+
+
+ .note{
+ //@include border-radius(5px);
+ //@include box-shadow(0px 0px 5px rgba(0,0,0,0.5) inset);
+ position:relative;
+ margin-bottom:1em;
+ min-height:120px;
+
+ .left{
+ //@include box-shadow(0px 0px 5px rgba(0,0,0,0.5));
+ //@include border-radius(3px 0px 0px 3px);
+ position:absolute;
+ top:0px;
+ left:0px;
+ bottom:0px;
+ width:100px;
+ background:rgba(0,0,0,0.8);
+ text-align:center;
+ padding:10px;
+
+ color:rgba(255,255,255,0.9);
+
+ *{
+ text-align:center;
+ }
+
+ .avatar{
+ width:70px;
+ height:70px;
+ //@include border-radius(50%);
+ margin:auto;
+ }
+
+ }
+
+ .right{
+ min-height:150px;
+ margin-left:120px;
+ padding:10px;
+ line-height:1.1em;
+ float:none;
+
+ img{
+ max-width:100%;
+ max-height:99%;
+
+ }
+ p,ul, h1,h2,h3{
+ max-width:600px;
+ margin-left:5%;
+
+ p,ul{
+ margin-left:0px;
+ max-width:inherit;
+
+ }
+ }
+
+ .large{
+ max-width:100%;
+ margin-left:0px;
+
+
+ }
+
+ .links{
+ float:right;
+
+ }
+ }
+
+ .bottom{
+ background:rgb(255, 255, 204);
+ position:relative;
+ margin-left:120px;
+ //@include border-radius(0px 0px 3px 0px);
+ //@include box-shadow(0px 0px 2px rgba(0,0,0,0.3),-1px -1px 5px rgba(0,0,0,0.2) inset);
+ padding:10px;
+ padding-top:2px;
+
+ min-height:75px;
+
+ .note_file{
+ margin:8px 0px;
+ position:relative;
+ top:-4px;
+ .icon{
+ height:28px;
+ position:relative;
+ top:8px;
+ }
+ }
+
+ .note_file_queue{
+ position:absolute;
+ top:1em;
+ right:0em;
+
+ .file_upload_progress{
+ width:100px;
+
+
+
+ }
+
+ }
+ .fileupload{
+
+ .upload{
+ position:absolute;
+ right:10px;
+ top:-24px;
+ z-index:1000;
+
+ .add_files{
+ background:black;
+ color:white;
+ padding:5px 10px;
+ //@include border-radius(5px 5px 0 0);
+
+ }
+
+ .progress{
+
+
+
+ }
+ }
+ input[type=file]{
+ display:none;
+
+ }
+
+ }
+
+
+ }
+
+
+
+
+ }
+
+
+
+ #file_prev{
+ position:absolute;
+ top:10px;
+ bottom:10px;
+ background:rgba(0,0,0,0.9);
+ width:98%;
+ right:-50%;
+
+ //@include border-radius(5px);
+
+ //@include transition(all 1s ease);
+
+
+ &:hover{
+
+ right:1%;
+
+ }
+ iframe{
+ position:absolute;
+ width:96%;
+ height:95%;
+ top:20px;
+ left:0px;
+ right:0px;
+ bottom:0px;
+ margin:auto;
+
+ }
+
+ }
+
+
+
+
+
+}
+
+
+
+textarea.markdown{
+ display:block;
+ width:97%;
+ margin:1% auto;
+
+ min-height:400px;
+
+}
+
+
+
+
+#add_topic{
+
+ display:block;
+ color:rgba(250,250,250,0.8);
+ text-decoration:none;
+ margin-left:5px;
+ margin-top:2px;
+ padding:5px 10px;
+
+
+
+}
+
+#topics{
+ margin-top:5px;
+ border-top:1px solid rgba(250,250,250,0.1);
+ overflow:auto;
+ position:absolute;
+ top:2em;
+ bottom:5px;
+ left:0px;
+ right:0px;
+ a{
+ color:white;
+ display:block;
+ padding:6px 10px;
+ border-bottom:1px solid rgba(250,250,250,0.1);
+ color:rgba(250,250,250,0.8);
+ text-decoration:none;
+ margin-left:5px;
+ margin-top:2px;
+ //@include border-radius(5px 0px 0px 5px);
+
+ &.active, &:hover{
+ background:rgba(250,250,250,0.9);
+ color:rgba(0,0,0,0.7);
+
+
+ }
+
+ }
+
+
+}
+
+
+#topic_show{
+ padding:10px;
+
+ .topic_links{
+ float:right;
+
+ }
+
+ h1{
+ margin-top:0px;
+ margin-bottom:0.2em;
+ padding-bottom:0px;
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin_auth.css.scss b/app/assets/stylesheets/admin_auth.css.scss
index c329316..aa5ea7a 100644
--- a/app/assets/stylesheets/admin_auth.css.scss
+++ b/app/assets/stylesheets/admin_auth.css.scss
@@ -1,18 +1,27 @@
@import "bootstrap";
body {
-padding:10px;
+padding:0px;
background-color: #f5f5f5;
}
.form-signin {
- max-width: 300px;
- padding: 19px 29px 29px;
+ max-width: 500px;
+ padding: 30px;
margin: 0 auto 20px;
- background-color: #fff;
- border: 1px solid #e5e5e5;
+ background:rgba(255,255,255,.7);
+
border-radius :5px;
box-shadow: 0 1px 2px rgba(0,0,0,.05);
+ opacity:0;
+ color:rgba(0,0,0,.5);
+ label{
+ color:rgba(0,0,0,.5);
+ }
+ p:last-child{
+
+ margin-bottom:0px;
+ }
}
@@ -26,3 +35,48 @@ padding:10px;
margin-bottom: 15px;
padding: 7px 9px;
}
+
+.input-dark{
+background:rgba(255,255,255,.5);
+border:0px;
+box-shadow: 0 1px 2px rgba(0,0,0,.4) inset;
+border-radius:3px;
+color: rgba(0,0,0,0.9);
+
+
+}
+
+::-webkit-input-placeholder {
+ color: rgba(0,0,0,0.7);
+}
+
+:-moz-placeholder { /* Firefox 18- */
+ color: rgba(0,0,0,0.7);
+}
+
+::-moz-placeholder { /* Firefox 19+ */
+ color: rgba(0,0,0,0.7);
+}
+
+:-ms-input-placeholder {
+ color: rgba(0,0,0,0.7);
+}
+
+#flashs{
+color:rgba(255,255,255,0.7);
+
+div{
+max-width: 500px;
+margin: auto;
+padding:10px;
+border:1px solid rgba(255,255,255,0.7);
+
+}
+.close{
+color:rgba(255,255,255,0.7);
+opacity:1;
+text-shadow:none;
+}
+
+}
+
diff --git a/app/assets/stylesheets/bootstrap/_forms.scss b/app/assets/stylesheets/bootstrap/_forms.scss
index 2628238..0eff9fc 100644
--- a/app/assets/stylesheets/bootstrap/_forms.scss
+++ b/app/assets/stylesheets/bootstrap/_forms.scss
@@ -32,7 +32,7 @@ legend {
label {
display: inline-block;
margin-bottom: 5px;
- font-weight: bold;
+ font-weight: normal;
}
diff --git a/app/assets/stylesheets/fontawesome/_icons.scss b/app/assets/stylesheets/fontawesome/_icons.scss
index 7490cf3..efb4435 100644
--- a/app/assets/stylesheets/fontawesome/_icons.scss
+++ b/app/assets/stylesheets/fontawesome/_icons.scss
@@ -63,6 +63,8 @@
.#{$fa-css-prefix}-outdent:before { content: $fa-var-outdent; }
.#{$fa-css-prefix}-indent:before { content: $fa-var-indent; }
.#{$fa-css-prefix}-video-camera:before { content: $fa-var-video-camera; }
+.#{$fa-css-prefix}-photo:before,
+.#{$fa-css-prefix}-image:before,
.#{$fa-css-prefix}-picture-o:before { content: $fa-var-picture-o; }
.#{$fa-css-prefix}-pencil:before { content: $fa-var-pencil; }
.#{$fa-css-prefix}-map-marker:before { content: $fa-var-map-marker; }
@@ -190,6 +192,8 @@
.#{$fa-css-prefix}-save:before,
.#{$fa-css-prefix}-floppy-o:before { content: $fa-var-floppy-o; }
.#{$fa-css-prefix}-square:before { content: $fa-var-square; }
+.#{$fa-css-prefix}-navicon:before,
+.#{$fa-css-prefix}-reorder:before,
.#{$fa-css-prefix}-bars:before { content: $fa-var-bars; }
.#{$fa-css-prefix}-list-ul:before { content: $fa-var-list-ul; }
.#{$fa-css-prefix}-list-ol:before { content: $fa-var-list-ol; }
@@ -211,9 +215,9 @@
.#{$fa-css-prefix}-unsorted:before,
.#{$fa-css-prefix}-sort:before { content: $fa-var-sort; }
.#{$fa-css-prefix}-sort-down:before,
-.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
-.#{$fa-css-prefix}-sort-up:before,
.#{$fa-css-prefix}-sort-desc:before { content: $fa-var-sort-desc; }
+.#{$fa-css-prefix}-sort-up:before,
+.#{$fa-css-prefix}-sort-asc:before { content: $fa-var-sort-asc; }
.#{$fa-css-prefix}-envelope:before { content: $fa-var-envelope; }
.#{$fa-css-prefix}-linkedin:before { content: $fa-var-linkedin; }
.#{$fa-css-prefix}-rotate-left:before,
@@ -281,8 +285,8 @@
.#{$fa-css-prefix}-flag-checkered:before { content: $fa-var-flag-checkered; }
.#{$fa-css-prefix}-terminal:before { content: $fa-var-terminal; }
.#{$fa-css-prefix}-code:before { content: $fa-var-code; }
+.#{$fa-css-prefix}-mail-reply-all:before,
.#{$fa-css-prefix}-reply-all:before { content: $fa-var-reply-all; }
-.#{$fa-css-prefix}-mail-reply-all:before { content: $fa-var-mail-reply-all; }
.#{$fa-css-prefix}-star-half-empty:before,
.#{$fa-css-prefix}-star-half-full:before,
.#{$fa-css-prefix}-star-half-o:before { content: $fa-var-star-half-o; }
@@ -410,3 +414,93 @@
.#{$fa-css-prefix}-turkish-lira:before,
.#{$fa-css-prefix}-try:before { content: $fa-var-try; }
.#{$fa-css-prefix}-plus-square-o:before { content: $fa-var-plus-square-o; }
+.#{$fa-css-prefix}-space-shuttle:before { content: $fa-var-space-shuttle; }
+.#{$fa-css-prefix}-slack:before { content: $fa-var-slack; }
+.#{$fa-css-prefix}-envelope-square:before { content: $fa-var-envelope-square; }
+.#{$fa-css-prefix}-wordpress:before { content: $fa-var-wordpress; }
+.#{$fa-css-prefix}-openid:before { content: $fa-var-openid; }
+.#{$fa-css-prefix}-institution:before,
+.#{$fa-css-prefix}-bank:before,
+.#{$fa-css-prefix}-university:before { content: $fa-var-university; }
+.#{$fa-css-prefix}-mortar-board:before,
+.#{$fa-css-prefix}-graduation-cap:before { content: $fa-var-graduation-cap; }
+.#{$fa-css-prefix}-yahoo:before { content: $fa-var-yahoo; }
+.#{$fa-css-prefix}-google:before { content: $fa-var-google; }
+.#{$fa-css-prefix}-reddit:before { content: $fa-var-reddit; }
+.#{$fa-css-prefix}-reddit-square:before { content: $fa-var-reddit-square; }
+.#{$fa-css-prefix}-stumbleupon-circle:before { content: $fa-var-stumbleupon-circle; }
+.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
+.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
+.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
+.#{$fa-css-prefix}-pied-piper-square:before,
+.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
+.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
+.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
+.#{$fa-css-prefix}-joomla:before { content: $fa-var-joomla; }
+.#{$fa-css-prefix}-language:before { content: $fa-var-language; }
+.#{$fa-css-prefix}-fax:before { content: $fa-var-fax; }
+.#{$fa-css-prefix}-building:before { content: $fa-var-building; }
+.#{$fa-css-prefix}-child:before { content: $fa-var-child; }
+.#{$fa-css-prefix}-paw:before { content: $fa-var-paw; }
+.#{$fa-css-prefix}-spoon:before { content: $fa-var-spoon; }
+.#{$fa-css-prefix}-cube:before { content: $fa-var-cube; }
+.#{$fa-css-prefix}-cubes:before { content: $fa-var-cubes; }
+.#{$fa-css-prefix}-behance:before { content: $fa-var-behance; }
+.#{$fa-css-prefix}-behance-square:before { content: $fa-var-behance-square; }
+.#{$fa-css-prefix}-steam:before { content: $fa-var-steam; }
+.#{$fa-css-prefix}-steam-square:before { content: $fa-var-steam-square; }
+.#{$fa-css-prefix}-recycle:before { content: $fa-var-recycle; }
+.#{$fa-css-prefix}-automobile:before,
+.#{$fa-css-prefix}-car:before { content: $fa-var-car; }
+.#{$fa-css-prefix}-cab:before,
+.#{$fa-css-prefix}-taxi:before { content: $fa-var-taxi; }
+.#{$fa-css-prefix}-tree:before { content: $fa-var-tree; }
+.#{$fa-css-prefix}-spotify:before { content: $fa-var-spotify; }
+.#{$fa-css-prefix}-deviantart:before { content: $fa-var-deviantart; }
+.#{$fa-css-prefix}-soundcloud:before { content: $fa-var-soundcloud; }
+.#{$fa-css-prefix}-database:before { content: $fa-var-database; }
+.#{$fa-css-prefix}-file-pdf-o:before { content: $fa-var-file-pdf-o; }
+.#{$fa-css-prefix}-file-word-o:before { content: $fa-var-file-word-o; }
+.#{$fa-css-prefix}-file-excel-o:before { content: $fa-var-file-excel-o; }
+.#{$fa-css-prefix}-file-powerpoint-o:before { content: $fa-var-file-powerpoint-o; }
+.#{$fa-css-prefix}-file-photo-o:before,
+.#{$fa-css-prefix}-file-picture-o:before,
+.#{$fa-css-prefix}-file-image-o:before { content: $fa-var-file-image-o; }
+.#{$fa-css-prefix}-file-zip-o:before,
+.#{$fa-css-prefix}-file-archive-o:before { content: $fa-var-file-archive-o; }
+.#{$fa-css-prefix}-file-sound-o:before,
+.#{$fa-css-prefix}-file-audio-o:before { content: $fa-var-file-audio-o; }
+.#{$fa-css-prefix}-file-movie-o:before,
+.#{$fa-css-prefix}-file-video-o:before { content: $fa-var-file-video-o; }
+.#{$fa-css-prefix}-file-code-o:before { content: $fa-var-file-code-o; }
+.#{$fa-css-prefix}-vine:before { content: $fa-var-vine; }
+.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
+.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
+.#{$fa-css-prefix}-life-bouy:before,
+.#{$fa-css-prefix}-life-saver:before,
+.#{$fa-css-prefix}-support:before,
+.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
+.#{$fa-css-prefix}-circle-o-notch:before { content: $fa-var-circle-o-notch; }
+.#{$fa-css-prefix}-ra:before,
+.#{$fa-css-prefix}-rebel:before { content: $fa-var-rebel; }
+.#{$fa-css-prefix}-ge:before,
+.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
+.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
+.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
+.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
+.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
+.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
+.#{$fa-css-prefix}-wechat:before,
+.#{$fa-css-prefix}-weixin:before { content: $fa-var-weixin; }
+.#{$fa-css-prefix}-send:before,
+.#{$fa-css-prefix}-paper-plane:before { content: $fa-var-paper-plane; }
+.#{$fa-css-prefix}-send-o:before,
+.#{$fa-css-prefix}-paper-plane-o:before { content: $fa-var-paper-plane-o; }
+.#{$fa-css-prefix}-history:before { content: $fa-var-history; }
+.#{$fa-css-prefix}-circle-thin:before { content: $fa-var-circle-thin; }
+.#{$fa-css-prefix}-header:before { content: $fa-var-header; }
+.#{$fa-css-prefix}-paragraph:before { content: $fa-var-paragraph; }
+.#{$fa-css-prefix}-sliders:before { content: $fa-var-sliders; }
+.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
+.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
+.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
diff --git a/app/assets/stylesheets/fontawesome/_mixins.scss b/app/assets/stylesheets/fontawesome/_mixins.scss
index 9f55596..3354e69 100644
--- a/app/assets/stylesheets/fontawesome/_mixins.scss
+++ b/app/assets/stylesheets/fontawesome/_mixins.scss
@@ -2,7 +2,7 @@
// --------------------------
@mixin fa-icon-rotate($degrees, $rotation) {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
-webkit-transform: rotate($degrees);
-moz-transform: rotate($degrees);
-ms-transform: rotate($degrees);
@@ -11,7 +11,7 @@
}
@mixin fa-icon-flip($horiz, $vert, $rotation) {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=$rotation);
+ filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
-webkit-transform: scale($horiz, $vert);
-moz-transform: scale($horiz, $vert);
-ms-transform: scale($horiz, $vert);
diff --git a/app/assets/stylesheets/fontawesome/_spinning.scss b/app/assets/stylesheets/fontawesome/_spinning.scss
index ba1e4f1..c378744 100644
--- a/app/assets/stylesheets/fontawesome/_spinning.scss
+++ b/app/assets/stylesheets/fontawesome/_spinning.scss
@@ -20,11 +20,13 @@
0% { -o-transform: rotate(0deg); }
100% { -o-transform: rotate(359deg); }
}
-@-ms-keyframes spin {
- 0% { -ms-transform: rotate(0deg); }
- 100% { -ms-transform: rotate(359deg); }
-}
@keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(359deg); }
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ 100% {
+ -webkit-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
}
diff --git a/app/assets/stylesheets/fontawesome/_variables.scss b/app/assets/stylesheets/fontawesome/_variables.scss
index efa24b9..ac2b505 100644
--- a/app/assets/stylesheets/fontawesome/_variables.scss
+++ b/app/assets/stylesheets/fontawesome/_variables.scss
@@ -1,381 +1,515 @@
// Variables
// --------------------------
-$fa-font-path: "/fonts" !default;
-//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts" !default; // for referencing Bootstrap CDN font files directly
+$fa-font-path: "../fonts" !default;
+//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly
$fa-css-prefix: fa !default;
-$fa-version: "4.0.3" !default;
+$fa-version: "4.1.0" !default;
$fa-border-color: #eee !default;
$fa-inverse: #fff !default;
-$fa-li-width: (30em / 14) !default;
+$fa-li-width: (30em / 14) !default;
-$fa-var-glass: "\f000";
-$fa-var-music: "\f001";
-$fa-var-search: "\f002";
-$fa-var-envelope-o: "\f003";
-$fa-var-heart: "\f004";
-$fa-var-star: "\f005";
-$fa-var-star-o: "\f006";
-$fa-var-user: "\f007";
-$fa-var-film: "\f008";
-$fa-var-th-large: "\f009";
-$fa-var-th: "\f00a";
-$fa-var-th-list: "\f00b";
-$fa-var-check: "\f00c";
-$fa-var-times: "\f00d";
-$fa-var-search-plus: "\f00e";
-$fa-var-search-minus: "\f010";
-$fa-var-power-off: "\f011";
-$fa-var-signal: "\f012";
-$fa-var-cog: "\f013";
-$fa-var-trash-o: "\f014";
-$fa-var-home: "\f015";
-$fa-var-file-o: "\f016";
-$fa-var-clock-o: "\f017";
-$fa-var-road: "\f018";
-$fa-var-download: "\f019";
-$fa-var-arrow-circle-o-down: "\f01a";
-$fa-var-arrow-circle-o-up: "\f01b";
-$fa-var-inbox: "\f01c";
-$fa-var-play-circle-o: "\f01d";
-$fa-var-repeat: "\f01e";
-$fa-var-refresh: "\f021";
-$fa-var-list-alt: "\f022";
-$fa-var-lock: "\f023";
-$fa-var-flag: "\f024";
-$fa-var-headphones: "\f025";
-$fa-var-volume-off: "\f026";
-$fa-var-volume-down: "\f027";
-$fa-var-volume-up: "\f028";
-$fa-var-qrcode: "\f029";
-$fa-var-barcode: "\f02a";
-$fa-var-tag: "\f02b";
-$fa-var-tags: "\f02c";
-$fa-var-book: "\f02d";
-$fa-var-bookmark: "\f02e";
-$fa-var-print: "\f02f";
-$fa-var-camera: "\f030";
-$fa-var-font: "\f031";
-$fa-var-bold: "\f032";
-$fa-var-italic: "\f033";
-$fa-var-text-height: "\f034";
-$fa-var-text-width: "\f035";
-$fa-var-align-left: "\f036";
-$fa-var-align-center: "\f037";
-$fa-var-align-right: "\f038";
-$fa-var-align-justify: "\f039";
-$fa-var-list: "\f03a";
-$fa-var-outdent: "\f03b";
-$fa-var-indent: "\f03c";
-$fa-var-video-camera: "\f03d";
-$fa-var-picture-o: "\f03e";
-$fa-var-pencil: "\f040";
-$fa-var-map-marker: "\f041";
$fa-var-adjust: "\f042";
-$fa-var-tint: "\f043";
-$fa-var-pencil-square-o: "\f044";
-$fa-var-share-square-o: "\f045";
-$fa-var-check-square-o: "\f046";
-$fa-var-arrows: "\f047";
-$fa-var-step-backward: "\f048";
-$fa-var-fast-backward: "\f049";
-$fa-var-backward: "\f04a";
-$fa-var-play: "\f04b";
-$fa-var-pause: "\f04c";
-$fa-var-stop: "\f04d";
-$fa-var-forward: "\f04e";
-$fa-var-fast-forward: "\f050";
-$fa-var-step-forward: "\f051";
-$fa-var-eject: "\f052";
-$fa-var-chevron-left: "\f053";
-$fa-var-chevron-right: "\f054";
-$fa-var-plus-circle: "\f055";
-$fa-var-minus-circle: "\f056";
-$fa-var-times-circle: "\f057";
-$fa-var-check-circle: "\f058";
-$fa-var-question-circle: "\f059";
-$fa-var-info-circle: "\f05a";
-$fa-var-crosshairs: "\f05b";
-$fa-var-times-circle-o: "\f05c";
-$fa-var-check-circle-o: "\f05d";
-$fa-var-ban: "\f05e";
-$fa-var-arrow-left: "\f060";
-$fa-var-arrow-right: "\f061";
-$fa-var-arrow-up: "\f062";
-$fa-var-arrow-down: "\f063";
-$fa-var-share: "\f064";
-$fa-var-expand: "\f065";
-$fa-var-compress: "\f066";
-$fa-var-plus: "\f067";
-$fa-var-minus: "\f068";
-$fa-var-asterisk: "\f069";
-$fa-var-exclamation-circle: "\f06a";
-$fa-var-gift: "\f06b";
-$fa-var-leaf: "\f06c";
-$fa-var-fire: "\f06d";
-$fa-var-eye: "\f06e";
-$fa-var-eye-slash: "\f070";
-$fa-var-exclamation-triangle: "\f071";
-$fa-var-plane: "\f072";
-$fa-var-calendar: "\f073";
-$fa-var-random: "\f074";
-$fa-var-comment: "\f075";
-$fa-var-magnet: "\f076";
-$fa-var-chevron-up: "\f077";
-$fa-var-chevron-down: "\f078";
-$fa-var-retweet: "\f079";
-$fa-var-shopping-cart: "\f07a";
-$fa-var-folder: "\f07b";
-$fa-var-folder-open: "\f07c";
-$fa-var-arrows-v: "\f07d";
-$fa-var-arrows-h: "\f07e";
-$fa-var-bar-chart-o: "\f080";
-$fa-var-twitter-square: "\f081";
-$fa-var-facebook-square: "\f082";
-$fa-var-camera-retro: "\f083";
-$fa-var-key: "\f084";
-$fa-var-cogs: "\f085";
-$fa-var-comments: "\f086";
-$fa-var-thumbs-o-up: "\f087";
-$fa-var-thumbs-o-down: "\f088";
-$fa-var-star-half: "\f089";
-$fa-var-heart-o: "\f08a";
-$fa-var-sign-out: "\f08b";
-$fa-var-linkedin-square: "\f08c";
-$fa-var-thumb-tack: "\f08d";
-$fa-var-external-link: "\f08e";
-$fa-var-sign-in: "\f090";
-$fa-var-trophy: "\f091";
-$fa-var-github-square: "\f092";
-$fa-var-upload: "\f093";
-$fa-var-lemon-o: "\f094";
-$fa-var-phone: "\f095";
-$fa-var-square-o: "\f096";
-$fa-var-bookmark-o: "\f097";
-$fa-var-phone-square: "\f098";
-$fa-var-twitter: "\f099";
-$fa-var-facebook: "\f09a";
-$fa-var-github: "\f09b";
-$fa-var-unlock: "\f09c";
-$fa-var-credit-card: "\f09d";
-$fa-var-rss: "\f09e";
-$fa-var-hdd-o: "\f0a0";
-$fa-var-bullhorn: "\f0a1";
-$fa-var-bell: "\f0f3";
-$fa-var-certificate: "\f0a3";
-$fa-var-hand-o-right: "\f0a4";
-$fa-var-hand-o-left: "\f0a5";
-$fa-var-hand-o-up: "\f0a6";
-$fa-var-hand-o-down: "\f0a7";
-$fa-var-arrow-circle-left: "\f0a8";
-$fa-var-arrow-circle-right: "\f0a9";
-$fa-var-arrow-circle-up: "\f0aa";
-$fa-var-arrow-circle-down: "\f0ab";
-$fa-var-globe: "\f0ac";
-$fa-var-wrench: "\f0ad";
-$fa-var-tasks: "\f0ae";
-$fa-var-filter: "\f0b0";
-$fa-var-briefcase: "\f0b1";
-$fa-var-arrows-alt: "\f0b2";
-$fa-var-users: "\f0c0";
-$fa-var-link: "\f0c1";
-$fa-var-cloud: "\f0c2";
-$fa-var-flask: "\f0c3";
-$fa-var-scissors: "\f0c4";
-$fa-var-files-o: "\f0c5";
-$fa-var-paperclip: "\f0c6";
-$fa-var-floppy-o: "\f0c7";
-$fa-var-square: "\f0c8";
-$fa-var-bars: "\f0c9";
-$fa-var-list-ul: "\f0ca";
-$fa-var-list-ol: "\f0cb";
-$fa-var-strikethrough: "\f0cc";
-$fa-var-underline: "\f0cd";
-$fa-var-table: "\f0ce";
-$fa-var-magic: "\f0d0";
-$fa-var-truck: "\f0d1";
-$fa-var-pinterest: "\f0d2";
-$fa-var-pinterest-square: "\f0d3";
-$fa-var-google-plus-square: "\f0d4";
-$fa-var-google-plus: "\f0d5";
-$fa-var-money: "\f0d6";
-$fa-var-caret-down: "\f0d7";
-$fa-var-caret-up: "\f0d8";
-$fa-var-caret-left: "\f0d9";
-$fa-var-caret-right: "\f0da";
-$fa-var-columns: "\f0db";
-$fa-var-sort: "\f0dc";
-$fa-var-sort-asc: "\f0dd";
-$fa-var-sort-desc: "\f0de";
-$fa-var-envelope: "\f0e0";
-$fa-var-linkedin: "\f0e1";
-$fa-var-undo: "\f0e2";
-$fa-var-gavel: "\f0e3";
-$fa-var-tachometer: "\f0e4";
-$fa-var-comment-o: "\f0e5";
-$fa-var-comments-o: "\f0e6";
-$fa-var-bolt: "\f0e7";
-$fa-var-sitemap: "\f0e8";
-$fa-var-umbrella: "\f0e9";
-$fa-var-clipboard: "\f0ea";
-$fa-var-lightbulb-o: "\f0eb";
-$fa-var-exchange: "\f0ec";
-$fa-var-cloud-download: "\f0ed";
-$fa-var-cloud-upload: "\f0ee";
-$fa-var-user-md: "\f0f0";
-$fa-var-stethoscope: "\f0f1";
-$fa-var-suitcase: "\f0f2";
-$fa-var-bell-o: "\f0a2";
-$fa-var-coffee: "\f0f4";
-$fa-var-cutlery: "\f0f5";
-$fa-var-file-text-o: "\f0f6";
-$fa-var-building-o: "\f0f7";
-$fa-var-hospital-o: "\f0f8";
+$fa-var-adn: "\f170";
+$fa-var-align-center: "\f037";
+$fa-var-align-justify: "\f039";
+$fa-var-align-left: "\f036";
+$fa-var-align-right: "\f038";
$fa-var-ambulance: "\f0f9";
-$fa-var-medkit: "\f0fa";
-$fa-var-fighter-jet: "\f0fb";
-$fa-var-beer: "\f0fc";
-$fa-var-h-square: "\f0fd";
-$fa-var-plus-square: "\f0fe";
+$fa-var-anchor: "\f13d";
+$fa-var-android: "\f17b";
+$fa-var-angle-double-down: "\f103";
$fa-var-angle-double-left: "\f100";
$fa-var-angle-double-right: "\f101";
$fa-var-angle-double-up: "\f102";
-$fa-var-angle-double-down: "\f103";
+$fa-var-angle-down: "\f107";
$fa-var-angle-left: "\f104";
$fa-var-angle-right: "\f105";
$fa-var-angle-up: "\f106";
-$fa-var-angle-down: "\f107";
-$fa-var-desktop: "\f108";
-$fa-var-laptop: "\f109";
-$fa-var-tablet: "\f10a";
-$fa-var-mobile: "\f10b";
-$fa-var-circle-o: "\f10c";
-$fa-var-quote-left: "\f10d";
-$fa-var-quote-right: "\f10e";
-$fa-var-spinner: "\f110";
-$fa-var-circle: "\f111";
-$fa-var-reply: "\f112";
-$fa-var-github-alt: "\f113";
-$fa-var-folder-o: "\f114";
-$fa-var-folder-open-o: "\f115";
-$fa-var-smile-o: "\f118";
-$fa-var-frown-o: "\f119";
-$fa-var-meh-o: "\f11a";
-$fa-var-gamepad: "\f11b";
-$fa-var-keyboard-o: "\f11c";
-$fa-var-flag-o: "\f11d";
-$fa-var-flag-checkered: "\f11e";
-$fa-var-terminal: "\f120";
-$fa-var-code: "\f121";
-$fa-var-reply-all: "\f122";
-$fa-var-mail-reply-all: "\f122";
-$fa-var-star-half-o: "\f123";
-$fa-var-location-arrow: "\f124";
-$fa-var-crop: "\f125";
-$fa-var-code-fork: "\f126";
-$fa-var-chain-broken: "\f127";
-$fa-var-question: "\f128";
-$fa-var-info: "\f129";
-$fa-var-exclamation: "\f12a";
-$fa-var-superscript: "\f12b";
-$fa-var-subscript: "\f12c";
-$fa-var-eraser: "\f12d";
-$fa-var-puzzle-piece: "\f12e";
-$fa-var-microphone: "\f130";
-$fa-var-microphone-slash: "\f131";
-$fa-var-shield: "\f132";
+$fa-var-apple: "\f179";
+$fa-var-archive: "\f187";
+$fa-var-arrow-circle-down: "\f0ab";
+$fa-var-arrow-circle-left: "\f0a8";
+$fa-var-arrow-circle-o-down: "\f01a";
+$fa-var-arrow-circle-o-left: "\f190";
+$fa-var-arrow-circle-o-right: "\f18e";
+$fa-var-arrow-circle-o-up: "\f01b";
+$fa-var-arrow-circle-right: "\f0a9";
+$fa-var-arrow-circle-up: "\f0aa";
+$fa-var-arrow-down: "\f063";
+$fa-var-arrow-left: "\f060";
+$fa-var-arrow-right: "\f061";
+$fa-var-arrow-up: "\f062";
+$fa-var-arrows: "\f047";
+$fa-var-arrows-alt: "\f0b2";
+$fa-var-arrows-h: "\f07e";
+$fa-var-arrows-v: "\f07d";
+$fa-var-asterisk: "\f069";
+$fa-var-automobile: "\f1b9";
+$fa-var-backward: "\f04a";
+$fa-var-ban: "\f05e";
+$fa-var-bank: "\f19c";
+$fa-var-bar-chart-o: "\f080";
+$fa-var-barcode: "\f02a";
+$fa-var-bars: "\f0c9";
+$fa-var-beer: "\f0fc";
+$fa-var-behance: "\f1b4";
+$fa-var-behance-square: "\f1b5";
+$fa-var-bell: "\f0f3";
+$fa-var-bell-o: "\f0a2";
+$fa-var-bitbucket: "\f171";
+$fa-var-bitbucket-square: "\f172";
+$fa-var-bitcoin: "\f15a";
+$fa-var-bold: "\f032";
+$fa-var-bolt: "\f0e7";
+$fa-var-bomb: "\f1e2";
+$fa-var-book: "\f02d";
+$fa-var-bookmark: "\f02e";
+$fa-var-bookmark-o: "\f097";
+$fa-var-briefcase: "\f0b1";
+$fa-var-btc: "\f15a";
+$fa-var-bug: "\f188";
+$fa-var-building: "\f1ad";
+$fa-var-building-o: "\f0f7";
+$fa-var-bullhorn: "\f0a1";
+$fa-var-bullseye: "\f140";
+$fa-var-cab: "\f1ba";
+$fa-var-calendar: "\f073";
$fa-var-calendar-o: "\f133";
-$fa-var-fire-extinguisher: "\f134";
-$fa-var-rocket: "\f135";
-$fa-var-maxcdn: "\f136";
+$fa-var-camera: "\f030";
+$fa-var-camera-retro: "\f083";
+$fa-var-car: "\f1b9";
+$fa-var-caret-down: "\f0d7";
+$fa-var-caret-left: "\f0d9";
+$fa-var-caret-right: "\f0da";
+$fa-var-caret-square-o-down: "\f150";
+$fa-var-caret-square-o-left: "\f191";
+$fa-var-caret-square-o-right: "\f152";
+$fa-var-caret-square-o-up: "\f151";
+$fa-var-caret-up: "\f0d8";
+$fa-var-certificate: "\f0a3";
+$fa-var-chain: "\f0c1";
+$fa-var-chain-broken: "\f127";
+$fa-var-check: "\f00c";
+$fa-var-check-circle: "\f058";
+$fa-var-check-circle-o: "\f05d";
+$fa-var-check-square: "\f14a";
+$fa-var-check-square-o: "\f046";
+$fa-var-chevron-circle-down: "\f13a";
$fa-var-chevron-circle-left: "\f137";
$fa-var-chevron-circle-right: "\f138";
$fa-var-chevron-circle-up: "\f139";
-$fa-var-chevron-circle-down: "\f13a";
-$fa-var-html5: "\f13b";
+$fa-var-chevron-down: "\f078";
+$fa-var-chevron-left: "\f053";
+$fa-var-chevron-right: "\f054";
+$fa-var-chevron-up: "\f077";
+$fa-var-child: "\f1ae";
+$fa-var-circle: "\f111";
+$fa-var-circle-o: "\f10c";
+$fa-var-circle-o-notch: "\f1ce";
+$fa-var-circle-thin: "\f1db";
+$fa-var-clipboard: "\f0ea";
+$fa-var-clock-o: "\f017";
+$fa-var-cloud: "\f0c2";
+$fa-var-cloud-download: "\f0ed";
+$fa-var-cloud-upload: "\f0ee";
+$fa-var-cny: "\f157";
+$fa-var-code: "\f121";
+$fa-var-code-fork: "\f126";
+$fa-var-codepen: "\f1cb";
+$fa-var-coffee: "\f0f4";
+$fa-var-cog: "\f013";
+$fa-var-cogs: "\f085";
+$fa-var-columns: "\f0db";
+$fa-var-comment: "\f075";
+$fa-var-comment-o: "\f0e5";
+$fa-var-comments: "\f086";
+$fa-var-comments-o: "\f0e6";
+$fa-var-compass: "\f14e";
+$fa-var-compress: "\f066";
+$fa-var-copy: "\f0c5";
+$fa-var-credit-card: "\f09d";
+$fa-var-crop: "\f125";
+$fa-var-crosshairs: "\f05b";
$fa-var-css3: "\f13c";
-$fa-var-anchor: "\f13d";
-$fa-var-unlock-alt: "\f13e";
-$fa-var-bullseye: "\f140";
+$fa-var-cube: "\f1b2";
+$fa-var-cubes: "\f1b3";
+$fa-var-cut: "\f0c4";
+$fa-var-cutlery: "\f0f5";
+$fa-var-dashboard: "\f0e4";
+$fa-var-database: "\f1c0";
+$fa-var-dedent: "\f03b";
+$fa-var-delicious: "\f1a5";
+$fa-var-desktop: "\f108";
+$fa-var-deviantart: "\f1bd";
+$fa-var-digg: "\f1a6";
+$fa-var-dollar: "\f155";
+$fa-var-dot-circle-o: "\f192";
+$fa-var-download: "\f019";
+$fa-var-dribbble: "\f17d";
+$fa-var-dropbox: "\f16b";
+$fa-var-drupal: "\f1a9";
+$fa-var-edit: "\f044";
+$fa-var-eject: "\f052";
$fa-var-ellipsis-h: "\f141";
$fa-var-ellipsis-v: "\f142";
-$fa-var-rss-square: "\f143";
-$fa-var-play-circle: "\f144";
-$fa-var-ticket: "\f145";
+$fa-var-empire: "\f1d1";
+$fa-var-envelope: "\f0e0";
+$fa-var-envelope-o: "\f003";
+$fa-var-envelope-square: "\f199";
+$fa-var-eraser: "\f12d";
+$fa-var-eur: "\f153";
+$fa-var-euro: "\f153";
+$fa-var-exchange: "\f0ec";
+$fa-var-exclamation: "\f12a";
+$fa-var-exclamation-circle: "\f06a";
+$fa-var-exclamation-triangle: "\f071";
+$fa-var-expand: "\f065";
+$fa-var-external-link: "\f08e";
+$fa-var-external-link-square: "\f14c";
+$fa-var-eye: "\f06e";
+$fa-var-eye-slash: "\f070";
+$fa-var-facebook: "\f09a";
+$fa-var-facebook-square: "\f082";
+$fa-var-fast-backward: "\f049";
+$fa-var-fast-forward: "\f050";
+$fa-var-fax: "\f1ac";
+$fa-var-female: "\f182";
+$fa-var-fighter-jet: "\f0fb";
+$fa-var-file: "\f15b";
+$fa-var-file-archive-o: "\f1c6";
+$fa-var-file-audio-o: "\f1c7";
+$fa-var-file-code-o: "\f1c9";
+$fa-var-file-excel-o: "\f1c3";
+$fa-var-file-image-o: "\f1c5";
+$fa-var-file-movie-o: "\f1c8";
+$fa-var-file-o: "\f016";
+$fa-var-file-pdf-o: "\f1c1";
+$fa-var-file-photo-o: "\f1c5";
+$fa-var-file-picture-o: "\f1c5";
+$fa-var-file-powerpoint-o: "\f1c4";
+$fa-var-file-sound-o: "\f1c7";
+$fa-var-file-text: "\f15c";
+$fa-var-file-text-o: "\f0f6";
+$fa-var-file-video-o: "\f1c8";
+$fa-var-file-word-o: "\f1c2";
+$fa-var-file-zip-o: "\f1c6";
+$fa-var-files-o: "\f0c5";
+$fa-var-film: "\f008";
+$fa-var-filter: "\f0b0";
+$fa-var-fire: "\f06d";
+$fa-var-fire-extinguisher: "\f134";
+$fa-var-flag: "\f024";
+$fa-var-flag-checkered: "\f11e";
+$fa-var-flag-o: "\f11d";
+$fa-var-flash: "\f0e7";
+$fa-var-flask: "\f0c3";
+$fa-var-flickr: "\f16e";
+$fa-var-floppy-o: "\f0c7";
+$fa-var-folder: "\f07b";
+$fa-var-folder-o: "\f114";
+$fa-var-folder-open: "\f07c";
+$fa-var-folder-open-o: "\f115";
+$fa-var-font: "\f031";
+$fa-var-forward: "\f04e";
+$fa-var-foursquare: "\f180";
+$fa-var-frown-o: "\f119";
+$fa-var-gamepad: "\f11b";
+$fa-var-gavel: "\f0e3";
+$fa-var-gbp: "\f154";
+$fa-var-ge: "\f1d1";
+$fa-var-gear: "\f013";
+$fa-var-gears: "\f085";
+$fa-var-gift: "\f06b";
+$fa-var-git: "\f1d3";
+$fa-var-git-square: "\f1d2";
+$fa-var-github: "\f09b";
+$fa-var-github-alt: "\f113";
+$fa-var-github-square: "\f092";
+$fa-var-gittip: "\f184";
+$fa-var-glass: "\f000";
+$fa-var-globe: "\f0ac";
+$fa-var-google: "\f1a0";
+$fa-var-google-plus: "\f0d5";
+$fa-var-google-plus-square: "\f0d4";
+$fa-var-graduation-cap: "\f19d";
+$fa-var-group: "\f0c0";
+$fa-var-h-square: "\f0fd";
+$fa-var-hacker-news: "\f1d4";
+$fa-var-hand-o-down: "\f0a7";
+$fa-var-hand-o-left: "\f0a5";
+$fa-var-hand-o-right: "\f0a4";
+$fa-var-hand-o-up: "\f0a6";
+$fa-var-hdd-o: "\f0a0";
+$fa-var-header: "\f1dc";
+$fa-var-headphones: "\f025";
+$fa-var-heart: "\f004";
+$fa-var-heart-o: "\f08a";
+$fa-var-history: "\f1da";
+$fa-var-home: "\f015";
+$fa-var-hospital-o: "\f0f8";
+$fa-var-html5: "\f13b";
+$fa-var-image: "\f03e";
+$fa-var-inbox: "\f01c";
+$fa-var-indent: "\f03c";
+$fa-var-info: "\f129";
+$fa-var-info-circle: "\f05a";
+$fa-var-inr: "\f156";
+$fa-var-instagram: "\f16d";
+$fa-var-institution: "\f19c";
+$fa-var-italic: "\f033";
+$fa-var-joomla: "\f1aa";
+$fa-var-jpy: "\f157";
+$fa-var-jsfiddle: "\f1cc";
+$fa-var-key: "\f084";
+$fa-var-keyboard-o: "\f11c";
+$fa-var-krw: "\f159";
+$fa-var-language: "\f1ab";
+$fa-var-laptop: "\f109";
+$fa-var-leaf: "\f06c";
+$fa-var-legal: "\f0e3";
+$fa-var-lemon-o: "\f094";
+$fa-var-level-down: "\f149";
+$fa-var-level-up: "\f148";
+$fa-var-life-bouy: "\f1cd";
+$fa-var-life-ring: "\f1cd";
+$fa-var-life-saver: "\f1cd";
+$fa-var-lightbulb-o: "\f0eb";
+$fa-var-link: "\f0c1";
+$fa-var-linkedin: "\f0e1";
+$fa-var-linkedin-square: "\f08c";
+$fa-var-linux: "\f17c";
+$fa-var-list: "\f03a";
+$fa-var-list-alt: "\f022";
+$fa-var-list-ol: "\f0cb";
+$fa-var-list-ul: "\f0ca";
+$fa-var-location-arrow: "\f124";
+$fa-var-lock: "\f023";
+$fa-var-long-arrow-down: "\f175";
+$fa-var-long-arrow-left: "\f177";
+$fa-var-long-arrow-right: "\f178";
+$fa-var-long-arrow-up: "\f176";
+$fa-var-magic: "\f0d0";
+$fa-var-magnet: "\f076";
+$fa-var-mail-forward: "\f064";
+$fa-var-mail-reply: "\f112";
+$fa-var-mail-reply-all: "\f122";
+$fa-var-male: "\f183";
+$fa-var-map-marker: "\f041";
+$fa-var-maxcdn: "\f136";
+$fa-var-medkit: "\f0fa";
+$fa-var-meh-o: "\f11a";
+$fa-var-microphone: "\f130";
+$fa-var-microphone-slash: "\f131";
+$fa-var-minus: "\f068";
+$fa-var-minus-circle: "\f056";
$fa-var-minus-square: "\f146";
$fa-var-minus-square-o: "\f147";
-$fa-var-level-up: "\f148";
-$fa-var-level-down: "\f149";
-$fa-var-check-square: "\f14a";
+$fa-var-mobile: "\f10b";
+$fa-var-mobile-phone: "\f10b";
+$fa-var-money: "\f0d6";
+$fa-var-moon-o: "\f186";
+$fa-var-mortar-board: "\f19d";
+$fa-var-music: "\f001";
+$fa-var-navicon: "\f0c9";
+$fa-var-openid: "\f19b";
+$fa-var-outdent: "\f03b";
+$fa-var-pagelines: "\f18c";
+$fa-var-paper-plane: "\f1d8";
+$fa-var-paper-plane-o: "\f1d9";
+$fa-var-paperclip: "\f0c6";
+$fa-var-paragraph: "\f1dd";
+$fa-var-paste: "\f0ea";
+$fa-var-pause: "\f04c";
+$fa-var-paw: "\f1b0";
+$fa-var-pencil: "\f040";
$fa-var-pencil-square: "\f14b";
-$fa-var-external-link-square: "\f14c";
-$fa-var-share-square: "\f14d";
-$fa-var-compass: "\f14e";
-$fa-var-caret-square-o-down: "\f150";
-$fa-var-caret-square-o-up: "\f151";
-$fa-var-caret-square-o-right: "\f152";
-$fa-var-eur: "\f153";
-$fa-var-gbp: "\f154";
-$fa-var-usd: "\f155";
-$fa-var-inr: "\f156";
-$fa-var-jpy: "\f157";
+$fa-var-pencil-square-o: "\f044";
+$fa-var-phone: "\f095";
+$fa-var-phone-square: "\f098";
+$fa-var-photo: "\f03e";
+$fa-var-picture-o: "\f03e";
+$fa-var-pied-piper: "\f1a7";
+$fa-var-pied-piper-alt: "\f1a8";
+$fa-var-pied-piper-square: "\f1a7";
+$fa-var-pinterest: "\f0d2";
+$fa-var-pinterest-square: "\f0d3";
+$fa-var-plane: "\f072";
+$fa-var-play: "\f04b";
+$fa-var-play-circle: "\f144";
+$fa-var-play-circle-o: "\f01d";
+$fa-var-plus: "\f067";
+$fa-var-plus-circle: "\f055";
+$fa-var-plus-square: "\f0fe";
+$fa-var-plus-square-o: "\f196";
+$fa-var-power-off: "\f011";
+$fa-var-print: "\f02f";
+$fa-var-puzzle-piece: "\f12e";
+$fa-var-qq: "\f1d6";
+$fa-var-qrcode: "\f029";
+$fa-var-question: "\f128";
+$fa-var-question-circle: "\f059";
+$fa-var-quote-left: "\f10d";
+$fa-var-quote-right: "\f10e";
+$fa-var-ra: "\f1d0";
+$fa-var-random: "\f074";
+$fa-var-rebel: "\f1d0";
+$fa-var-recycle: "\f1b8";
+$fa-var-reddit: "\f1a1";
+$fa-var-reddit-square: "\f1a2";
+$fa-var-refresh: "\f021";
+$fa-var-renren: "\f18b";
+$fa-var-reorder: "\f0c9";
+$fa-var-repeat: "\f01e";
+$fa-var-reply: "\f112";
+$fa-var-reply-all: "\f122";
+$fa-var-retweet: "\f079";
+$fa-var-rmb: "\f157";
+$fa-var-road: "\f018";
+$fa-var-rocket: "\f135";
+$fa-var-rotate-left: "\f0e2";
+$fa-var-rotate-right: "\f01e";
+$fa-var-rouble: "\f158";
+$fa-var-rss: "\f09e";
+$fa-var-rss-square: "\f143";
$fa-var-rub: "\f158";
-$fa-var-krw: "\f159";
-$fa-var-btc: "\f15a";
-$fa-var-file: "\f15b";
-$fa-var-file-text: "\f15c";
+$fa-var-ruble: "\f158";
+$fa-var-rupee: "\f156";
+$fa-var-save: "\f0c7";
+$fa-var-scissors: "\f0c4";
+$fa-var-search: "\f002";
+$fa-var-search-minus: "\f010";
+$fa-var-search-plus: "\f00e";
+$fa-var-send: "\f1d8";
+$fa-var-send-o: "\f1d9";
+$fa-var-share: "\f064";
+$fa-var-share-alt: "\f1e0";
+$fa-var-share-alt-square: "\f1e1";
+$fa-var-share-square: "\f14d";
+$fa-var-share-square-o: "\f045";
+$fa-var-shield: "\f132";
+$fa-var-shopping-cart: "\f07a";
+$fa-var-sign-in: "\f090";
+$fa-var-sign-out: "\f08b";
+$fa-var-signal: "\f012";
+$fa-var-sitemap: "\f0e8";
+$fa-var-skype: "\f17e";
+$fa-var-slack: "\f198";
+$fa-var-sliders: "\f1de";
+$fa-var-smile-o: "\f118";
+$fa-var-sort: "\f0dc";
$fa-var-sort-alpha-asc: "\f15d";
$fa-var-sort-alpha-desc: "\f15e";
$fa-var-sort-amount-asc: "\f160";
$fa-var-sort-amount-desc: "\f161";
+$fa-var-sort-asc: "\f0de";
+$fa-var-sort-desc: "\f0dd";
+$fa-var-sort-down: "\f0dd";
$fa-var-sort-numeric-asc: "\f162";
$fa-var-sort-numeric-desc: "\f163";
-$fa-var-thumbs-up: "\f164";
-$fa-var-thumbs-down: "\f165";
-$fa-var-youtube-square: "\f166";
-$fa-var-youtube: "\f167";
-$fa-var-xing: "\f168";
-$fa-var-xing-square: "\f169";
-$fa-var-youtube-play: "\f16a";
-$fa-var-dropbox: "\f16b";
+$fa-var-sort-up: "\f0de";
+$fa-var-soundcloud: "\f1be";
+$fa-var-space-shuttle: "\f197";
+$fa-var-spinner: "\f110";
+$fa-var-spoon: "\f1b1";
+$fa-var-spotify: "\f1bc";
+$fa-var-square: "\f0c8";
+$fa-var-square-o: "\f096";
+$fa-var-stack-exchange: "\f18d";
$fa-var-stack-overflow: "\f16c";
-$fa-var-instagram: "\f16d";
-$fa-var-flickr: "\f16e";
-$fa-var-adn: "\f170";
-$fa-var-bitbucket: "\f171";
-$fa-var-bitbucket-square: "\f172";
+$fa-var-star: "\f005";
+$fa-var-star-half: "\f089";
+$fa-var-star-half-empty: "\f123";
+$fa-var-star-half-full: "\f123";
+$fa-var-star-half-o: "\f123";
+$fa-var-star-o: "\f006";
+$fa-var-steam: "\f1b6";
+$fa-var-steam-square: "\f1b7";
+$fa-var-step-backward: "\f048";
+$fa-var-step-forward: "\f051";
+$fa-var-stethoscope: "\f0f1";
+$fa-var-stop: "\f04d";
+$fa-var-strikethrough: "\f0cc";
+$fa-var-stumbleupon: "\f1a4";
+$fa-var-stumbleupon-circle: "\f1a3";
+$fa-var-subscript: "\f12c";
+$fa-var-suitcase: "\f0f2";
+$fa-var-sun-o: "\f185";
+$fa-var-superscript: "\f12b";
+$fa-var-support: "\f1cd";
+$fa-var-table: "\f0ce";
+$fa-var-tablet: "\f10a";
+$fa-var-tachometer: "\f0e4";
+$fa-var-tag: "\f02b";
+$fa-var-tags: "\f02c";
+$fa-var-tasks: "\f0ae";
+$fa-var-taxi: "\f1ba";
+$fa-var-tencent-weibo: "\f1d5";
+$fa-var-terminal: "\f120";
+$fa-var-text-height: "\f034";
+$fa-var-text-width: "\f035";
+$fa-var-th: "\f00a";
+$fa-var-th-large: "\f009";
+$fa-var-th-list: "\f00b";
+$fa-var-thumb-tack: "\f08d";
+$fa-var-thumbs-down: "\f165";
+$fa-var-thumbs-o-down: "\f088";
+$fa-var-thumbs-o-up: "\f087";
+$fa-var-thumbs-up: "\f164";
+$fa-var-ticket: "\f145";
+$fa-var-times: "\f00d";
+$fa-var-times-circle: "\f057";
+$fa-var-times-circle-o: "\f05c";
+$fa-var-tint: "\f043";
+$fa-var-toggle-down: "\f150";
+$fa-var-toggle-left: "\f191";
+$fa-var-toggle-right: "\f152";
+$fa-var-toggle-up: "\f151";
+$fa-var-trash-o: "\f014";
+$fa-var-tree: "\f1bb";
+$fa-var-trello: "\f181";
+$fa-var-trophy: "\f091";
+$fa-var-truck: "\f0d1";
+$fa-var-try: "\f195";
$fa-var-tumblr: "\f173";
$fa-var-tumblr-square: "\f174";
-$fa-var-long-arrow-down: "\f175";
-$fa-var-long-arrow-up: "\f176";
-$fa-var-long-arrow-left: "\f177";
-$fa-var-long-arrow-right: "\f178";
-$fa-var-apple: "\f179";
-$fa-var-windows: "\f17a";
-$fa-var-android: "\f17b";
-$fa-var-linux: "\f17c";
-$fa-var-dribbble: "\f17d";
-$fa-var-skype: "\f17e";
-$fa-var-foursquare: "\f180";
-$fa-var-trello: "\f181";
-$fa-var-female: "\f182";
-$fa-var-male: "\f183";
-$fa-var-gittip: "\f184";
-$fa-var-sun-o: "\f185";
-$fa-var-moon-o: "\f186";
-$fa-var-archive: "\f187";
-$fa-var-bug: "\f188";
-$fa-var-vk: "\f189";
-$fa-var-weibo: "\f18a";
-$fa-var-renren: "\f18b";
-$fa-var-pagelines: "\f18c";
-$fa-var-stack-exchange: "\f18d";
-$fa-var-arrow-circle-o-right: "\f18e";
-$fa-var-arrow-circle-o-left: "\f190";
-$fa-var-caret-square-o-left: "\f191";
-$fa-var-dot-circle-o: "\f192";
-$fa-var-wheelchair: "\f193";
+$fa-var-turkish-lira: "\f195";
+$fa-var-twitter: "\f099";
+$fa-var-twitter-square: "\f081";
+$fa-var-umbrella: "\f0e9";
+$fa-var-underline: "\f0cd";
+$fa-var-undo: "\f0e2";
+$fa-var-university: "\f19c";
+$fa-var-unlink: "\f127";
+$fa-var-unlock: "\f09c";
+$fa-var-unlock-alt: "\f13e";
+$fa-var-unsorted: "\f0dc";
+$fa-var-upload: "\f093";
+$fa-var-usd: "\f155";
+$fa-var-user: "\f007";
+$fa-var-user-md: "\f0f0";
+$fa-var-users: "\f0c0";
+$fa-var-video-camera: "\f03d";
$fa-var-vimeo-square: "\f194";
-$fa-var-try: "\f195";
-$fa-var-plus-square-o: "\f196";
+$fa-var-vine: "\f1ca";
+$fa-var-vk: "\f189";
+$fa-var-volume-down: "\f027";
+$fa-var-volume-off: "\f026";
+$fa-var-volume-up: "\f028";
+$fa-var-warning: "\f071";
+$fa-var-wechat: "\f1d7";
+$fa-var-weibo: "\f18a";
+$fa-var-weixin: "\f1d7";
+$fa-var-wheelchair: "\f193";
+$fa-var-windows: "\f17a";
+$fa-var-won: "\f159";
+$fa-var-wordpress: "\f19a";
+$fa-var-wrench: "\f0ad";
+$fa-var-xing: "\f168";
+$fa-var-xing-square: "\f169";
+$fa-var-yahoo: "\f19e";
+$fa-var-yen: "\f157";
+$fa-var-youtube: "\f167";
+$fa-var-youtube-play: "\f16a";
+$fa-var-youtube-square: "\f166";
diff --git a/app/assets/stylesheets/fontawesome/font-awesome.scss b/app/assets/stylesheets/fontawesome/font-awesome.scss
index 96d2f22..2307dbd 100644
--- a/app/assets/stylesheets/fontawesome/font-awesome.scss
+++ b/app/assets/stylesheets/fontawesome/font-awesome.scss
@@ -1,5 +1,5 @@
/*!
- * Font Awesome 4.0.3 by @davegandy - http://fontawesome.io - @fontawesome
+ * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
diff --git a/app/assets/stylesheets/student.scss b/app/assets/stylesheets/student.scss
new file mode 100644
index 0000000..4beb13d
--- /dev/null
+++ b/app/assets/stylesheets/student.scss
@@ -0,0 +1,448 @@
+@import "bootstrap";
+@import "fontawesome/font-awesome";
+@import "./redactor";
+
+.download_content a{
+
+display:block;
+padding:5px 10px;
+border: 1px solid rgba(84,132,187,1);
+border-radius:3px;
+margin:1em 0;
+&:hover{
+background:rgba(84,132,187,.1);
+text-decoration:none;
+
+}
+}
+
+
+img{
+max-width:100%;
+}
+.row{
+//margin-left:0px;
+//margin-right:0px;
+}
+.form-signin {
+ max-width: 900px;
+ padding: 30px;
+ margin: 0 auto 20px;
+ background:rgba(255,255,255,.7);
+
+ border-radius :5px;
+ box-shadow: 0 1px 2px rgba(0,0,0,.05);
+ opacity:0;
+ color:rgba(0,0,0,.5);
+ label{
+ color:rgba(0,0,0,.5);
+ }
+ p:last-child{
+
+ margin-bottom:0px;
+ }
+
+}
+
+.white_block{
+
+background:rgba(250,250,250,0.9);
+border-radius:4px;
+}
+
+.pad{
+padding:10px;
+}
+.student_users{
+
+tr th{
+background:transparent !important;
+}
+}
+#topic_app_index{
+
+
+
+
+
+ #left{
+
+ li{
+ a{
+ background:rgba(250,250,250,0.9);
+
+
+ }
+ &.active{
+ a{
+ background:rgba(66,139,202,0.9);
+ }
+ }
+
+ }
+
+ }
+
+ #topic_show{
+
+
+ .note_files{
+ padding:10px;
+ background:rgba(84,132,187,.4);
+ }
+
+ .note_file{
+
+ margin:8px 0px;
+
+ img{
+ height:40px;
+ }
+
+
+
+ }
+
+ .note{
+ border-radius:4px;
+ margin-bottom:1em;
+ background:rgba(250,250,250,0.9);
+
+ .note_content{
+ padding:10px;
+
+ }
+ }
+
+
+
+ }
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#menu_top{
+background:rgba(84,132,187,0.5);
+border-radius:0;
+border:0;
+color:rgba(255,255,255,.9);
+
+a{
+color:rgba(255,255,255,.9);
+}
+
+.dropdown ul{
+a{
+color:rgba(0,0,0,.9);
+}
+}
+
+}
+
+#main{
+min-height:600px;
+
+}
+
+.footer{
+//background:rgba(221,221,221,1);
+padding:2em;
+}
+.transparent{
+td, th{
+background-color:transparent !important;}
+}
+#main{
+padding:0 1em;
+}
+
+.icon{
+border:1px solid #0088cc;
+display:inline-block;
+padding:6px;
+border-radius:50%;
+
+text-align:center;
+background:white;
+
+&:hover{
+background:#0088cc;
+color:white;
+text-decoration:none;
+}
+
+
+}
+
+.container-fluid{
+max-width:1100px;
+margin:auto;
+
+}
+
+h1{
+margin-top:10px;
+font-family:Stylograph;
+}
+
+.student_users{
+
+td{
+vertical-align:middle !important;
+}
+}
+
+.message{
+min-height:150px;
+border:1px solid black;
+margin:1em 1em 0 1em;
+
+}
+
+.right{float:right;}
+
+
+
+
+
+.forum_message{
+ border-radius: 0 2em 0 2em ;
+ border:1px solid rgba(244,243,239,1);
+ position:relative;
+ margin-bottom:1em;
+ min-height:120px;
+
+ .left{
+
+ border-radius :0px 0px 0px 2em ;
+ position:absolute;
+ top:0px;
+ left:0px;
+ bottom:0px;
+ width:150px;
+ background:rgba(244,243,239,1);
+ text-align:center;
+ padding:10px;
+
+
+
+ *{
+ text-align:center;
+ }
+
+ .avatar{
+ width:90px;
+ border-radius:60%;
+
+ margin:auto;
+ margin-bottom:1em;
+ }
+
+ }
+
+ .right{
+ min-height:150px;
+ margin-left:170px;
+ padding:10px 2%;
+ line-height:1.1em;
+ float:none;
+ position:relative;
+
+ img{
+ max-width:100%;
+ max-height:90%;
+ display:block;
+ margin:1em auto;
+
+
+ }
+
+
+ .large{
+ max-width:100%;
+ margin-left:0px;
+
+
+ }
+
+ .links{
+ position:absolute;
+ top:-1.2em;
+ right:1em;
+
+ }
+ }
+
+
+
+
+
+
+}
+
+.user_images{
+ width:430px;
+ box-shadow:0 0 5px rgba(0,0,0,0.5);
+ position:fixed;
+ bottom:2em;
+ right:-450px;
+ top:100px;
+ background:white;
+ padding:0;
+ padding-left:20px;
+
+ h3, a{
+ color:black;
+ }
+
+ .toggle-button{
+ font-size:25px;
+ color:white;
+ background:rgba(24,24,24,0.9);
+ width:25px;
+ height:25px;
+ text-align:center;
+ padding:10px;
+ position:absolute;
+ top:0px;
+ left:-45px;
+ .c{
+ display:none;
+ }
+ }
+
+
+ &:hover{
+ right:0px;
+ .o{
+ display:none;
+ }
+ .c{
+ display:block;
+ }
+ }
+
+ .progress{
+
+ float:right;
+ width:250px;
+
+ .bar{
+ text-align:right;
+ }
+ }
+
+input[type=file]{
+ display:none;
+
+}
+ .images{
+ height:400px;
+ overflow:auto;
+
+
+ .user_image_block{
+ padding:5px;
+ float:left;
+ width:120px;
+
+ min-height:140px;
+ text-align:center;
+ margin:5px;
+ .user_image{
+ cursor:pointer;
+ display:block;
+ margin:auto;
+ max-width:120px;
+ max-height:120px;
+
+
+ }
+ }
+ }
+
+}
+
+.redactor_box{
+border:0px !important;
+background:transparent !important;
+}
+.message_form{
+
+ .form{
+ width:60%;
+
+ float:left;
+ .ace_editor{
+ height:400px;
+ width:57%;
+ border:solid 1px #C9C9C9;
+
+
+ .ace_scroller{
+
+
+ background:transparent !important;
+ }
+
+
+
+
+ }
+ }
+
+
+
+ }
+#toolbar-text{
+
+background: linear-gradient(to bottom, #f1f1f1 0%, #e2e2e2 100%);
+z-index:10;
+position:fixed;
+top:40px;
+left:0px;
+right:0px;
+
+.redactor_toolbar{
+border:0px;
+margin:5px 0 !important;
+background:transparent !important;
+}
+}
+
+
+.fix-submit{
+z-index:10;
+position:fixed;
+top:40px;
+margin-top:5px;
+right:1em;
+
+}
+
+#flashs{
+ position:fixed;
+ bottom:0px;
+
+ right:1em;
+ min-width:600px;
+ width:50%;
+
+}
\ No newline at end of file
diff --git a/app/controllers/admin/note_files_controller.rb b/app/controllers/admin/note_files_controller.rb
new file mode 100644
index 0000000..64bf923
--- /dev/null
+++ b/app/controllers/admin/note_files_controller.rb
@@ -0,0 +1,38 @@
+# -*- encoding : utf-8 -*-
+class Admin::NoteFilesController < ApplicationController
+ before_filter :auth_admin
+
+
+layout "admin"
+
+ def show
+ @note_file = NoteFile.find(params[:id])
+
+
+ if params[:inline] and !params[:force]
+
+ else
+ send_file @note_file.file.path, :filename => @note_file.abstract_file_name_slug, :disposition => (params[:download] ? "attachment" : "inline")
+ end
+
+ end
+
+
+ def create
+
+ @note_file = NoteFile.new(:original_filename => params[:files][0].original_filename ,:name => params[:files][0].original_filename, :note_id => params[:note_id], :file =>params[:files][0])
+
+ if @note_file.save
+
+ else
+
+ end
+
+ end
+
+ def destroy
+ @note_file = NoteFile.find(params[:id])
+ @note_file.destroy
+
+ end
+end
diff --git a/app/controllers/admin/notes_controller.rb b/app/controllers/admin/notes_controller.rb
new file mode 100644
index 0000000..18afde5
--- /dev/null
+++ b/app/controllers/admin/notes_controller.rb
@@ -0,0 +1,55 @@
+# -*- encoding : utf-8 -*-
+class Admin::NotesController < ApplicationController
+ before_filter :auth_admin
+
+
+layout "admin"
+ def show
+ @note = Note.find(params[:id])
+
+
+ end
+
+
+ def new
+ @note = Note.new(:topic_id => params[:topic_id])
+
+
+ end
+
+
+ def edit
+ @note = Note.find(params[:id])
+ end
+
+ def create
+ @note = Note.new(params.require(:note).permit!)
+ @note.admin = current_admin
+
+ if @note.save
+
+ else
+ render :action => :new
+ end
+
+ end
+
+
+ def update
+ @note = Note.find(params[:id])
+
+
+ if @note.update_attributes(params.require(:note).permit!)
+
+ else
+ render :action => :edit
+ end
+
+ end
+
+ def destroy
+ @note = Note.find(params[:id])
+ @note.destroy
+
+ end
+end
diff --git a/app/controllers/admin/student_groups_controller.rb b/app/controllers/admin/student_groups_controller.rb
new file mode 100644
index 0000000..3f524f3
--- /dev/null
+++ b/app/controllers/admin/student_groups_controller.rb
@@ -0,0 +1,66 @@
+class Admin::StudentGroupsController < ApplicationController
+ layout "admin"
+
+ before_filter :auth_admin
+
+ def index
+
+ @student_groups = StudentGroup.all
+ end
+
+
+ def show
+ @student_group = StudentGroup.find(params[:id])
+
+ end
+
+
+ def new
+ @student_group = StudentGroup.new
+
+ end
+
+ def edit
+ @student_group = StudentGroup.find(params[:id])
+
+ end
+
+ def create
+ @student_group = StudentGroup.new(student_group_params)
+
+ if @student_group.save
+ redirect_to admin_student_groups_path
+ else
+ render :action => "new"
+ end
+ end
+
+ def update
+ @student_group = StudentGroup.find(params[:id])
+
+ if @student_group.update_attributes(student_group_params)
+
+ redirect_to admin_student_groups_path
+ else
+ render :action => "edit"
+ end
+
+ end
+
+
+
+ def destroy
+ @student_group = StudentGroup.find(params[:id])
+
+ @student_group.destroy if @student_group != @current_student_group
+
+ end
+
+ private
+ def student_group_params
+ params.require(:student_group).permit!
+ end
+
+
+
+end
diff --git a/app/controllers/admin/student_users_controller.rb b/app/controllers/admin/student_users_controller.rb
new file mode 100644
index 0000000..7176b60
--- /dev/null
+++ b/app/controllers/admin/student_users_controller.rb
@@ -0,0 +1,66 @@
+class Admin::StudentUsersController < ApplicationController
+ layout "admin"
+
+ before_filter :auth_admin
+
+ def index
+
+ @student_users = StudentUser.all
+ end
+
+
+ def show
+ @student_user = StudentUser.find(params[:id])
+
+ end
+
+
+ def new
+ @student_user = StudentUser.new
+
+ end
+
+ def edit
+ @student_user = StudentUser.find(params[:id])
+
+ end
+
+ def create
+ @student_user = StudentUser.new(student_user_params)
+
+ if @student_user.save
+ redirect_to admin_student_users_path
+ else
+ render :action => "new"
+ end
+ end
+
+ def update
+ @student_user = StudentUser.find(params[:id])
+
+ if @student_user.update_attributes(student_user_params)
+
+ redirect_to admin_student_users_path
+ else
+ render :action => "edit"
+ end
+
+ end
+
+
+
+ def destroy
+ @student_user = StudentUser.find(params[:id])
+
+ @student_user.destroy if @student_user != @current_student_user
+
+ end
+
+ private
+ def student_user_params
+ params.require(:student_user).permit!
+ end
+
+
+
+end
diff --git a/app/controllers/admin/topics_controller.rb b/app/controllers/admin/topics_controller.rb
new file mode 100644
index 0000000..d2aae5c
--- /dev/null
+++ b/app/controllers/admin/topics_controller.rb
@@ -0,0 +1,59 @@
+# -*- encoding : utf-8 -*-
+class Admin::TopicsController < ApplicationController
+ before_filter :auth_admin
+
+
+layout "admin"
+
+ def index
+ @topics = Topic.all
+
+ end
+
+ def show
+ @topic = Topic.find(params[:id])
+
+ end
+
+
+ def new
+ @topic = Topic.new
+
+ end
+
+
+ def edit
+ @topic = Topic.find(params[:id])
+ end
+
+ def create
+ @topic = Topic.new(params.require(:topic).permit!)
+ @topic.admin = current_admin
+
+ if @topic.save
+ @topics = Topic.all
+ else
+ @topic_create = true
+ render :action => :new
+ end
+
+ end
+
+ def update
+ @topic = Topic.find(params[:id])
+
+
+ if @topic.update_attributes(params.require(:topic).permit!)
+ @topics = Topic.all
+ else
+ render :action => :edit
+ end
+
+ end
+
+ def destroy
+ @topic = Topic.find(params[:id])
+ @topic.destroy
+ end
+
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 95b43a9..b095718 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -12,8 +12,37 @@ class ApplicationController < ActionController::Base
end
+ def auth_suser
+ if !current_suser
+ redirect_to new_student_auth_path
+ end
+
+
+ end
+
+
private
+ def current_suser
+
+ @current_suser ||= StudentUser.find_by_auth_token!(cookies[:student_auth_token]) if cookies[:student_auth_token]
+
+ if @current_suser.lock?
+ @current_suser = false
+ end
+
+ return @current_suser
+
+ #if session[:student_user_id] and StudentUser.exists?(session[:student_user_id])
+ # @current_suser = StudentUser.find(session[:student_user_id])
+ #else
+ # nil
+ #end
+
+ end
+
+ helper_method :current_suser, :auth_suser
+
def current_admin
if cookies[:admin_remember_token]
diff --git a/app/controllers/portlet/block_contents_controller.rb b/app/controllers/portlet/block_contents_controller.rb
index cc92966..d77b793 100644
--- a/app/controllers/portlet/block_contents_controller.rb
+++ b/app/controllers/portlet/block_contents_controller.rb
@@ -102,7 +102,7 @@ class Portlet::BlockContentsController < ApplicationController
end
respond_to do |format|
- format.html {}
+ format.html {render :inline => "test"}
format.js { render :template => "portlet/shared/destroy" }
end
end
diff --git a/app/controllers/public/menu_items_controller.rb b/app/controllers/public/menu_items_controller.rb
index bb2abf1..046246e 100644
--- a/app/controllers/public/menu_items_controller.rb
+++ b/app/controllers/public/menu_items_controller.rb
@@ -39,7 +39,7 @@ class Public::MenuItemsController < ApplicationController
end
else
- redirect_to "/", :notice => "La page que vous demandez n'a pas pu être trouvée.
Vous avez donc été redirigé sur notre page d'accueil"
+ @menu_item = MenuItem.find_by_slug("404")
end
end
diff --git a/app/controllers/student/auths_controller.rb b/app/controllers/student/auths_controller.rb
new file mode 100644
index 0000000..151798c
--- /dev/null
+++ b/app/controllers/student/auths_controller.rb
@@ -0,0 +1,40 @@
+# -*- encoding : utf-8 -*-
+class Student::AuthsController < ApplicationController
+ layout "connexion"
+
+ def new
+ @student = true
+ end
+
+ def create
+ @student = true
+ user = StudentUser.find_by_email(params[:email])
+ if user && user.authenticate(params[:password]) && !user.lock
+ #session[:student_user_id] = user.id
+
+
+ if params[:remember_me]
+ cookies.permanent[:student_auth_token] = user.auth_token
+ else
+ cookies[:student_auth_token] = user.auth_token
+ end
+
+ redirect_to student_root_path, notice: "Connecté !"
+
+
+ elsif user && user.authenticate(params[:password])
+
+ flash.now[:error] = "Votre compte n'est pas encore activé."
+ render "new"
+
+ else
+ flash.now[:error] = "Email ou mot de passe incorect"
+ render "new"
+ end
+ end
+
+ def logout
+ cookies.delete(:student_auth_token)
+ redirect_to student_root_path, notice: "Déconnecté."
+ end
+end
diff --git a/app/controllers/student/password_resets_controller.rb b/app/controllers/student/password_resets_controller.rb
new file mode 100644
index 0000000..638b9e2
--- /dev/null
+++ b/app/controllers/student/password_resets_controller.rb
@@ -0,0 +1,52 @@
+# -*- encoding : utf-8 -*-
+class Student::PasswordResetsController < ApplicationController
+ layout "connexion"
+
+ def new
+ @student = true
+ end
+
+ def create
+ @student = true
+ student_user = StudentUser.find_by_email(params[:email])
+ if student_user
+ student_user.reset_password_token = SecureRandom.urlsafe_base64(nil, false)
+ student_user.reset_password_sent_at = Time.now
+ student_user.save
+ StudentMails.reset_password(student_user).deliver
+ redirect_to student_student_topics_path, notice: "Un message vient de vous être envoyé avec un lien pour réinitialiser votre mot de passe."
+ else
+ flash.now.alert = "Email incorect"
+ render "new"
+ end
+ end
+
+ def edit
+ @student = true
+
+ @student_user = StudentUser.find_by_reset_password_token(params[:id])
+
+ if @student_user and @student_user.reset_password_sent_at > Time.now - 1.day
+
+ else
+
+ end
+ end
+
+ def update
+ @student = true
+
+ @student_user = StudentUser.find_by_reset_password_token(params[:id])
+
+ if @student_user.update_attributes(params.require(:student_user).permit(:password, :password_confirmation))
+ redirect_to student_student_topics_path, :notice => "Votre mot de passe a bien été changé, vous pouvez vous connecter dès maintenant."
+
+ else
+ render :action => "edit"
+ end
+
+
+
+ end
+
+end
diff --git a/app/controllers/student/student_users_controller.rb b/app/controllers/student/student_users_controller.rb
new file mode 100644
index 0000000..fe3c64a
--- /dev/null
+++ b/app/controllers/student/student_users_controller.rb
@@ -0,0 +1,72 @@
+class Student::StudentUsersController < ApplicationController
+ layout "student"
+
+ before_filter :auth_suser, :except => [:new, :create]
+
+ def index
+
+ @users = StudentUser.all
+ end
+
+
+ def show
+ @user = StudentUser.find(params[:id])
+
+ end
+
+
+ def new
+ @user = StudentUser.new()
+
+ end
+
+ def edit
+ @user = StudentUser.find(params[:id])
+
+ end
+
+ def create
+ @user = StudentUser.new(params.require(:student_user).permit!)
+ @user.lock = true
+ @user.locked_at = Time.now
+ if @user.save
+
+ @user.authenticate(params[:password])
+ session[:student_user_id] = @user.id
+ redirect_to student_student_topics_path, notice: "Vous êtes désormais inscrit."
+
+
+
+ else
+ render :action => "new"
+ end
+ end
+
+ def update
+ @user = StudentUser.find(params[:id])
+ if @user == current_suser or moderator?
+
+
+ if @user.update_attributes(params.require(:student_user).permit!)
+ redirect_to student_student_user_path(@user)
+
+ else
+ render :action => "edit"
+ end
+ end
+ end
+
+
+
+ def destroy
+ if moderator?
+ @user = StudentUser.find(params[:id])
+ @user.destroy
+ redirect_to student_student_users_path
+ end
+
+ end
+
+
+
+end
diff --git a/app/controllers/student/topics_controller.rb b/app/controllers/student/topics_controller.rb
new file mode 100644
index 0000000..d880341
--- /dev/null
+++ b/app/controllers/student/topics_controller.rb
@@ -0,0 +1,21 @@
+# -*- encoding : utf-8 -*-
+class Student::TopicsController < ApplicationController
+ before_filter :auth_admin
+
+
+layout "student"
+
+ def index
+ @topics = current_suser.topics.order("updated_at DESC").uniq
+ @topic = @topics[0]
+
+ end
+
+ def show
+ @topic = Topic.find(params[:id])
+ render :layout => false
+ end
+
+
+
+end
diff --git a/app/mailers/student_mails.rb b/app/mailers/student_mails.rb
new file mode 100644
index 0000000..b0c5a32
--- /dev/null
+++ b/app/mailers/student_mails.rb
@@ -0,0 +1,16 @@
+class StudentMails < ActionMailer::Base
+ layout 'mail'
+
+ default from: "Geneviève Gagos
"
+
+ def reset_password(student_user, options = {})
+ @student_user = student_user
+ @options = options
+ mail(:to => student_user.email, :subject => "Réinitialisation de votre mot de passe.")
+ end
+
+
+
+
+
+end
diff --git a/app/models/block.rb b/app/models/block.rb
index 1accc54..19108ec 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -13,7 +13,7 @@ class Block < ActiveRecord::Base
DynamicContent: "Contenu dynamique",
TableContent: "Tableau",
BlockContent: "Bloc",
- MapContent: "Plan",
+ MapContent: "Plan"
}
@@ -36,10 +36,10 @@ class Block < ActiveRecord::Base
end
end
-def alloweds_types
- allow_types :all #:TitleContent, :ImageContent
+ def alloweds_types
+ allow_types :all #:TitleContent, :ImageContent
-end
+ end
def dup
@block = Block.new(self.attributes)
diff --git a/app/models/block_content.rb b/app/models/block_content.rb
index e661386..469319a 100644
--- a/app/models/block_content.rb
+++ b/app/models/block_content.rb
@@ -1,7 +1,7 @@
# -*- encoding : utf-8 -*-
class BlockContent < ActiveRecord::Base
has_one :portlet, :as => :content, :dependent => :destroy
- has_many :blocks, :as => :blockable, :dependent => :destroy
+ has_many :blocks, :as => :blockable #, :dependent => :destroy
validates :nbr_columns, :presence => true
diff --git a/app/models/note.rb b/app/models/note.rb
new file mode 100644
index 0000000..97e5856
--- /dev/null
+++ b/app/models/note.rb
@@ -0,0 +1,7 @@
+# -*- encoding : utf-8 -*-
+class Note < ActiveRecord::Base
+ belongs_to :admin
+ belongs_to :topic
+ has_many :note_files
+ #attr_accessible :message, :subject, :topic, :topic_id
+end
diff --git a/app/models/note_file.rb b/app/models/note_file.rb
new file mode 100644
index 0000000..41beec1
--- /dev/null
+++ b/app/models/note_file.rb
@@ -0,0 +1,36 @@
+# -*- encoding : utf-8 -*-
+class NoteFile < ActiveRecord::Base
+
+ attr_accessor :original_filename
+ #attr_accessible :description, :file, :name, :slug, :note, :note_id, :file_cache, :original_filename
+ belongs_to :note
+ mount_uploader :file, FileUploader
+
+
+ before_save do
+ if !self.name?
+ self.name = File.basename(self.file.filename, File.extname(self.file.filename)).to_s if self.file?
+ end
+
+ end
+
+
+
+
+ def file_type
+
+
+ mime = `file --mime -br "#{self.file.path}"`.strip.split(';')[0]
+ mime
+
+ end
+
+ def abstract_file_name
+ self.name+File.extname(self.attributes['file'])
+ end
+
+ def abstract_file_name_slug
+ self.name.to_slug+File.extname(self.attributes['file'])
+ end
+
+end
diff --git a/app/models/student_group.rb b/app/models/student_group.rb
new file mode 100644
index 0000000..b58d1b0
--- /dev/null
+++ b/app/models/student_group.rb
@@ -0,0 +1,8 @@
+class StudentGroup < ActiveRecord::Base
+
+ has_many :student_user_groups
+ has_many :student_user, :through => :student_user_groups
+
+ has_many :topic_student_groups
+ has_many :topics, :through => :topic_student_groups
+end
diff --git a/app/models/student_user.rb b/app/models/student_user.rb
new file mode 100644
index 0000000..ca4d3fe
--- /dev/null
+++ b/app/models/student_user.rb
@@ -0,0 +1,40 @@
+class StudentUser < ActiveRecord::Base
+ #attr_accessible :bio, :email, :firstname, :name, :password, :password_confirmation, :avatar, :moderator
+
+ has_secure_password
+ validates_presence_of :password, :on => :create
+ validates :email, :presence => true, :uniqueness => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
+ validates :name, :presence => true
+ validates :firstname, :presence => true
+
+ mount_uploader :avatar, AvatarUploader
+
+ has_many :messages, :class_name => "StudentMessage"
+ has_many :topics, :class_name => "StudentTopic"
+
+ has_many :images, :class_name => "StudentUserImage", :order => "created_at DESC"
+
+
+ has_many :student_user_groups
+ has_many :student_group, :through => :student_user_groups
+ has_many :topics, :through => :student_group
+ belongs_to :sheet
+
+ before_create { generate_token(:auth_token) }
+
+ before_validation do
+
+ if self.lock_changed? and self.lock
+ self.locked_at = Time.now
+ end
+
+ end
+
+ def generate_token(column)
+ begin
+ self[column] = SecureRandom.urlsafe_base64
+ end while StudentUser.exists?(column => self[column])
+ end
+
+
+end
diff --git a/app/models/student_user_group.rb b/app/models/student_user_group.rb
new file mode 100644
index 0000000..c252994
--- /dev/null
+++ b/app/models/student_user_group.rb
@@ -0,0 +1,4 @@
+class StudentUserGroup < ActiveRecord::Base
+ belongs_to :student_user
+ belongs_to :student_group
+end
diff --git a/app/models/topic.rb b/app/models/topic.rb
new file mode 100644
index 0000000..7d93ebe
--- /dev/null
+++ b/app/models/topic.rb
@@ -0,0 +1,25 @@
+# -*- encoding : utf-8 -*-
+class Topic < ActiveRecord::Base
+ belongs_to :admin
+ #attr_accessible :description, :title
+ validates :title, :presence => true
+ has_many :notes
+
+ has_many :topic_student_groups
+ has_many :student_groups, :through => :topic_student_groups
+
+ has_one :block, :as => :blockable
+
+ def alloweds_types
+
+ self.block.allow_types :all
+
+
+ end
+ before_create do
+ self.block = Block.new
+ end
+
+
+
+end
diff --git a/app/models/topic_student_group.rb b/app/models/topic_student_group.rb
new file mode 100644
index 0000000..b71a1b4
--- /dev/null
+++ b/app/models/topic_student_group.rb
@@ -0,0 +1,4 @@
+class TopicStudentGroup < ActiveRecord::Base
+ belongs_to :topic
+ belongs_to :student_group
+end
diff --git a/app/uploaders/avatar_uploader.rb b/app/uploaders/avatar_uploader.rb
new file mode 100644
index 0000000..e6b2a0a
--- /dev/null
+++ b/app/uploaders/avatar_uploader.rb
@@ -0,0 +1,61 @@
+# -*- encoding : utf-8 -*-
+
+class AvatarUploader < CarrierWave::Uploader::Base
+
+ # Include RMagick or ImageScience support:
+ include CarrierWave::RMagick
+ # include CarrierWave::ImageScience
+
+ # Choose what kind of storage to use for this uploader:
+ storage :file
+ # storage :s3
+
+ # Override the directory where uploaded files will be stored.
+ # This is a sensible default for uploaders that are meant to be mounted:
+ def store_dir
+ "public_medias/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
+ end
+
+ # Provide a default URL as a default if there hasn't been a file uploaded:
+ # def default_url
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
+ # end
+
+ # Process files as they are uploaded:
+ process :resize_to_limit => [1200, 1200]
+ #
+ # def scale(width, height)
+ # # do something
+ # end
+
+
+
+
+
+
+ # Create different versions of your uploaded files:
+ version :large do
+ process :resize_to_limit => [800, 800]
+
+ end
+
+ version :square do
+ process :resize_to_fill => [300, 300]
+ end
+
+
+
+ # Add a white list of extensions which are allowed to be uploaded.
+ # For images you might use something like this:
+ def extension_white_list
+ %w(jpg jpeg gif png)
+ end
+
+ # Override the filename of the uploaded files:
+ def filename
+ File.basename(original_filename, File.extname(original_filename)).to_s.to_slug + File.extname(original_filename).to_s if original_filename
+
+
+ end
+
+end
diff --git a/app/views/admin/note_files/_form.html.haml b/app/views/admin/note_files/_form.html.haml
new file mode 100644
index 0000000..2c6d030
--- /dev/null
+++ b/app/views/admin/note_files/_form.html.haml
@@ -0,0 +1,19 @@
+%form.fileupload{:action => admin_note_files_path(:note_id => note.id), :enctype => "multipart/form-data", :method => "POST"}
+
+ .upload
+ %button.add_files.btn ajouter des fichiers
+
+ %input{:multiple => "", :name => "files[]", :type => "file", :style => "float:right;display:none;"}
+
+
+ .progress
+ .bar{:style => "height:1em;"}
+
+
+.note_file_queue#note_file_queue
+ %table#files
+
+
+%script
+
+ ="init_note_upload_fields("+note.id.to_s+");"
diff --git a/app/views/admin/note_files/_note_file.html.haml b/app/views/admin/note_files/_note_file.html.haml
new file mode 100644
index 0000000..004c24d
--- /dev/null
+++ b/app/views/admin/note_files/_note_file.html.haml
@@ -0,0 +1,9 @@
+.note_file#note_file{:id => note_file.id}
+ -ext = File.extname(note_file.file.path)[1..-1]
+ %div{:style => "display:inline-block;text-align:center;width:30px;"}=image_tag "admin/file_types/"+ext+".png"
+ =l note_file.created_at, :format => :short
+ =note_file.name
+ =link_to "supprimer", admin_note_file_path(note_file), :remote => true, :method => :delete, :confirm => "Voulez-vous vraiment supprimer ce fichier ?"
+ =link_to "voir", admin_note_file_path(note_file), :target => "_blank"
+ =link_to "télécharger", admin_note_file_path(note_file, :download => true)
+
\ No newline at end of file
diff --git a/app/views/admin/note_files/_show.html.haml b/app/views/admin/note_files/_show.html.haml
new file mode 100644
index 0000000..04dbe7a
--- /dev/null
+++ b/app/views/admin/note_files/_show.html.haml
@@ -0,0 +1,4 @@
+%a{:href => "#", :onclick => "$(this).closest('#file_prev').remove();return false;"} retour
+
+%iframe{:src => admin_note_file_path(@note_file, :inline => true, :force => true)}
+
diff --git a/app/views/admin/note_files/create.js.erb b/app/views/admin/note_files/create.js.erb
new file mode 100644
index 0000000..8b60150
--- /dev/null
+++ b/app/views/admin/note_files/create.js.erb
@@ -0,0 +1,2 @@
+
+$('#note_files_<%= @note_file.note.id %>').html('<%= escape_javascript(render(@note_file.note.note_files))%>');
diff --git a/app/views/admin/note_files/destroy.js.erb b/app/views/admin/note_files/destroy.js.erb
new file mode 100644
index 0000000..3453f72
--- /dev/null
+++ b/app/views/admin/note_files/destroy.js.erb
@@ -0,0 +1 @@
+$('#note_file_<%= @note_file.id %>').remove();
\ No newline at end of file
diff --git a/app/views/admin/note_files/show.js.erb b/app/views/admin/note_files/show.js.erb
new file mode 100644
index 0000000..d729a02
--- /dev/null
+++ b/app/views/admin/note_files/show.js.erb
@@ -0,0 +1,4 @@
+$('body').append('');
+$('#file_prev').html('<%= escape_javascript(render(:partial => "show"))%>');
+$('#file_prev').css('right',"1%");
+$('#file_prev').css("-webkit-transition-duration", "0.8s");
\ No newline at end of file
diff --git a/app/views/admin/notes/_form.html.haml b/app/views/admin/notes/_form.html.haml
new file mode 100644
index 0000000..fe6cd81
--- /dev/null
+++ b/app/views/admin/notes/_form.html.haml
@@ -0,0 +1,8 @@
+#note_form
+ %p ```
+ = form_for [:admin, @note], :remote => true do |f|
+
+ =f.hidden_field :topic_id
+ =f.text_area :message, :class => "markdown"
+
+ = f.submit 'Ajouter !'
diff --git a/app/views/admin/notes/_note.haml b/app/views/admin/notes/_note.haml
new file mode 100644
index 0000000..b3e9a81
--- /dev/null
+++ b/app/views/admin/notes/_note.haml
@@ -0,0 +1,25 @@
+.note#note{:id => note.id}
+
+
+ .left
+
+ .user
+ =image_tag (note.admin.avatar? ? note.admin.avatar.square.url : ""), :class => "avatar"
+
+ =note.admin.username
+ .date=l note.created_at, :format => :short
+ .right
+ .links
+ =link_to "modifier", edit_admin_note_path(note), :remote => true
+ =link_to "suprimer", admin_note_path(note), :remote => true, :method => :delete, :confirm => "Voulez-vous vraiment supprimer cette note ?"
+ =raw note.message
+
+ .bottom
+ =render :partial => "admin/note_files/form", :locals => {:note => note}
+ #note_files.note_files{:id => note.id}=render note.note_files
+
+ :javascript
+
+ $(".note img").each(function(){
+ $(this).closest("p").addClass("large");
+ });
\ No newline at end of file
diff --git a/app/views/admin/notes/create.js.erb b/app/views/admin/notes/create.js.erb
new file mode 100644
index 0000000..e6d26e3
--- /dev/null
+++ b/app/views/admin/notes/create.js.erb
@@ -0,0 +1,2 @@
+$('#notes').html('<%= escape_javascript(render(@note.topic.notes)) %>');
+$("#note_form_place").html("");
\ No newline at end of file
diff --git a/app/views/admin/notes/destroy.js.erb b/app/views/admin/notes/destroy.js.erb
new file mode 100644
index 0000000..e343528
--- /dev/null
+++ b/app/views/admin/notes/destroy.js.erb
@@ -0,0 +1 @@
+$('#note_<%= @note.id %>').remove();
\ No newline at end of file
diff --git a/app/views/admin/notes/edit.js.erb b/app/views/admin/notes/edit.js.erb
new file mode 100644
index 0000000..59ad679
--- /dev/null
+++ b/app/views/admin/notes/edit.js.erb
@@ -0,0 +1 @@
+$("#note_<%=@note.id %>").html('<%= escape_javascript(render :partial => "form") %>');
\ No newline at end of file
diff --git a/app/views/admin/notes/new.js.erb b/app/views/admin/notes/new.js.erb
new file mode 100644
index 0000000..37117c9
--- /dev/null
+++ b/app/views/admin/notes/new.js.erb
@@ -0,0 +1 @@
+$("#note_form_place").html("<%= escape_javascript(render(:partial => "form"))%>");
\ No newline at end of file
diff --git a/app/views/admin/notes/update.js.erb b/app/views/admin/notes/update.js.erb
new file mode 100644
index 0000000..b7ed6e2
--- /dev/null
+++ b/app/views/admin/notes/update.js.erb
@@ -0,0 +1 @@
+$('#note_<%= @note.id %>').replaceWith('<%= escape_javascript(render(@note))%>');
\ No newline at end of file
diff --git a/app/views/admin/student_groups/_form.haml b/app/views/admin/student_groups/_form.haml
new file mode 100644
index 0000000..5318f66
--- /dev/null
+++ b/app/views/admin/student_groups/_form.haml
@@ -0,0 +1,7 @@
+= semantic_form_for [:admin, @student_group] do |f|
+ =f.input :name, :label => "Nom du groupe"
+
+ %br
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
+
\ No newline at end of file
diff --git a/app/views/admin/student_groups/_student_group.html.haml b/app/views/admin/student_groups/_student_group.html.haml
new file mode 100644
index 0000000..ecdb738
--- /dev/null
+++ b/app/views/admin/student_groups/_student_group.html.haml
@@ -0,0 +1,13 @@
+%tr.vertical_center.student_group#student_group{:id => student_group.id}
+
+ %td=student_group.name
+
+ %td.actions
+ = link_to i(:"trash-o"), [:admin, student_group], :confirm => 'Voulez-vous vraiment supprimer cet utilisateur ?', :method => :delete, :remote => true
+
+ = link_to i(:pencil), edit_admin_student_group_path(student_group)
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/student_groups/create.js.erb b/app/views/admin/student_groups/create.js.erb
new file mode 100644
index 0000000..5637ed8
--- /dev/null
+++ b/app/views/admin/student_groups/create.js.erb
@@ -0,0 +1,2 @@
+$('#student_group_rows').html("<%= escape_javascript(render(@student_groups))%>");
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/admin/student_groups/destroy.js.erb b/app/views/admin/student_groups/destroy.js.erb
new file mode 100644
index 0000000..9c686de
--- /dev/null
+++ b/app/views/admin/student_groups/destroy.js.erb
@@ -0,0 +1 @@
+$('#student_group_row_<%= @student_group.id %>').remove();
\ No newline at end of file
diff --git a/app/views/admin/student_groups/edit.js.erb b/app/views/admin/student_groups/edit.js.erb
new file mode 100644
index 0000000..6c8f015
--- /dev/null
+++ b/app/views/admin/student_groups/edit.js.erb
@@ -0,0 +1 @@
+show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/student_groups/index.html.haml b/app/views/admin/student_groups/index.html.haml
new file mode 100644
index 0000000..03d6bdb
--- /dev/null
+++ b/app/views/admin/student_groups/index.html.haml
@@ -0,0 +1,38 @@
+= link_to 'Ajouter un groupe', new_admin_student_group_path, :class => "btn btn-primary", :style => "float:right;", :remote => true
+
+
+%h1 Liste des étudiants
+
+
+%table.table.table-hover
+ %thead#Admin_rows_header.rows_header
+
+ %tr
+
+
+ %td
+ Nom
+
+
+ %td{:style => "width:100px"}
+
+
+
+
+
+ %tbody#student_group_rows.rows
+
+ =render @student_groups
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/admin/student_groups/index.js.erb b/app/views/admin/student_groups/index.js.erb
new file mode 100644
index 0000000..6a4e08d
--- /dev/null
+++ b/app/views/admin/student_groups/index.js.erb
@@ -0,0 +1,2 @@
+
+$('#Admin_index_block').replaceWith("<%= escape_javascript(render(:partial => "index_block")) %>");
\ No newline at end of file
diff --git a/app/views/admin/student_groups/new.js.erb b/app/views/admin/student_groups/new.js.erb
new file mode 100644
index 0000000..6c8f015
--- /dev/null
+++ b/app/views/admin/student_groups/new.js.erb
@@ -0,0 +1 @@
+show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/student_groups/update.js.erb b/app/views/admin/student_groups/update.js.erb
new file mode 100644
index 0000000..8bf1c90
--- /dev/null
+++ b/app/views/admin/student_groups/update.js.erb
@@ -0,0 +1,3 @@
+$('#student_group_row_<%= @student_group.id %>').replaceWith("<%= escape_javascript(render(@student_group))%>");
+
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/admin/student_users/_form.haml b/app/views/admin/student_users/_form.haml
new file mode 100644
index 0000000..f961e80
--- /dev/null
+++ b/app/views/admin/student_users/_form.haml
@@ -0,0 +1,72 @@
+= semantic_form_for [:admin, @student_user] do |f|
+ %hr
+ .row
+ .col-md-4
+
+ =f.input :lock, :label => "Verouillé"
+ =l f.object.locked_at if f.object.lock
+ .col-md-4
+ =f.input :student_group, :as => :check_boxes, :collection => StudentGroup.all, :label => "Groupe d'étudiant"
+ %hr
+
+ .row
+ .col-md-4
+ = f.input :name, :label => "Nom"
+ .col-md-4
+ = f.input :firstname, :label => "Prénom"
+ .col-md-4
+ =image_tag(f.object.avatar.square.url, :style => "height:4em;float:left;margin-right:10px;border-radius:50%;") if f.object.avatar
+ = f.input :avatar, :label => "Image de profil"
+
+ .row
+ .col-md-4
+ = f.input :email, :label => "Email"
+ .col-md-4
+ = f.input :show_email, :label => "Permettre aux étudiants de voir mon mail ?" if f.object.id
+ .row
+ .col-md-4
+ = f.input :password, :label => "Mot de passe"
+ .col-md-4
+ = f.input :password_confirmation, :label => "Confirmation"
+ .col-md-4
+
+
+
+ .row
+ .col-md-4
+ = f.input :tel, :label => "Téléphone"
+ .col-md-4
+ = f.input :show_tel, :label => "Permettre aux étudiants de voir mon numéro ?" if f.object.id
+
+ .row
+ .col-md-4
+ = f.input :address, :label => "Adresse"
+ .col-md-4
+ = f.input :address2, :label => "Adresse (suite)"
+ .col-md-4
+ .row
+ .col-md-4
+ = f.input :cp, :label => "Code postal"
+ .col-md-4
+ = f.input :city, :label => "Ville"
+ .col-md-4
+ = f.input :country, :label => "Pays", :as => :string
+
+
+
+
+ =f.inputs do
+
+ = f.input :bio, :label => "Présentation"
+
+
+
+
+
+
+
+
+ %br
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
+
\ No newline at end of file
diff --git a/app/views/admin/student_users/_student_user.html.haml b/app/views/admin/student_users/_student_user.html.haml
new file mode 100644
index 0000000..3804dd8
--- /dev/null
+++ b/app/views/admin/student_users/_student_user.html.haml
@@ -0,0 +1,28 @@
+%tr.vertical_center.student_user#student_user{:id => student_user.id}
+
+ %td=image_tag (student_user.avatar? ? student_user.avatar.square.url : ""), :class => "avatar", :style => "width:50px; border-radius:50%;"
+
+ %td=link_to student_user.firstname.to_s+" "+student_user.name.to_s, student_student_user_path(student_user)
+
+ %td
+ =student_user.cp
+ =student_user.city
+ -if student_user.country?
+ ="-"
+ =student_user.country
+
+ %td
+ =student_user.email
+ %td
+ =student_user.tel
+ %td
+ ="Verouillé" if student_user.lock
+ %td.actions
+ = link_to i(:"trash-o"), [:admin, student_user], :confirm => 'Voulez-vous vraiment supprimer cet utilisateur ?', :method => :delete, :remote => true
+
+ = link_to i(:pencil), edit_admin_student_user_path(student_user)
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/student_users/create.js.erb b/app/views/admin/student_users/create.js.erb
new file mode 100644
index 0000000..4bc6130
--- /dev/null
+++ b/app/views/admin/student_users/create.js.erb
@@ -0,0 +1,2 @@
+$('#admin_rows').html("<%= escape_javascript(render(@admins))%>");
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/admin/student_users/destroy.js.erb b/app/views/admin/student_users/destroy.js.erb
new file mode 100644
index 0000000..f6f6315
--- /dev/null
+++ b/app/views/admin/student_users/destroy.js.erb
@@ -0,0 +1 @@
+$('#admin_row_<%= @admin.id %>').remove();
\ No newline at end of file
diff --git a/app/views/admin/student_users/edit.haml b/app/views/admin/student_users/edit.haml
new file mode 100644
index 0000000..015bb4e
--- /dev/null
+++ b/app/views/admin/student_users/edit.haml
@@ -0,0 +1,4 @@
+.container
+ %h1 Modifier une fiche étudiant
+
+ =render :partial => "form"
\ No newline at end of file
diff --git a/app/views/admin/student_users/edit.js.erb b/app/views/admin/student_users/edit.js.erb
new file mode 100644
index 0000000..6c8f015
--- /dev/null
+++ b/app/views/admin/student_users/edit.js.erb
@@ -0,0 +1 @@
+show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/student_users/index.html.haml b/app/views/admin/student_users/index.html.haml
new file mode 100644
index 0000000..01fc46e
--- /dev/null
+++ b/app/views/admin/student_users/index.html.haml
@@ -0,0 +1,45 @@
+= link_to 'Ajouter un utilisateur', new_admin_student_user_path, :class => "btn btn-primary", :style => "float:right;"
+
+
+%h1 Liste des étudiants
+
+
+%table.table.table-hover
+ %thead#Admin_rows_header.rows_header
+
+ %tr
+ %td
+
+ %td
+ Nom
+ %td
+ Adresse
+ %td
+ Email
+ %td
+ Téléphone
+
+
+
+ %td{:style => "width:100px"}
+
+
+
+
+
+ %tbody#admin_rows.rows
+
+ =render @student_users
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/admin/student_users/index.js.erb b/app/views/admin/student_users/index.js.erb
new file mode 100644
index 0000000..6a4e08d
--- /dev/null
+++ b/app/views/admin/student_users/index.js.erb
@@ -0,0 +1,2 @@
+
+$('#Admin_index_block').replaceWith("<%= escape_javascript(render(:partial => "index_block")) %>");
\ No newline at end of file
diff --git a/app/views/admin/student_users/new.haml b/app/views/admin/student_users/new.haml
new file mode 100644
index 0000000..2b6b07c
--- /dev/null
+++ b/app/views/admin/student_users/new.haml
@@ -0,0 +1,4 @@
+.container
+ %h1 Ajouter une fiche étudiant
+
+ =render :partial => "form"
\ No newline at end of file
diff --git a/app/views/admin/student_users/new.js.erb b/app/views/admin/student_users/new.js.erb
new file mode 100644
index 0000000..6c8f015
--- /dev/null
+++ b/app/views/admin/student_users/new.js.erb
@@ -0,0 +1 @@
+show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/student_users/update.js.erb b/app/views/admin/student_users/update.js.erb
new file mode 100644
index 0000000..3c75f21
--- /dev/null
+++ b/app/views/admin/student_users/update.js.erb
@@ -0,0 +1,3 @@
+$('#admin_row_<%= @admin.id %>').replaceWith("<%= escape_javascript(render(@admin))%>");
+
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/admin/testimonies/_testimony.html.haml b/app/views/admin/testimonies/_testimony.html.haml
index 2aeadf3..b53f242 100644
--- a/app/views/admin/testimonies/_testimony.html.haml
+++ b/app/views/admin/testimonies/_testimony.html.haml
@@ -2,8 +2,8 @@
%td=testimony.author
%td=testimony.quote
- %td{:style => "width:70px;"}
- = link_to i(:trash), [:admin, testimony], :confirm => 'Voulez-vous vraiment supprimer cette testimony ?', :method => :delete, :remote => true
+ %td{:style => "width:100px;"}
+ = link_to i(:"trash-o"), [:admin, testimony], :confirm => 'Voulez-vous vraiment supprimer cette testimony ?', :method => :delete, :remote => true
= link_to i(:pencil), edit_admin_testimony_path(testimony)
diff --git a/app/views/admin/testimonies/edit.html.haml b/app/views/admin/testimonies/edit.html.haml
index 2a4544b..a9d8bc1 100644
--- a/app/views/admin/testimonies/edit.html.haml
+++ b/app/views/admin/testimonies/edit.html.haml
@@ -1,45 +1,73 @@
+#toolbar-text
-
-
-#article_block_edit
-
+#menu_item_block_edit{:style => "margin-right:330px;margin-top:45px;"}
+
=render :partial => "admin/blocks/block", :locals => {:block => @testimony.block, :sortable => true}
-
+
#menu_item_inspector_container
- .accordion#menu_item_informations
-
- .accordion-group
- .inspector_handle
- .accordion-heading.navbar-inner.navbar-inverse
- %a.accordion-toggle{:href => "#collapseOne",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
- Infos sur le témoignage
+
+
+
+
+
+
+
+ .accordion#menu_item_informations.panel-group
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapseOne",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ Infos sur le témoignage
- #collapseOne.accordion-body.collapse
- .accordion-inner
+ #collapseOne.panel-collapse.collapse
+ .panel-body
=link_to "modifier", edit_admin_testimony_path(@testimony), :remote => true,:class => "btn"
- =render :partial => "show"
+ =render :partial => "show"
-
- .accordion-heading.navbar-inner.navbar-inverse
- %a.accordion-toggle{:href => "#collapse2",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
- éléments
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapse2",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ éléments
- #collapse2.accordion-body.collapse.in
- .accordion-inner
+ #collapse2.panel-collapse.collapse.in
+ .panel-body
.block_portlets_sortable#content_types
-@testimony.alloweds_types.each do |slug, name|
- .portlet{:id => slug, :data_type => slug}
- =image_tag("admin/content_type/type_"+slug.to_s+".png", :alt => name, :class => "handle")
+ .content_type{:id => slug, :"data-type" => slug}
+ =image_tag("admin/content_type/type_"+slug.to_s+".png", :alt => name, :title => name, :class => "handle")
+
+
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapse3",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ Modifier l'élément
+
+
+ #collapse3.panel-collapse.collapse
+ .panel-body
+
+ #element_form
+
+ %div
+ %a.btn.btn-default.portlet_handle{:href => "#", :data => {:portlet_id => nil}}
+ =ic :arrows
+ déplacer
+ =link_to ic(:"trash-o")+" Supprimer", "#", :method => :delete, :data => { :confirm => "Etes-vous sûr ?"}, :remote => true, :class => "btn btn-danger trash"
+
-
+
+
+
diff --git a/app/views/admin/testimonies/index.html.haml b/app/views/admin/testimonies/index.html.haml
index 92e4b91..c4374b9 100644
--- a/app/views/admin/testimonies/index.html.haml
+++ b/app/views/admin/testimonies/index.html.haml
@@ -1,6 +1,6 @@
+%h1 Témoignages
-
-= link_to "Ajouter un témoignage", new_admin_testimony_path(), :class => "btn", :remote => true
+.right= link_to "Ajouter un témoignage", new_admin_testimony_path(), :class => "btn btn-primary", :remote => true
%table.table.table-striped#testimonies
diff --git a/app/views/admin/topics/_form.html.haml b/app/views/admin/topics/_form.html.haml
new file mode 100644
index 0000000..5786fb0
--- /dev/null
+++ b/app/views/admin/topics/_form.html.haml
@@ -0,0 +1,7 @@
+= semantic_form_for [:admin, @topic], :remote => true do |f|
+ =f.input :title, :label => "Titre"
+
+ =f.input :student_groups, :as => :check_boxes, :collection => StudentGroup.all, :label => "Groupe d'étudiant"
+
+
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
diff --git a/app/views/admin/topics/_show.html.haml b/app/views/admin/topics/_show.html.haml
new file mode 100644
index 0000000..deb16af
--- /dev/null
+++ b/app/views/admin/topics/_show.html.haml
@@ -0,0 +1,15 @@
+.topic_links
+ = link_to 'Modifier', edit_admin_topic_path(@topic), :remote => true
+ = link_to 'Suprimer', admin_topic_path(@topic), :remote => true, :method => :delete, :confirm => "Voulez-vous vraiment supprimer ce topic, et tout son contenu ?"
+
+
+
+%h1.topic_title= @topic.title
+%p
+ Lancé par
+ = @topic.admin.username
+
+#notes=render @topic.notes
+=link_to "Ajouter une note", new_admin_note_path(:topic_id => @topic), :remote => true, :id => "add_note"
+
+#note_form_place
diff --git a/app/views/admin/topics/_topic.haml b/app/views/admin/topics/_topic.haml
new file mode 100644
index 0000000..d9cc091
--- /dev/null
+++ b/app/views/admin/topics/_topic.haml
@@ -0,0 +1,12 @@
+%tr.vertical_center.student_user#student_user{:id => topic.id}
+
+ %td=topic.title
+ %td.actions
+ = link_to i(:"trash-o"), [:admin, topic], :confirm => 'Voulez-vous vraiment supprimer cette ressource ?', :method => :delete, :remote => true
+
+ = link_to i(:pencil), edit_admin_topic_path(topic)
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/topics/create.js.erb b/app/views/admin/topics/create.js.erb
new file mode 100644
index 0000000..361dcb5
--- /dev/null
+++ b/app/views/admin/topics/create.js.erb
@@ -0,0 +1,2 @@
+$('#topic_rows').html("<%= escape_javascript(render(@topics)) %>");
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/admin/topics/destroy.js.erb b/app/views/admin/topics/destroy.js.erb
new file mode 100644
index 0000000..b08ddbb
--- /dev/null
+++ b/app/views/admin/topics/destroy.js.erb
@@ -0,0 +1,2 @@
+$('#topic_line_<%= @topic.id %>').remove();
+$('#topic_show').html("");
\ No newline at end of file
diff --git a/app/views/admin/topics/edit.haml b/app/views/admin/topics/edit.haml
new file mode 100644
index 0000000..84734ce
--- /dev/null
+++ b/app/views/admin/topics/edit.haml
@@ -0,0 +1,72 @@
+#toolbar-text
+
+#menu_item_block_edit{:style => "margin-right:330px;margin-top:45px;"}
+
+ =render :partial => "admin/blocks/block", :locals => {:block => @topic.block, :sortable => true}
+
+
+
+#menu_item_inspector_container
+
+
+
+
+
+
+
+ .accordion#menu_item_informations.panel-group
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapseOne",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ Infos sur la ressource
+
+
+ #collapseOne.panel-collapse.collapse
+ .panel-body
+ =render :partial => "form"
+
+
+
+
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapse2",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ éléments
+
+
+ #collapse2.panel-collapse.collapse.in
+ .panel-body
+ .block_portlets_sortable#content_types
+ -@topic.block.alloweds_types.each do |slug, name|
+
+ .content_type{:id => slug, :"data-type" => slug}
+ =image_tag("admin/content_type/type_"+slug.to_s+".png", :alt => name, :title => name, :class => "handle")
+
+
+ .panel.panel-default
+ .panel-heading
+ %h4.panel-title
+ %a.panel-toggle{:href => "#collapse3",:data => {:toggle => "collapse", :parent => "#menu_item_informations"}}
+ Modifier l'élément
+
+
+ #collapse3.panel-collapse.collapse
+ .panel-body
+
+ #element_form
+
+ %div
+ %a.btn.btn-default.portlet_handle{:href => "#", :data => {:portlet_id => nil}}
+ =ic :arrows
+ déplacer
+ =link_to ic(:"trash-o")+" Supprimer", "#", :method => :delete, :data => { :confirm => "Etes-vous sûr ?"}, :remote => true, :class => "btn btn-danger trash"
+
+
+
+
+
+
+
+
diff --git a/app/views/admin/topics/edit.js.erb b/app/views/admin/topics/edit.js.erb
new file mode 100644
index 0000000..b66f38e
--- /dev/null
+++ b/app/views/admin/topics/edit.js.erb
@@ -0,0 +1 @@
+//show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/topics/index.html.haml b/app/views/admin/topics/index.html.haml
new file mode 100644
index 0000000..76b70f4
--- /dev/null
+++ b/app/views/admin/topics/index.html.haml
@@ -0,0 +1,34 @@
+= link_to 'Ajouter une ressource', new_admin_topic_path, :class => "btn btn-primary", :style => "float:right;", :remote => true
+
+
+%h1 Liste des ressources
+
+
+%table.table.table-hover
+ %thead#Admin_rows_header.rows_header
+
+ %tr
+
+
+ %td
+ Nom
+
+
+
+ %td{:style => "width:100px"}
+
+
+
+
+
+ %tbody#topic_rows.rows
+
+ =render @topics
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/topics/new.js.erb b/app/views/admin/topics/new.js.erb
new file mode 100644
index 0000000..6c8f015
--- /dev/null
+++ b/app/views/admin/topics/new.js.erb
@@ -0,0 +1 @@
+show_pane_hover("<%= escape_javascript(render(:partial => "form"))%>",700,900);
\ No newline at end of file
diff --git a/app/views/admin/topics/show.js.erb b/app/views/admin/topics/show.js.erb
new file mode 100644
index 0000000..fd7663e
--- /dev/null
+++ b/app/views/admin/topics/show.js.erb
@@ -0,0 +1,5 @@
+$('.topic_line').removeClass("active");
+
+$('#topic_line_<%= @topic.id %>').addClass("active");
+
+$('#topic_show').html("<%= escape_javascript(render(:partial => "show")) %>");
diff --git a/app/views/admin/topics/update.js.erb b/app/views/admin/topics/update.js.erb
new file mode 100644
index 0000000..933acd5
--- /dev/null
+++ b/app/views/admin/topics/update.js.erb
@@ -0,0 +1,7 @@
+$('#topics').html("<%= escape_javascript(render(@topics)) %>");
+
+
+$('.topic_title').html("<%= escape_javascript(raw(@topic.title)) %>");
+
+
+close_pane_hover();
\ No newline at end of file
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 6b49f2b..5384caa 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -19,7 +19,7 @@
%body.admin
- %nav.navbar.navbar-default.navbar-inverse{role: "navigation"}
+ %nav#admin_navbar.navbar.navbar-default.navbar-inverse{role: "navigation"}
.container-fluid
/ Brand and toggle get grouped for better mobile display
.navbar-header
@@ -41,8 +41,15 @@
%li= link_to "témoignages", admin_testimonies_path
-
-
+
+ %li.dropdown
+ %a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
+ Etudiants
+ %ul.dropdown-menu
+ %li= link_to "Etudiants", admin_student_users_path
+ %li= link_to "Ressources", admin_topics_path
+ %li.divider
+ %li= link_to "Groupe d'étudiants", admin_student_groups_path
%li= link_to "Images", admin_image_files_path
%li= link_to "Fichiers", admin_data_files_path
diff --git a/app/views/layouts/connexion.html.haml b/app/views/layouts/connexion.html.haml
new file mode 100644
index 0000000..84862de
--- /dev/null
+++ b/app/views/layouts/connexion.html.haml
@@ -0,0 +1,29 @@
+!!!
+%html{:lang => "fr"}
+ %head
+ %meta{:charset => "utf-8"}/
+ %meta{:content => "IE=Edge,chrome=1", "http-equiv" => "X-UA-Compatible"}/
+ %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/
+ %title Connection
+ = csrf_meta_tags
+ = stylesheet_link_tag :admin_auth
+ = javascript_include_tag :connexion
+
+
+ %body
+ -if @student
+ :coffeescript
+ $ ->
+ $.backstretch("/login_background5.jpg")
+
+ -else
+ :coffeescript
+ $ ->
+ $.backstretch("/login_background.jpg")
+
+ .form-signin= yield
+ #flashs= bootstrap_flash
+
+
+
+
\ No newline at end of file
diff --git a/app/views/layouts/mail.html.haml b/app/views/layouts/mail.html.haml
new file mode 100755
index 0000000..b66d652
--- /dev/null
+++ b/app/views/layouts/mail.html.haml
@@ -0,0 +1,30 @@
+!!!
+%html
+ %head
+ %meta{ :"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8" }
+
+ :css
+ a {
+ color: #0088cc;
+ text-decoration: none;
+ }
+
+ a:hover, a:focus {
+ color: #005580;
+ text-decoration: underline;
+ }
+
+ *{
+
+ line-height:1.3em;
+ }
+
+
+ %body{:style => "font-family: Helvetica,Arial;padding:0px;margin:0px;font-size:15px;"}
+
+ = yield
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/layouts/student.haml b/app/views/layouts/student.haml
new file mode 100644
index 0000000..379c5c7
--- /dev/null
+++ b/app/views/layouts/student.haml
@@ -0,0 +1,100 @@
+!!!
+%html{:lang => "fr"}
+ %head
+ %meta{:charset => "utf-8"}/
+ %meta{:content => "IE=Edge,chrome=1", "http-equiv" => "X-UA-Compatible"}/
+ %meta{:content => "width=device-width, initial-scale=1.0", :name => "viewport"}/
+ %title= @title || "Espace étudiants"
+
+ =javascript_include_tag "student"
+ =stylesheet_link_tag "student"
+ = csrf_meta_tags
+ = stylesheet_link_tag '/fonts/Stylograph/stylesheet.css'
+
+
+ =javascript_include_tag "http://maps.google.com/maps/api/js?sensor=false®ion=FR"
+
+
+
+
+
+
+%body.admin
+
+ -if current_suser
+ %nav#menu_top.navbar.navbar-default.navbar-inverse{role: "navigation"}
+ .container-fluid
+ / Brand and toggle get grouped for better mobile display
+ .navbar-header
+ %button.navbar-toggle{"data-target" => "#bs-example-navbar-collapse-1", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.icon-bar
+ %span.icon-bar
+ %span.icon-bar
+ %a.navbar-brand{href: "/student"}
+ =ic(:"graduation-cap")
+ Espace étudiants
+
+ #bs-example-navbar-collapse-1.collapse.navbar-collapse
+ %ul.nav.navbar-nav
+
+ %li=link_to ic(:"users")+" Annuaire", student_student_users_path
+ %li=link_to ic(:"folder-open")+" Ressources", student_topics_path
+
+
+ %ul.nav.navbar-nav.navbar-right
+ %li.dropdown
+ %a.dropdown-toggle{"data-toggle" => "dropdown", href: "#"}
+ =image_tag (current_suser.avatar? ? current_suser.avatar.square.url : ""), :class => "img img-rounded", :style => "height:15px;"
+ =current_suser.firstname
+ =current_suser.name
+ %b.caret
+ %ul.dropdown-menu
+ %li=link_to ic(:pencil)+" Mon profil", edit_student_student_user_path(current_suser)
+ %li.divider
+ %li=link_to "se déconnecter", logout_student_auths_path
+
+
+
+ #toolbar-text
+
+ #main.container-fluid
+
+ = yield
+
+ -if current_suser and current_suser.sheet and current_suser.sheet.last_year < Date.today.year
+ %div{:style => "background:#e16b13;padding:10px;text-align:center;color:white;"}
+ %a{:href => "http://www.lepicvert.asso.fr/131/lassociation/adherer", :style => "color:white;text-decoration:none;"}
+ Attention : votre adhésion n'a pas encore été renouvelée pour
+ = Date.today.year.to_s+"."
+
+
+
+
+
+
+ .footer
+ .container
+ %p{:style => "float:right;"}
+ -if current_suser and current_suser.sheet
+ Cotisation à jour pour
+ =current_suser.sheet.last_year.to_s+" - "
+ N° d'adhésion :
+ ="#"+current_suser.sheet.sheet_number.to_s
+ =link_to image_tag("/logo-white.png", :style => "height:100px;"), "/student"
+
+
+
+ #flashs= bootstrap_flash
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/portlets.old/render_public/_downloadcontent.html.haml b/app/views/portlets.old/render_public/_downloadcontent.html.haml
index 8165052..4c90d6e 100644
--- a/app/views/portlets.old/render_public/_downloadcontent.html.haml
+++ b/app/views/portlets.old/render_public/_downloadcontent.html.haml
@@ -3,7 +3,7 @@
.portlet.download_content
- =link_to input.title.to_s, input.data_file.file.url
+ =link_to ic(:download)+" "+input.title.to_s, input.data_file.file.url
-else
diff --git a/app/views/portlets/render_public/_downloadcontent.html.haml b/app/views/portlets/render_public/_downloadcontent.html.haml
index 8165052..f86c9f4 100644
--- a/app/views/portlets/render_public/_downloadcontent.html.haml
+++ b/app/views/portlets/render_public/_downloadcontent.html.haml
@@ -3,7 +3,8 @@
.portlet.download_content
- =link_to input.title.to_s, input.data_file.file.url
+ =link_to ic(:"cloud-download")+raw(" ")+input.title.to_s, input.data_file.file.url
+
-else
diff --git a/app/views/student/auths/new.haml b/app/views/student/auths/new.haml
new file mode 100644
index 0000000..cee1b0e
--- /dev/null
+++ b/app/views/student/auths/new.haml
@@ -0,0 +1,22 @@
+
+= form_tag student_auths_path do
+ %p
+ = text_field_tag :email, params[:email], :placeholder => "email", :class => "input-dark"
+ %p
+ = password_field_tag :password,"", :placeholder => "Mot de passe", :class => "input-dark"
+
+
+ =check_box_tag :remember_me, 1,params[:remember_me]
+
+ = label_tag :remember_me, "Rester connecter ?"
+
+ %p
+ = submit_tag "Se connecter", :class => "btn btn-primary"
+
+ %p
+
+ =link_to "Mot de passe perdu ?", new_student_password_reset_path
+ ="-"
+ =link_to "Pas encore inscrit ?", new_student_student_user_path
+
+
diff --git a/app/views/student/forum_categories/_form.haml b/app/views/student/forum_categories/_form.haml
new file mode 100644
index 0000000..21df5c2
--- /dev/null
+++ b/app/views/student/forum_categories/_form.haml
@@ -0,0 +1,11 @@
+= semantic_form_for [:forum, @category] do |f|
+ =f.inputs :name => "Basic" do
+ = f.input :title, :label => "Titre"
+ = f.input :description, :label => "Description"
+ = f.hidden_field :forum_id
+
+
+
+ =f.submit "Sauvegarder", :class => "btn btn-primay"
+
+
\ No newline at end of file
diff --git a/app/views/student/forum_categories/_forum_category.haml b/app/views/student/forum_categories/_forum_category.haml
new file mode 100644
index 0000000..405a707
--- /dev/null
+++ b/app/views/student/forum_categories/_forum_category.haml
@@ -0,0 +1,13 @@
+%tr.category
+
+
+
+ %td
+ =link_to forum_category.title, [:forum, forum_category]
+
+
+ -if moderator?
+ %td
+ =link_to i(:pencil), edit_forum_forum_category_path(forum_category)
+ =link_to i(:"trash-o"), [:forum, forum_category], :confirm => "Supprimer cette catégorie ?", :method => :delete
+
\ No newline at end of file
diff --git a/app/views/student/forum_categories/edit.haml b/app/views/student/forum_categories/edit.haml
new file mode 100644
index 0000000..038bb12
--- /dev/null
+++ b/app/views/student/forum_categories/edit.haml
@@ -0,0 +1 @@
+=render :partial => "form"
\ No newline at end of file
diff --git a/app/views/student/forum_categories/index.haml b/app/views/student/forum_categories/index.haml
new file mode 100644
index 0000000..7c1680b
--- /dev/null
+++ b/app/views/student/forum_categories/index.haml
@@ -0,0 +1,12 @@
+=link_to "nouvel catégorie", new_forum_forum_category_path, :class => "btn btn-primary", :style => "margin:1em 0em;float:right" if moderator?
+
+%h1 Liste des catégories
+
+%table.table.table-hover.table-striped
+ %tr
+
+ %th Nom
+
+ -if moderator?
+ %th Actions
+ =render @categories
\ No newline at end of file
diff --git a/app/views/student/forum_categories/new.haml b/app/views/student/forum_categories/new.haml
new file mode 100644
index 0000000..038bb12
--- /dev/null
+++ b/app/views/student/forum_categories/new.haml
@@ -0,0 +1 @@
+=render :partial => "form"
\ No newline at end of file
diff --git a/app/views/student/forum_messages/_form.haml b/app/views/student/forum_messages/_form.haml
new file mode 100644
index 0000000..5fa74f7
--- /dev/null
+++ b/app/views/student/forum_messages/_form.haml
@@ -0,0 +1,58 @@
+#message_form
+ .form
+
+ %h3 Contenu du message
+
+
+ =f.hidden_field :forum_topic_id
+ =f.hidden_field :forum_user_id
+
+ %br
+ %br
+
+
+ .forum_message
+
+
+ .left
+
+ .user
+ =image_tag((current_fuser.avatar? ? current_fuser.avatar.square.url : ""), :class => "avatar" )
+ %br
+ =current_fuser.firstname+" "+current_fuser.name
+
+ .date=l @message.created_at, :format => :human if @message and @message.created_at
+
+ .right{:style => "padding:0px;"}
+ .content{:style => "border:0px;padding:2% !important;min-height:200px;background:transparent !important;"}
+ =raw f.object.description
+ =f.text_area :description, :id => "redactor_content", :style => "display:none;"
+
+ .fix-submit
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
+
+
+ :javascript
+ $("#message_form").closest("form").submit(function (e){
+
+ $("textarea").val($('#message_form .content').html());
+ $("#toolbar-text").html("");
+
+ });
+
+
+
+ $('#message_form .content').redactor({
+ toolbarExternal: '#toolbar-text',
+ lang: 'fr',
+ buttons : ['undo','redo','|', 'formatting', '|', 'bold', 'italic', 'deleted','underline','|', 'alignleft', 'aligncenter', 'alignright', 'justify', '|', 'unorderedlist', 'orderedlist', '|', 'link', '|', 'backcolor','|', 'horizontalrule']
+
+
+
+ });
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/student/forum_messages/_forum_message.haml b/app/views/student/forum_messages/_forum_message.haml
new file mode 100644
index 0000000..0ce18b3
--- /dev/null
+++ b/app/views/student/forum_messages/_forum_message.haml
@@ -0,0 +1,33 @@
+.forum_message#forum_message{:id => forum_message.id}
+
+
+ .left
+
+ .user
+ -if forum_message.forum_user
+
+ =link_to image_tag((forum_message.forum_user.avatar? ? forum_message.forum_user.avatar.square.url : ""), :class => "avatar" ), [:forum, forum_message.forum_user]
+ %br
+
+ =link_to forum_message.forum_user.firstname+" "+forum_message.forum_user.name, [:forum, forum_message.forum_user]
+ -else
+ utilisateur supprimé
+ .date
+ =l forum_message.created_at, :format => "%d %B %Y"
+ %br
+ =l forum_message.created_at, :format => "%Hh%M"
+
+ .right
+ .links
+ =link_to i(:pencil), edit_forum_forum_message_path(forum_message) if forum_message.forum_user == current_fuser or moderator?
+ =link_to i(:"trash-o"), [:forum, forum_message], :confirm => "Supprimer ce message ?", :method => :delete if moderator?
+
+ .content=markdown forum_message.description
+
+ -if forum_message.updated_at != forum_message.created_at
+ %p.edited.alert
+ Ce message a été modifié
+ =l forum_message.created_at, :format => :human
+ .clear
+
+
\ No newline at end of file
diff --git a/app/views/student/forum_messages/edit.haml b/app/views/student/forum_messages/edit.haml
new file mode 100644
index 0000000..0e463d9
--- /dev/null
+++ b/app/views/student/forum_messages/edit.haml
@@ -0,0 +1,5 @@
+%br
+%br
+= form_for [:forum, @message] do |f|
+ =render :partial => "form", :locals => {:f => f}
+=render :partial => "forum/forum_user_images/images_form"
\ No newline at end of file
diff --git a/app/views/student/forum_messages/new.haml b/app/views/student/forum_messages/new.haml
new file mode 100644
index 0000000..65ad145
--- /dev/null
+++ b/app/views/student/forum_messages/new.haml
@@ -0,0 +1,6 @@
+%br
+%br
+
+= form_for [:forum, @message] do |f|
+ =render :partial => "form", :locals => {:f => f}
+=render :partial => "forum/forum_user_images/images_form"
\ No newline at end of file
diff --git a/app/views/student/forum_topics/_form.haml b/app/views/student/forum_topics/_form.haml
new file mode 100644
index 0000000..dd60de5
--- /dev/null
+++ b/app/views/student/forum_topics/_form.haml
@@ -0,0 +1,20 @@
+%br
+%br
+%h1 Créer un nouveau fil de discussion
+= semantic_form_for [:forum, @topic] do |f|
+ =f.inputs do
+ =f.input :category, :label => "Catégorie", :include_blank => false
+ %p
+ = f.label :title, "Titre : ", :style => "width:8%;display:inline-block;"
+ = f.text_field :title, :style => "width:90%;"
+
+
+
+
+ =f.fields_for :forum_messages do |f|
+ =render :partial => "forum/forum_messages/form", :locals => {:f => f}
+
+
+
+
+
diff --git a/app/views/student/forum_topics/_forum_topic.haml b/app/views/student/forum_topics/_forum_topic.haml
new file mode 100644
index 0000000..4286bb2
--- /dev/null
+++ b/app/views/student/forum_topics/_forum_topic.haml
@@ -0,0 +1,22 @@
+%tr.topic
+ %td=link_to forum_topic.title, [:forum, forum_topic]
+ %td{:style => "width:160px;"}=forum_topic.category.title if forum_topic.category
+ %td{:style => "width:100px;"}=forum_topic.forum_messages.count - 1
+ %td{:style => "width:160px;"}
+ = forum_topic.username
+ %br
+ il y a
+ =distance_of_time_in_words Time.now, forum_topic.created_at
+
+
+ %td{:style => "width:160px;"}
+ -if forum_topic.forum_messages.count > 1
+ =forum_topic.forum_messages.order("created_at ASC").last.username
+ %br
+ il y a
+ =distance_of_time_in_words Time.now, forum_topic.forum_messages.order("created_at ASC").last.created_at
+
+ -if moderator?
+ %td
+ =link_to i(:"trash-o"), [:forum, forum_topic], :confirm => "Supprimer ce topic ?", :method => :delete
+
\ No newline at end of file
diff --git a/app/views/student/forum_topics/edit.haml b/app/views/student/forum_topics/edit.haml
new file mode 100644
index 0000000..038bb12
--- /dev/null
+++ b/app/views/student/forum_topics/edit.haml
@@ -0,0 +1 @@
+=render :partial => "form"
\ No newline at end of file
diff --git a/app/views/student/forum_topics/index.haml b/app/views/student/forum_topics/index.haml
new file mode 100644
index 0000000..c6fe737
--- /dev/null
+++ b/app/views/student/forum_topics/index.haml
@@ -0,0 +1,16 @@
+=link_to "Lancer un fil de discussion", new_forum_forum_topic_path, :class => "btn btn-primary", :style => "margin:1em 0em;float:right"
+
+
+%table.table.table-striped.table-hover
+ %tr.transparent
+ %th Fil de discussion
+ %th{:style => "width:150px;"} Catégorie
+ %th Réponses
+ %th Lancé
+ %th Activité
+ -if moderator?
+ %th{:style => "width:50px;"}
+ =render @forum_topics
+
+
+=link_to "Lancer un fil de discussion", new_forum_forum_topic_path, :class => "btn btn-primary", :style => "margin:1em 0em;float:right"
\ No newline at end of file
diff --git a/app/views/student/forum_topics/new.haml b/app/views/student/forum_topics/new.haml
new file mode 100644
index 0000000..bc17697
--- /dev/null
+++ b/app/views/student/forum_topics/new.haml
@@ -0,0 +1,2 @@
+=render :partial => "form"
+=render :partial => "forum/forum_user_images/images_form"
\ No newline at end of file
diff --git a/app/views/student/forum_topics/show.haml b/app/views/student/forum_topics/show.haml
new file mode 100644
index 0000000..f611150
--- /dev/null
+++ b/app/views/student/forum_topics/show.haml
@@ -0,0 +1,14 @@
+
+=link_to "ajouter un message", new_forum_forum_message_path(:topic_id => @topic.id), :class => "btn btn-primary", :style => "margin:1em 0em;float:right"
+
+%h1= @topic.title
+%br
+%br
+=render @topic.forum_messages.order("created_at ASC")
+
+=link_to "ajouter un message", new_forum_forum_message_path(:topic_id => @topic.id), :class => "btn btn-primary", :style => "margin:1em 0em;float:right"
+
+%br
+%br
+%br
+%br
\ No newline at end of file
diff --git a/app/views/student/forum_user_images/_forum_user_image.haml b/app/views/student/forum_user_images/_forum_user_image.haml
new file mode 100644
index 0000000..bb354b2
--- /dev/null
+++ b/app/views/student/forum_user_images/_forum_user_image.haml
@@ -0,0 +1,6 @@
+-if forum_user_image.image?
+
+ #user_image.user_image_block{:id => forum_user_image.id}
+ =image_tag forum_user_image.image.thumb.url+"?"+forum_user_image.updated_at.to_s, :"data-src-large" =>forum_user_image.image.large.url, :class => "user_image"
+ = link_to i(:"rotate-left", :icon => false), rotate_forum_forum_user_image_path(:id => forum_user_image.id, :manager => params[:manager], :multiple => params[:multiple]), :remote => true
+ = link_to i(:"rotate-right", :icon => false), rotate_forum_forum_user_image_path(:id => forum_user_image.id, :manager => params[:manager], :multiple => params[:multiple], :direction => :right), :remote => true
\ No newline at end of file
diff --git a/app/views/student/forum_user_images/_images_form.haml b/app/views/student/forum_user_images/_images_form.haml
new file mode 100644
index 0000000..9f8c698
--- /dev/null
+++ b/app/views/student/forum_user_images/_images_form.haml
@@ -0,0 +1,32 @@
+.user_images
+ .toggle-button
+ .o=i(:"picture-o", :icon => false)
+ .c=i(:"times", :icon => false)
+ %h3 Mon album photo
+
+
+
+
+
+
+
+ .images=render current_fuser.images
+ %form.fileupload{:action => forum_forum_user_images_path(), :enctype => "multipart/form-data", :method => "POST"}
+
+ .upload
+ .progress
+ .bar{:style => "height:1em;"}
+
+ %button.add_files{:class => "btn"} ajouter des photos
+
+ %input{:multiple => "", :name => "files[]", :type => "file", :style => "float:right;"}
+
+ :javascript
+ init_user_images();
+
+%p{:style => "clear:both;"} Vous pouvez télécharger de nouvelles images pour les ajouter dans votre message en cliquant sur l'onglet avec une image se trouvant en haut à droite qui seront automatiquement redimensionnées par le serveur.
+%p Vous pouvez ensuite ajouter une image dans votre message en cliquant sur celle que vous souhaitez ajouter.
+
+
+
+
\ No newline at end of file
diff --git a/app/views/student/forum_user_images/create.js.erb b/app/views/student/forum_user_images/create.js.erb
new file mode 100644
index 0000000..54e4ead
--- /dev/null
+++ b/app/views/student/forum_user_images/create.js.erb
@@ -0,0 +1,2 @@
+$('.user_images .images').html('<%= escape_javascript(render(current_fuser.images))%>');
+init_user_images();
\ No newline at end of file
diff --git a/app/views/student/forum_user_images/rotate.js.erb b/app/views/student/forum_user_images/rotate.js.erb
new file mode 100644
index 0000000..1f997e1
--- /dev/null
+++ b/app/views/student/forum_user_images/rotate.js.erb
@@ -0,0 +1,2 @@
+
+$('#user_image_<%= @forum_user_image.id %>').replaceWith("<%= escape_javascript(render(@forum_user_image))%>");
\ No newline at end of file
diff --git a/app/views/student/forums/index.haml b/app/views/student/forums/index.haml
new file mode 100644
index 0000000..07c3c6e
--- /dev/null
+++ b/app/views/student/forums/index.haml
@@ -0,0 +1 @@
+=debug @forums
\ No newline at end of file
diff --git a/app/views/student/forums/show.html.haml b/app/views/student/forums/show.html.haml
new file mode 100644
index 0000000..0f96969
--- /dev/null
+++ b/app/views/student/forums/show.html.haml
@@ -0,0 +1,15 @@
+=link_to "ajouter une catégorie", new_forum_forum_category_path(:forum_id => @forum.id), :class => "btn", :style => "margin:1em 0em;float:right" if moderator?
+
+%h1=@forum.title
+.description
+ =markdown @forum.description
+
+
+%table
+ %tr
+ %th Titre
+ %th Topics
+ -if moderator?
+ %th Actions
+
+ =render @forum.forum_categories
diff --git a/app/views/student/note_files/_note_file.html.haml b/app/views/student/note_files/_note_file.html.haml
new file mode 100644
index 0000000..efb3c79
--- /dev/null
+++ b/app/views/student/note_files/_note_file.html.haml
@@ -0,0 +1,8 @@
+.note_file#note_file{:id => note_file.id}
+ -ext = File.extname(note_file.file.path)[1..-1]
+
+ =image_tag "admin/file_types/"+ext+".png"
+ =l note_file.created_at, :format => :short
+
+ =link_to note_file.name, admin_note_file_path(note_file), :target => "_blank"
+
\ No newline at end of file
diff --git a/app/views/student/notes/_note.haml b/app/views/student/notes/_note.haml
new file mode 100644
index 0000000..8aef882
--- /dev/null
+++ b/app/views/student/notes/_note.haml
@@ -0,0 +1,13 @@
+.note#note{:id => note.id}
+ .note_content
+ .date=l note.created_at, :format => :date
+ =raw note.message
+
+ .bottom
+ #note_files.note_files{:id => note.id}=render note.note_files
+
+ :javascript
+
+ $(".note img").each(function(){
+ $(this).closest("p").addClass("large");
+ });
\ No newline at end of file
diff --git a/app/views/student/password_resets/edit.haml b/app/views/student/password_resets/edit.haml
new file mode 100644
index 0000000..7c0ab6e
--- /dev/null
+++ b/app/views/student/password_resets/edit.haml
@@ -0,0 +1,10 @@
+%p Vous pouvez définir votre nouveau mot de passe ci-dessous :
+= semantic_form_for @student_user, :url => student_password_reset_path(params[:id]) do |f|
+
+ %p= f.password_field :password, :placeholder => "Mot de passe", :class => "input-dark"
+ %p= f.password_field :password_confirmation, :placeholder => "Confirmation", :class => "input-dark"
+
+
+ %p
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
\ No newline at end of file
diff --git a/app/views/student/password_resets/new.haml b/app/views/student/password_resets/new.haml
new file mode 100644
index 0000000..a78a240
--- /dev/null
+++ b/app/views/student/password_resets/new.haml
@@ -0,0 +1,13 @@
+
+= form_tag student_password_resets_path do
+ %p
+ = text_field_tag :email, params[:email], :placeholder => "email", :class => "input-dark"
+
+ %p= submit_tag "Recevoir un lien", :class => "btn btn-primary"
+
+ %p
+
+ =link_to "Pas encore inscrit ?", new_student_student_user_path
+ ="-"
+ =link_to "Connexion", new_student_auth_path
+
\ No newline at end of file
diff --git a/app/views/student/student_users/_form.haml b/app/views/student/student_users/_form.haml
new file mode 100644
index 0000000..05e9959
--- /dev/null
+++ b/app/views/student/student_users/_form.haml
@@ -0,0 +1,42 @@
+= semantic_form_for [:student, @user] do |f|
+
+ =render :partial => "form_min", :locals => {:f => f}
+
+ .row
+ .col-md-4
+ = f.input :tel, :label => "Téléphone"
+ .col-md-4
+ = f.input :show_tel, :label => "Permettre aux étudiants de voir mon numéro ?" if f.object.id
+
+ .row
+ .col-md-4
+ = f.input :address, :label => "Adresse"
+ .col-md-4
+ = f.input :address2, :label => "Adresse (suite)"
+ .col-md-4
+ .row
+ .col-md-4
+ = f.input :cp, :label => "Code postal"
+ .col-md-4
+ = f.input :city, :label => "Ville"
+ .col-md-4
+ = f.input :country, :label => "Pays", :as => :string
+
+
+
+
+ =f.inputs do
+
+ = f.input :bio, :label => "Présentation"
+
+
+
+
+
+
+
+
+ %br
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
+
\ No newline at end of file
diff --git a/app/views/student/student_users/_form_min.haml b/app/views/student/student_users/_form_min.haml
new file mode 100644
index 0000000..99b6251
--- /dev/null
+++ b/app/views/student/student_users/_form_min.haml
@@ -0,0 +1,21 @@
+.row
+ .col-md-4
+ = f.input :name, :label => "Nom"
+ .col-md-4
+ = f.input :firstname, :label => "Prénom"
+ .col-md-4
+ =image_tag(f.object.avatar.square.url, :style => "height:4em;float:left;margin-right:10px;border-radius:50%;") if f.object.avatar
+ = f.input :avatar, :label => "Image de profil"
+
+.row
+ .col-md-4
+ = f.input :email, :label => "Email"
+ .col-md-4
+ = f.input :show_email, :label => "Permettre aux étudiants de voir mon mail ?" if f.object.id
+.row
+ .col-md-4
+ = f.input :password, :label => "Mot de passe"
+ .col-md-4
+ = f.input :password_confirmation, :label => "Confirmation"
+ .col-md-4
+
diff --git a/app/views/student/student_users/_student_user.haml b/app/views/student/student_users/_student_user.haml
new file mode 100644
index 0000000..a3e30e9
--- /dev/null
+++ b/app/views/student/student_users/_student_user.haml
@@ -0,0 +1,18 @@
+%tr.vertical_center.student_user#student_user{:id => student_user.id}
+
+ %td=image_tag (student_user.avatar? ? student_user.avatar.square.url : ""), :class => "avatar", :style => "width:50px; border-radius:50%;"
+
+ %td=link_to student_user.firstname.to_s+" "+student_user.name.to_s, student_student_user_path(student_user)
+
+ %td
+ =student_user.cp
+ =student_user.city
+ -if student_user.country?
+ ="-"
+ =student_user.country
+
+ %td
+ =student_user.email if student_user.show_email
+ %td
+ =student_user.tel if student_user.tel and student_user.show_tel
+
\ No newline at end of file
diff --git a/app/views/student/student_users/edit.haml b/app/views/student/student_users/edit.haml
new file mode 100644
index 0000000..7bce962
--- /dev/null
+++ b/app/views/student/student_users/edit.haml
@@ -0,0 +1,3 @@
+%h1 Modifier ma fiche étudiant
+.white_block.pad
+ =render :partial => "form"
\ No newline at end of file
diff --git a/app/views/student/student_users/index.haml b/app/views/student/student_users/index.haml
new file mode 100644
index 0000000..be852d9
--- /dev/null
+++ b/app/views/student/student_users/index.haml
@@ -0,0 +1,14 @@
+
+
+%h1 Annuaire des étudiants de l'école.
+
+%table.table.table-hover.table-striped.student_users.white_block
+ %tr
+ %th{:style => "width:50px;"}
+ %th Nom
+ %th Localisation
+ %th Email
+ %th Téléphone
+
+
+ =render @users
\ No newline at end of file
diff --git a/app/views/student/student_users/new.haml b/app/views/student/student_users/new.haml
new file mode 100644
index 0000000..a461917
--- /dev/null
+++ b/app/views/student/student_users/new.haml
@@ -0,0 +1,13 @@
+.form-signin
+
+ %h1 M'inscrire
+
+
+ = semantic_form_for [:student, @user] do |f|
+ =render :partial => "form_min", :locals => {:f => f}
+
+
+ %br
+ =f.submit "Sauvegarder", :class => "btn btn-primary"
+
+
\ No newline at end of file
diff --git a/app/views/student/student_users/show.haml b/app/views/student/student_users/show.haml
new file mode 100644
index 0000000..0194d5a
--- /dev/null
+++ b/app/views/student/student_users/show.haml
@@ -0,0 +1,37 @@
+.white_block.pad
+ %h1 Fiche étudiant
+ .row
+
+ .col-md-2
+ =image_tag (@user.avatar? ? @user.avatar.square.url : ""), :class => "avatar", :style => "width:100%; border-radius:50%;"
+ .clear
+ %br
+ .col-md-10
+ %br
+ %p
+ =@user.firstname
+ =@user.name
+
+ -if @user.country? or @user.cp? or @user.city
+ %p
+ =@user.cp
+ =@user.city
+ -if @user.country
+ ="-"
+ =@user.country
+
+ -if @user.show_email and @user.email?
+ %p
+ =link_to @user.email, "mailto:#{@user.email}"
+
+ -if @user.show_tel and @user.tel?
+ =@user.tel
+
+
+
+
+
+ -if @user.bio
+ %hr
+ =simple_format @user.bio
+ %hr
\ No newline at end of file
diff --git a/app/views/student/topics/_show.html.haml b/app/views/student/topics/_show.html.haml
new file mode 100644
index 0000000..f68b6b0
--- /dev/null
+++ b/app/views/student/topics/_show.html.haml
@@ -0,0 +1 @@
+.white_block.pad=render :object => @topic.block, :partial => "public/blocks/block"
diff --git a/app/views/student/topics/_topic.haml b/app/views/student/topics/_topic.haml
new file mode 100644
index 0000000..890f41b
--- /dev/null
+++ b/app/views/student/topics/_topic.haml
@@ -0,0 +1 @@
+%li{:id => "topic_line_#{topic.id}"}= link_to topic.title, [:student, topic], :remote => true
diff --git a/app/views/student/topics/index.html.haml b/app/views/student/topics/index.html.haml
new file mode 100644
index 0000000..d4b1af6
--- /dev/null
+++ b/app/views/student/topics/index.html.haml
@@ -0,0 +1,16 @@
+.row#topic_app_index
+
+
+ .col-md-4#left
+ %ul.nav.nav-pills.nav-stacked
+ =render @topics
+
+
+
+
+
+ .col-md-8#topic_show
+ =render :partial => "show", :object => @topic if @topic
+ :javascript
+ $("#left ul li:first-child").addClass("active");
+
\ No newline at end of file
diff --git a/app/views/student/topics/show.js.erb b/app/views/student/topics/show.js.erb
new file mode 100644
index 0000000..35571c3
--- /dev/null
+++ b/app/views/student/topics/show.js.erb
@@ -0,0 +1,5 @@
+$('.nav-pills li').removeClass("active");
+
+$('#topic_line_<%= @topic.id %>').addClass("active");
+
+$('#topic_show').html("<%= escape_javascript(render(:partial => "show")) %>");
diff --git a/app/views/student_mails/reset_password.html.haml b/app/views/student_mails/reset_password.html.haml
new file mode 100644
index 0000000..839d3b6
--- /dev/null
+++ b/app/views/student_mails/reset_password.html.haml
@@ -0,0 +1,11 @@
+%p
+ Bonjour,
+%p
+ Vous avez fait une demande pour réinitialiser votre mot de passe.
+%p
+ Vous pouvez suivre ce lien pour définir votre nouveau mot de passe :
+%p{:style => "text-align:center;"}
+ -url = edit_student_password_reset_url(:id => @student_user.reset_password_token)
+ =link_to url, url
+%p A bientôt !
+%p Geneviève Gagos
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 5634646..2793daf 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -19,6 +19,31 @@ CMSnb::Application.routes.draw do
get 'rubriques/:id.html' => "public/portfolios#show", :as => "public_portfolio"
get 'vos-temoignages/:slug.:f' => 'public/testimonies#show', :as => :testimony, :f => "html"
+ namespace :student do
+ root :to => "topics#index", :id => 1
+ resources :student_topics
+ resources :student_messages
+ resources :students
+ resources :student_categories
+ resources :student_users
+ resources :password_resets
+
+ resources :topics
+
+ resources :student_user_images do
+ member do
+ get :rotate
+ end
+ end
+ resources :auths do
+ collection do
+ get :logout
+ end
+ end
+
+ end
+
+
namespace :public do
resources :testimonies
resources :portfolios
@@ -65,6 +90,12 @@ CMSnb::Application.routes.draw do
end
namespace :admin do
+ resources :student_users
+ resources :student_groups
+ resources :note_files
+ resources :notes
+ resources :topics
+
resources :testimonies
resources :photos
resources :quotes
diff --git a/db/migrate/20130814112013_create_student_users.rb b/db/migrate/20130814112013_create_student_users.rb
new file mode 100644
index 0000000..cabe82f
--- /dev/null
+++ b/db/migrate/20130814112013_create_student_users.rb
@@ -0,0 +1,50 @@
+class CreateStudentUsers < ActiveRecord::Migration
+ def change
+ create_table :student_users do |t|
+ t.string :name
+ t.string :firstname
+ t.text :bio
+ t.string :avatar
+ t.string :localisation
+ t.boolean :moderator
+ t.string :address
+ t.string :address2
+ t.string :cp
+ t.string :city
+ t.string :country
+ t.string :tel
+ t.boolean :show_tel
+ t.boolean :show_email
+
+ t.string :auth_token
+
+
+ ## Database authenticatable
+ t.string :email, :null => false, :default => ""
+ t.string :password_digest, :null => false, :default => ""
+
+ ## Recoverable
+ t.string :reset_password_token
+ t.datetime :reset_password_sent_at
+
+ ## Rememberable
+ t.datetime :remember_created_at
+
+ ## Trackable
+ t.integer :sign_in_count, :default => 0
+ t.datetime :current_sign_in_at
+ t.datetime :last_sign_in_at
+ t.string :current_sign_in_ip
+ t.string :last_sign_in_ip
+
+ t.boolean :lock
+ t.datetime :locked_at
+
+
+
+ t.timestamps
+ end
+
+ StudentUser.create(:email => "info@nicolasbally.com", :password => "123456", :password_confirmation => "123456")
+ end
+end
diff --git a/db/migrate/20140612064654_create_topics.rb b/db/migrate/20140612064654_create_topics.rb
new file mode 100644
index 0000000..2e32809
--- /dev/null
+++ b/db/migrate/20140612064654_create_topics.rb
@@ -0,0 +1,13 @@
+# -*- encoding : utf-8 -*-
+class CreateTopics < ActiveRecord::Migration
+ def change
+ create_table :topics do |t|
+ t.string :title
+ t.text :description
+ t.references :admin
+
+ t.timestamps
+ end
+ add_index :topics, :admin_id
+ end
+end
diff --git a/db/migrate/20140612064754_create_notes.rb b/db/migrate/20140612064754_create_notes.rb
new file mode 100644
index 0000000..1709822
--- /dev/null
+++ b/db/migrate/20140612064754_create_notes.rb
@@ -0,0 +1,13 @@
+# -*- encoding : utf-8 -*-
+class CreateNotes < ActiveRecord::Migration
+ def change
+ create_table :notes do |t|
+ t.string :subject
+ t.text :message
+ t.references :admin
+ t.references :topic
+ t.timestamps
+ end
+ add_index :notes, :admin_id
+ end
+end
diff --git a/db/migrate/20140612065146_create_topic_files.rb b/db/migrate/20140612065146_create_topic_files.rb
new file mode 100644
index 0000000..8d69b64
--- /dev/null
+++ b/db/migrate/20140612065146_create_topic_files.rb
@@ -0,0 +1,15 @@
+# -*- encoding : utf-8 -*-
+class CreateTopicFiles < ActiveRecord::Migration
+ def change
+ create_table :note_files do |t|
+ t.string :file
+ t.string :name
+ t.string :slug
+ t.text :description
+ t.references :admin
+ t.references :topic
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20140719210441_create_student_groups.rb b/db/migrate/20140719210441_create_student_groups.rb
new file mode 100644
index 0000000..7a252aa
--- /dev/null
+++ b/db/migrate/20140719210441_create_student_groups.rb
@@ -0,0 +1,10 @@
+class CreateStudentGroups < ActiveRecord::Migration
+ def change
+ create_table :student_groups do |t|
+ t.string :name
+ t.string :slug
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20140719211604_create_student_user_groups.rb b/db/migrate/20140719211604_create_student_user_groups.rb
new file mode 100644
index 0000000..a00ac2c
--- /dev/null
+++ b/db/migrate/20140719211604_create_student_user_groups.rb
@@ -0,0 +1,10 @@
+class CreateStudentUserGroups < ActiveRecord::Migration
+ def change
+ create_table :student_user_groups do |t|
+ t.references :student_user, index: true
+ t.references :student_group, index: true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20140719214911_create_topic_student_groups.rb b/db/migrate/20140719214911_create_topic_student_groups.rb
new file mode 100644
index 0000000..1e06af3
--- /dev/null
+++ b/db/migrate/20140719214911_create_topic_student_groups.rb
@@ -0,0 +1,10 @@
+class CreateTopicStudentGroups < ActiveRecord::Migration
+ def change
+ create_table :topic_student_groups do |t|
+ t.references :topic, index: true
+ t.references :student_group, index: true
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20140719230318_add_token_to_data_files.rb b/db/migrate/20140719230318_add_token_to_data_files.rb
new file mode 100644
index 0000000..a7907c7
--- /dev/null
+++ b/db/migrate/20140719230318_add_token_to_data_files.rb
@@ -0,0 +1,5 @@
+class AddTokenToDataFiles < ActiveRecord::Migration
+ def change
+ add_column :data_files, :token, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index eaf6f1e..9ab642e 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20130717201143) do
+ActiveRecord::Schema.define(version: 20140719230318) do
create_table "admins", force: true do |t|
t.string "name"
@@ -160,6 +160,7 @@ ActiveRecord::Schema.define(version: 20130717201143) do
t.integer "file_folder_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "token"
end
create_table "download_contents", force: true do |t|
@@ -336,6 +337,28 @@ ActiveRecord::Schema.define(version: 20130717201143) do
t.datetime "updated_at", null: false
end
+ create_table "note_files", force: true do |t|
+ t.string "file"
+ t.string "name"
+ t.string "slug"
+ t.text "description"
+ t.integer "admin_id"
+ t.integer "topic_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ create_table "notes", force: true do |t|
+ t.string "subject"
+ t.text "message"
+ t.integer "admin_id"
+ t.integer "topic_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "notes", ["admin_id"], name: "index_notes_on_admin_id", using: :btree
+
create_table "pages", force: true do |t|
t.text "title"
t.text "description"
@@ -353,6 +376,55 @@ ActiveRecord::Schema.define(version: 20130717201143) do
t.datetime "updated_at", null: false
end
+ create_table "student_groups", force: true do |t|
+ t.string "name"
+ t.string "slug"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ create_table "student_user_groups", force: true do |t|
+ t.integer "student_user_id"
+ t.integer "student_group_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "student_user_groups", ["student_group_id"], name: "index_student_user_groups_on_student_group_id", using: :btree
+ add_index "student_user_groups", ["student_user_id"], name: "index_student_user_groups_on_student_user_id", using: :btree
+
+ create_table "student_users", force: true do |t|
+ t.string "name"
+ t.string "firstname"
+ t.text "bio"
+ t.string "avatar"
+ t.string "localisation"
+ t.boolean "moderator"
+ t.string "address"
+ t.string "address2"
+ t.string "cp"
+ t.string "city"
+ t.string "country"
+ t.string "tel"
+ t.boolean "show_tel"
+ t.boolean "show_email"
+ t.string "auth_token"
+ t.string "email", default: "", null: false
+ t.string "password_digest", default: "", null: false
+ t.string "reset_password_token"
+ t.datetime "reset_password_sent_at"
+ t.datetime "remember_created_at"
+ t.integer "sign_in_count", default: 0
+ t.datetime "current_sign_in_at"
+ t.datetime "last_sign_in_at"
+ t.string "current_sign_in_ip"
+ t.string "last_sign_in_ip"
+ t.boolean "lock"
+ t.datetime "locked_at"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "table_contents", force: true do |t|
t.integer "style"
t.integer "nbr_rows"
@@ -393,4 +465,24 @@ ActiveRecord::Schema.define(version: 20130717201143) do
t.datetime "updated_at", null: false
end
+ create_table "topic_student_groups", force: true do |t|
+ t.integer "topic_id"
+ t.integer "student_group_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "topic_student_groups", ["student_group_id"], name: "index_topic_student_groups_on_student_group_id", using: :btree
+ add_index "topic_student_groups", ["topic_id"], name: "index_topic_student_groups_on_topic_id", using: :btree
+
+ create_table "topics", force: true do |t|
+ t.string "title"
+ t.text "description"
+ t.integer "admin_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "topics", ["admin_id"], name: "index_topics_on_admin_id", using: :btree
+
end
diff --git a/public/background.png b/public/background.png
deleted file mode 100644
index 62dcefc..0000000
Binary files a/public/background.png and /dev/null differ
diff --git a/public/fonts/FontAwesome.otf b/public/fonts/FontAwesome.otf
new file mode 100644
index 0000000..3461e3f
Binary files /dev/null and b/public/fonts/FontAwesome.otf differ
diff --git a/public/fonts/fontawesome-webfont.eot b/public/fonts/fontawesome-webfont.eot
index c080283..6cfd566 100755
Binary files a/public/fonts/fontawesome-webfont.eot and b/public/fonts/fontawesome-webfont.eot differ
diff --git a/public/fonts/fontawesome-webfont.svg b/public/fonts/fontawesome-webfont.svg
index 10a1e1b..a9f8469 100755
--- a/public/fonts/fontawesome-webfont.svg
+++ b/public/fonts/fontawesome-webfont.svg
@@ -14,10 +14,11 @@
+
-
+
-
+
@@ -30,310 +31,474 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/fonts/fontawesome-webfont.ttf b/public/fonts/fontawesome-webfont.ttf
index 908f69e..5cd6cff 100755
Binary files a/public/fonts/fontawesome-webfont.ttf and b/public/fonts/fontawesome-webfont.ttf differ
diff --git a/public/fonts/fontawesome-webfont.woff b/public/fonts/fontawesome-webfont.woff
index a33af95..9eaecb3 100755
Binary files a/public/fonts/fontawesome-webfont.woff and b/public/fonts/fontawesome-webfont.woff differ
diff --git a/public/images/admin/default_image.png b/public/images/admin/default_image.png
new file mode 100644
index 0000000..a89151e
Binary files /dev/null and b/public/images/admin/default_image.png differ
diff --git a/public/images/logo.png b/public/images/logo.png
new file mode 100644
index 0000000..3d9a848
Binary files /dev/null and b/public/images/logo.png differ
diff --git a/public/img_4958-1.jpg b/public/img_4958-1.jpg
new file mode 100644
index 0000000..f082231
Binary files /dev/null and b/public/img_4958-1.jpg differ
diff --git a/public/login_background.jpg b/public/login_background.jpg
new file mode 100644
index 0000000..7b2a1d1
Binary files /dev/null and b/public/login_background.jpg differ
diff --git a/public/login_background2.jpg b/public/login_background2.jpg
new file mode 100644
index 0000000..994a6f6
Binary files /dev/null and b/public/login_background2.jpg differ
diff --git a/public/login_background3.jpg b/public/login_background3.jpg
new file mode 100644
index 0000000..6806a47
Binary files /dev/null and b/public/login_background3.jpg differ
diff --git a/public/login_background4.jpg b/public/login_background4.jpg
new file mode 100644
index 0000000..bead0bb
Binary files /dev/null and b/public/login_background4.jpg differ
diff --git a/public/login_background5.jpg b/public/login_background5.jpg
new file mode 100644
index 0000000..a0d9d05
Binary files /dev/null and b/public/login_background5.jpg differ
diff --git a/public/login_background6.jpg b/public/login_background6.jpg
new file mode 100644
index 0000000..77eb2de
Binary files /dev/null and b/public/login_background6.jpg differ
diff --git a/public/login_background7.jpg b/public/login_background7.jpg
new file mode 100644
index 0000000..335f38f
Binary files /dev/null and b/public/login_background7.jpg differ
diff --git a/public/login_background8.jpg b/public/login_background8.jpg
new file mode 100644
index 0000000..516d27c
Binary files /dev/null and b/public/login_background8.jpg differ
diff --git a/public/logo-white.png b/public/logo-white.png
new file mode 100644
index 0000000..81c9d1c
Binary files /dev/null and b/public/logo-white.png differ
diff --git a/test/fixtures/student_groups.yml b/test/fixtures/student_groups.yml
new file mode 100644
index 0000000..1e500b9
--- /dev/null
+++ b/test/fixtures/student_groups.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+
+one:
+ name: MyString
+ slug: MyString
+
+two:
+ name: MyString
+ slug: MyString
diff --git a/test/fixtures/student_user_groups.yml b/test/fixtures/student_user_groups.yml
new file mode 100644
index 0000000..a582829
--- /dev/null
+++ b/test/fixtures/student_user_groups.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+
+one:
+ student_user_id:
+ student_group_id:
+
+two:
+ student_user_id:
+ student_group_id:
diff --git a/test/fixtures/topic_student_groups.yml b/test/fixtures/topic_student_groups.yml
new file mode 100644
index 0000000..b1ab9f0
--- /dev/null
+++ b/test/fixtures/topic_student_groups.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+
+one:
+ topic_id:
+ student_group_id:
+
+two:
+ topic_id:
+ student_group_id:
diff --git a/test/models/student_group_test.rb b/test/models/student_group_test.rb
new file mode 100644
index 0000000..051233c
--- /dev/null
+++ b/test/models/student_group_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class StudentGroupTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/student_user_group_test.rb b/test/models/student_user_group_test.rb
new file mode 100644
index 0000000..9d8c891
--- /dev/null
+++ b/test/models/student_user_group_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class StudentUserGroupTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/topic_student_group_test.rb b/test/models/topic_student_group_test.rb
new file mode 100644
index 0000000..0f31a4b
--- /dev/null
+++ b/test/models/topic_student_group_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class TopicStudentGroupTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end