First checkin
50
Gemfile
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
|
gem 'rails', '3.2.9'
|
||||||
|
|
||||||
|
# Bundle edge Rails instead:
|
||||||
|
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
||||||
|
|
||||||
|
gem 'sqlite3'
|
||||||
|
|
||||||
|
|
||||||
|
# Gems used only for assets and not required
|
||||||
|
# in production environments by default.
|
||||||
|
group :assets do
|
||||||
|
gem 'sass-rails', '~> 3.2.3'
|
||||||
|
gem 'coffee-rails', '~> 3.2.1'
|
||||||
|
|
||||||
|
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||||
|
# gem 'therubyracer', :platforms => :ruby
|
||||||
|
|
||||||
|
gem 'uglifier', '>= 1.0.3'
|
||||||
|
end
|
||||||
|
|
||||||
|
gem 'paperclip', '~> 3.0'
|
||||||
|
gem 'jquery-rails'
|
||||||
|
gem 'jquery_datepicker'
|
||||||
|
gem 'jquery-fileupload-rails'
|
||||||
|
gem 'devise'
|
||||||
|
gem 'cancan'
|
||||||
|
gem "haml"
|
||||||
|
gem 'bcrypt-ruby', '~> 3.0.0'
|
||||||
|
gem 'node'
|
||||||
|
gem 'twitter-bootstrap-rails'
|
||||||
|
gem 'formtastic-bootstrap'
|
||||||
|
gem 'cocoon'
|
||||||
|
gem 'transitions', :require => ["transitions", "active_record/transitions"]
|
||||||
|
gem 'acts_as_commentable_with_threading'
|
||||||
|
gem 'prawn'
|
||||||
|
gem 'prawn_rails'
|
||||||
|
|
||||||
|
# To use Jbuilder templates for JSON
|
||||||
|
# gem 'jbuilder'
|
||||||
|
|
||||||
|
# Use unicorn as the app server
|
||||||
|
# gem 'unicorn'
|
||||||
|
|
||||||
|
# Deploy with Capistrano
|
||||||
|
# gem 'capistrano'
|
||||||
|
|
||||||
|
# To use debugger
|
||||||
|
# gem 'debugger'
|
||||||
183
Gemfile.lock
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
Ascii85 (1.0.2)
|
||||||
|
actionmailer (3.2.9)
|
||||||
|
actionpack (= 3.2.9)
|
||||||
|
mail (~> 2.4.4)
|
||||||
|
actionpack (3.2.9)
|
||||||
|
activemodel (= 3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
builder (~> 3.0.0)
|
||||||
|
erubis (~> 2.7.0)
|
||||||
|
journey (~> 1.0.4)
|
||||||
|
rack (~> 1.4.0)
|
||||||
|
rack-cache (~> 1.2)
|
||||||
|
rack-test (~> 0.6.1)
|
||||||
|
sprockets (~> 2.2.1)
|
||||||
|
activemodel (3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
builder (~> 3.0.0)
|
||||||
|
activerecord (3.2.9)
|
||||||
|
activemodel (= 3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
arel (~> 3.0.2)
|
||||||
|
tzinfo (~> 0.3.29)
|
||||||
|
activeresource (3.2.9)
|
||||||
|
activemodel (= 3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
activesupport (3.2.9)
|
||||||
|
i18n (~> 0.6)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
acts_as_commentable_with_threading (1.1.2)
|
||||||
|
activerecord (>= 3.0)
|
||||||
|
activesupport (~> 3.0)
|
||||||
|
awesome_nested_set (>= 2.0)
|
||||||
|
arel (3.0.2)
|
||||||
|
awesome_nested_set (2.1.5)
|
||||||
|
activerecord (>= 3.0.0)
|
||||||
|
bcrypt-ruby (3.0.1)
|
||||||
|
builder (3.0.4)
|
||||||
|
cancan (1.6.8)
|
||||||
|
cocaine (0.4.2)
|
||||||
|
cocoon (1.1.1)
|
||||||
|
coffee-rails (3.2.2)
|
||||||
|
coffee-script (>= 2.2.0)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
coffee-script (2.2.0)
|
||||||
|
coffee-script-source
|
||||||
|
execjs
|
||||||
|
coffee-script-source (1.4.0)
|
||||||
|
devise (2.1.2)
|
||||||
|
bcrypt-ruby (~> 3.0)
|
||||||
|
orm_adapter (~> 0.1)
|
||||||
|
railties (~> 3.1)
|
||||||
|
warden (~> 1.2.1)
|
||||||
|
erubis (2.7.0)
|
||||||
|
eventmachine (1.0.0)
|
||||||
|
execjs (1.4.0)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
formtastic (2.2.1)
|
||||||
|
actionpack (>= 3.0)
|
||||||
|
formtastic-bootstrap (2.0.0)
|
||||||
|
formtastic (~> 2.2)
|
||||||
|
formtastic-bootstrap
|
||||||
|
haml (3.1.7)
|
||||||
|
hashery (2.1.0)
|
||||||
|
hike (1.2.1)
|
||||||
|
i18n (0.6.1)
|
||||||
|
journey (1.0.4)
|
||||||
|
jquery-fileupload-rails (0.4.0)
|
||||||
|
actionpack (>= 3.1)
|
||||||
|
railties (>= 3.1)
|
||||||
|
jquery-rails (2.1.4)
|
||||||
|
railties (>= 3.0, < 5.0)
|
||||||
|
thor (>= 0.14, < 2.0)
|
||||||
|
jquery_datepicker (0.4)
|
||||||
|
json (1.7.5)
|
||||||
|
mail (2.4.4)
|
||||||
|
i18n (>= 0.4.0)
|
||||||
|
mime-types (~> 1.16)
|
||||||
|
treetop (~> 1.4.8)
|
||||||
|
mime-types (1.19)
|
||||||
|
multi_json (1.5.0)
|
||||||
|
node (0.0.2)
|
||||||
|
eventmachine
|
||||||
|
orm_adapter (0.4.0)
|
||||||
|
paperclip (3.4.0)
|
||||||
|
activemodel (>= 3.0.0)
|
||||||
|
activerecord (>= 3.0.0)
|
||||||
|
activesupport (>= 3.0.0)
|
||||||
|
cocaine (~> 0.4.0)
|
||||||
|
mime-types
|
||||||
|
pdf-reader (1.2.0)
|
||||||
|
Ascii85 (~> 1.0.0)
|
||||||
|
hashery (~> 2.0)
|
||||||
|
ruby-rc4
|
||||||
|
polyglot (0.3.3)
|
||||||
|
prawn (0.12.0)
|
||||||
|
pdf-reader (>= 0.9.0)
|
||||||
|
ttfunk (~> 1.0.2)
|
||||||
|
prawn_rails (0.0.11)
|
||||||
|
prawn (>= 0.11.1)
|
||||||
|
railties (>= 3.0.0)
|
||||||
|
rack (1.4.1)
|
||||||
|
rack-cache (1.2)
|
||||||
|
rack (>= 0.4)
|
||||||
|
rack-ssl (1.3.2)
|
||||||
|
rack
|
||||||
|
rack-test (0.6.2)
|
||||||
|
rack (>= 1.0)
|
||||||
|
rails (3.2.9)
|
||||||
|
actionmailer (= 3.2.9)
|
||||||
|
actionpack (= 3.2.9)
|
||||||
|
activerecord (= 3.2.9)
|
||||||
|
activeresource (= 3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
bundler (~> 1.0)
|
||||||
|
railties (= 3.2.9)
|
||||||
|
railties (3.2.9)
|
||||||
|
actionpack (= 3.2.9)
|
||||||
|
activesupport (= 3.2.9)
|
||||||
|
rack-ssl (~> 1.3.2)
|
||||||
|
rake (>= 0.8.7)
|
||||||
|
rdoc (~> 3.4)
|
||||||
|
thor (>= 0.14.6, < 2.0)
|
||||||
|
rake (10.0.3)
|
||||||
|
rdoc (3.12)
|
||||||
|
json (~> 1.4)
|
||||||
|
ruby-rc4 (0.1.5)
|
||||||
|
sass (3.2.4)
|
||||||
|
sass-rails (3.2.5)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
sass (>= 3.1.10)
|
||||||
|
tilt (~> 1.3)
|
||||||
|
sprockets (2.2.2)
|
||||||
|
hike (~> 1.2)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rack (~> 1.0)
|
||||||
|
tilt (~> 1.1, != 1.3.0)
|
||||||
|
sqlite3 (1.3.6)
|
||||||
|
thor (0.16.0)
|
||||||
|
tilt (1.3.3)
|
||||||
|
transitions (0.1.4)
|
||||||
|
treetop (1.4.12)
|
||||||
|
polyglot
|
||||||
|
polyglot (>= 0.3.1)
|
||||||
|
ttfunk (1.0.3)
|
||||||
|
twitter-bootstrap-rails (2.1.9)
|
||||||
|
actionpack (>= 3.1)
|
||||||
|
execjs
|
||||||
|
railties (>= 3.1)
|
||||||
|
tzinfo (0.3.35)
|
||||||
|
uglifier (1.3.0)
|
||||||
|
execjs (>= 0.3.0)
|
||||||
|
multi_json (~> 1.0, >= 1.0.2)
|
||||||
|
warden (1.2.1)
|
||||||
|
rack (>= 1.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
acts_as_commentable_with_threading
|
||||||
|
bcrypt-ruby (~> 3.0.0)
|
||||||
|
cancan
|
||||||
|
cocoon
|
||||||
|
coffee-rails (~> 3.2.1)
|
||||||
|
devise
|
||||||
|
formtastic-bootstrap
|
||||||
|
haml
|
||||||
|
jquery-fileupload-rails
|
||||||
|
jquery-rails
|
||||||
|
jquery_datepicker
|
||||||
|
node
|
||||||
|
paperclip (~> 3.0)
|
||||||
|
prawn
|
||||||
|
prawn_rails
|
||||||
|
rails (= 3.2.9)
|
||||||
|
sass-rails (~> 3.2.3)
|
||||||
|
sqlite3
|
||||||
|
transitions
|
||||||
|
twitter-bootstrap-rails
|
||||||
|
uglifier (>= 1.0.3)
|
||||||
261
README.rdoc
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
== Welcome to Rails
|
||||||
|
|
||||||
|
Rails is a web-application framework that includes everything needed to create
|
||||||
|
database-backed web applications according to the Model-View-Control pattern.
|
||||||
|
|
||||||
|
This pattern splits the view (also called the presentation) into "dumb"
|
||||||
|
templates that are primarily responsible for inserting pre-built data in between
|
||||||
|
HTML tags. The model contains the "smart" domain objects (such as Account,
|
||||||
|
Product, Person, Post) that holds all the business logic and knows how to
|
||||||
|
persist themselves to a database. The controller handles the incoming requests
|
||||||
|
(such as Save New Account, Update Product, Show Post) by manipulating the model
|
||||||
|
and directing data to the view.
|
||||||
|
|
||||||
|
In Rails, the model is handled by what's called an object-relational mapping
|
||||||
|
layer entitled Active Record. This layer allows you to present the data from
|
||||||
|
database rows as objects and embellish these data objects with business logic
|
||||||
|
methods. You can read more about Active Record in
|
||||||
|
link:files/vendor/rails/activerecord/README.html.
|
||||||
|
|
||||||
|
The controller and view are handled by the Action Pack, which handles both
|
||||||
|
layers by its two parts: Action View and Action Controller. These two layers
|
||||||
|
are bundled in a single package due to their heavy interdependence. This is
|
||||||
|
unlike the relationship between the Active Record and Action Pack that is much
|
||||||
|
more separate. Each of these packages can be used independently outside of
|
||||||
|
Rails. You can read more about Action Pack in
|
||||||
|
link:files/vendor/rails/actionpack/README.html.
|
||||||
|
|
||||||
|
|
||||||
|
== Getting Started
|
||||||
|
|
||||||
|
1. At the command prompt, create a new Rails application:
|
||||||
|
<tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
|
||||||
|
|
||||||
|
2. Change directory to <tt>myapp</tt> and start the web server:
|
||||||
|
<tt>cd myapp; rails server</tt> (run with --help for options)
|
||||||
|
|
||||||
|
3. Go to http://localhost:3000/ and you'll see:
|
||||||
|
"Welcome aboard: You're riding Ruby on Rails!"
|
||||||
|
|
||||||
|
4. Follow the guidelines to start developing your application. You can find
|
||||||
|
the following resources handy:
|
||||||
|
|
||||||
|
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
|
||||||
|
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
|
||||||
|
|
||||||
|
|
||||||
|
== Debugging Rails
|
||||||
|
|
||||||
|
Sometimes your application goes wrong. Fortunately there are a lot of tools that
|
||||||
|
will help you debug it and get it back on the rails.
|
||||||
|
|
||||||
|
First area to check is the application log files. Have "tail -f" commands
|
||||||
|
running on the server.log and development.log. Rails will automatically display
|
||||||
|
debugging and runtime information to these files. Debugging info will also be
|
||||||
|
shown in the browser on requests from 127.0.0.1.
|
||||||
|
|
||||||
|
You can also log your own messages directly into the log file from your code
|
||||||
|
using the Ruby logger class from inside your controllers. Example:
|
||||||
|
|
||||||
|
class WeblogController < ActionController::Base
|
||||||
|
def destroy
|
||||||
|
@weblog = Weblog.find(params[:id])
|
||||||
|
@weblog.destroy
|
||||||
|
logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
The result will be a message in your log file along the lines of:
|
||||||
|
|
||||||
|
Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
|
||||||
|
|
||||||
|
More information on how to use the logger is at http://www.ruby-doc.org/core/
|
||||||
|
|
||||||
|
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
|
||||||
|
several books available online as well:
|
||||||
|
|
||||||
|
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
|
||||||
|
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
|
||||||
|
|
||||||
|
These two books will bring you up to speed on the Ruby language and also on
|
||||||
|
programming in general.
|
||||||
|
|
||||||
|
|
||||||
|
== Debugger
|
||||||
|
|
||||||
|
Debugger support is available through the debugger command when you start your
|
||||||
|
Mongrel or WEBrick server with --debugger. This means that you can break out of
|
||||||
|
execution at any point in the code, investigate and change the model, and then,
|
||||||
|
resume execution! You need to install ruby-debug to run the server in debugging
|
||||||
|
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
|
||||||
|
|
||||||
|
class WeblogController < ActionController::Base
|
||||||
|
def index
|
||||||
|
@posts = Post.all
|
||||||
|
debugger
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
So the controller will accept the action, run the first line, then present you
|
||||||
|
with a IRB prompt in the server window. Here you can do things like:
|
||||||
|
|
||||||
|
>> @posts.inspect
|
||||||
|
=> "[#<Post:0x14a6be8
|
||||||
|
@attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
|
||||||
|
#<Post:0x14a6620
|
||||||
|
@attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
|
||||||
|
>> @posts.first.title = "hello from a debugger"
|
||||||
|
=> "hello from a debugger"
|
||||||
|
|
||||||
|
...and even better, you can examine how your runtime objects actually work:
|
||||||
|
|
||||||
|
>> f = @posts.first
|
||||||
|
=> #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
|
||||||
|
>> f.
|
||||||
|
Display all 152 possibilities? (y or n)
|
||||||
|
|
||||||
|
Finally, when you're ready to resume execution, you can enter "cont".
|
||||||
|
|
||||||
|
|
||||||
|
== Console
|
||||||
|
|
||||||
|
The console is a Ruby shell, which allows you to interact with your
|
||||||
|
application's domain model. Here you'll have all parts of the application
|
||||||
|
configured, just like it is when the application is running. You can inspect
|
||||||
|
domain models, change values, and save to the database. Starting the script
|
||||||
|
without arguments will launch it in the development environment.
|
||||||
|
|
||||||
|
To start the console, run <tt>rails console</tt> from the application
|
||||||
|
directory.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
|
||||||
|
made to the database.
|
||||||
|
* Passing an environment name as an argument will load the corresponding
|
||||||
|
environment. Example: <tt>rails console production</tt>.
|
||||||
|
|
||||||
|
To reload your controllers and models after launching the console run
|
||||||
|
<tt>reload!</tt>
|
||||||
|
|
||||||
|
More information about irb can be found at:
|
||||||
|
link:http://www.rubycentral.org/pickaxe/irb.html
|
||||||
|
|
||||||
|
|
||||||
|
== dbconsole
|
||||||
|
|
||||||
|
You can go to the command line of your database directly through <tt>rails
|
||||||
|
dbconsole</tt>. You would be connected to the database with the credentials
|
||||||
|
defined in database.yml. Starting the script without arguments will connect you
|
||||||
|
to the development database. Passing an argument will connect you to a different
|
||||||
|
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
|
||||||
|
PostgreSQL and SQLite 3.
|
||||||
|
|
||||||
|
== Description of Contents
|
||||||
|
|
||||||
|
The default directory structure of a generated Ruby on Rails application:
|
||||||
|
|
||||||
|
|-- app
|
||||||
|
| |-- assets
|
||||||
|
| |-- images
|
||||||
|
| |-- javascripts
|
||||||
|
| `-- stylesheets
|
||||||
|
| |-- controllers
|
||||||
|
| |-- helpers
|
||||||
|
| |-- mailers
|
||||||
|
| |-- models
|
||||||
|
| `-- views
|
||||||
|
| `-- layouts
|
||||||
|
|-- config
|
||||||
|
| |-- environments
|
||||||
|
| |-- initializers
|
||||||
|
| `-- locales
|
||||||
|
|-- db
|
||||||
|
|-- doc
|
||||||
|
|-- lib
|
||||||
|
| `-- tasks
|
||||||
|
|-- log
|
||||||
|
|-- public
|
||||||
|
|-- script
|
||||||
|
|-- test
|
||||||
|
| |-- fixtures
|
||||||
|
| |-- functional
|
||||||
|
| |-- integration
|
||||||
|
| |-- performance
|
||||||
|
| `-- unit
|
||||||
|
|-- tmp
|
||||||
|
| |-- cache
|
||||||
|
| |-- pids
|
||||||
|
| |-- sessions
|
||||||
|
| `-- sockets
|
||||||
|
`-- vendor
|
||||||
|
|-- assets
|
||||||
|
`-- stylesheets
|
||||||
|
`-- plugins
|
||||||
|
|
||||||
|
app
|
||||||
|
Holds all the code that's specific to this particular application.
|
||||||
|
|
||||||
|
app/assets
|
||||||
|
Contains subdirectories for images, stylesheets, and JavaScript files.
|
||||||
|
|
||||||
|
app/controllers
|
||||||
|
Holds controllers that should be named like weblogs_controller.rb for
|
||||||
|
automated URL mapping. All controllers should descend from
|
||||||
|
ApplicationController which itself descends from ActionController::Base.
|
||||||
|
|
||||||
|
app/models
|
||||||
|
Holds models that should be named like post.rb. Models descend from
|
||||||
|
ActiveRecord::Base by default.
|
||||||
|
|
||||||
|
app/views
|
||||||
|
Holds the template files for the view that should be named like
|
||||||
|
weblogs/index.html.erb for the WeblogsController#index action. All views use
|
||||||
|
eRuby syntax by default.
|
||||||
|
|
||||||
|
app/views/layouts
|
||||||
|
Holds the template files for layouts to be used with views. This models the
|
||||||
|
common header/footer method of wrapping views. In your views, define a layout
|
||||||
|
using the <tt>layout :default</tt> and create a file named default.html.erb.
|
||||||
|
Inside default.html.erb, call <% yield %> to render the view using this
|
||||||
|
layout.
|
||||||
|
|
||||||
|
app/helpers
|
||||||
|
Holds view helpers that should be named like weblogs_helper.rb. These are
|
||||||
|
generated for you automatically when using generators for controllers.
|
||||||
|
Helpers can be used to wrap functionality for your views into methods.
|
||||||
|
|
||||||
|
config
|
||||||
|
Configuration files for the Rails environment, the routing map, the database,
|
||||||
|
and other dependencies.
|
||||||
|
|
||||||
|
db
|
||||||
|
Contains the database schema in schema.rb. db/migrate contains all the
|
||||||
|
sequence of Migrations for your schema.
|
||||||
|
|
||||||
|
doc
|
||||||
|
This directory is where your application documentation will be stored when
|
||||||
|
generated using <tt>rake doc:app</tt>
|
||||||
|
|
||||||
|
lib
|
||||||
|
Application specific libraries. Basically, any kind of custom code that
|
||||||
|
doesn't belong under controllers, models, or helpers. This directory is in
|
||||||
|
the load path.
|
||||||
|
|
||||||
|
public
|
||||||
|
The directory available for the web server. Also contains the dispatchers and the
|
||||||
|
default HTML files. This should be set as the DOCUMENT_ROOT of your web
|
||||||
|
server.
|
||||||
|
|
||||||
|
script
|
||||||
|
Helper scripts for automation and generation.
|
||||||
|
|
||||||
|
test
|
||||||
|
Unit and functional tests along with fixtures. When using the rails generate
|
||||||
|
command, template test files will be generated for you and placed in this
|
||||||
|
directory.
|
||||||
|
|
||||||
|
vendor
|
||||||
|
External libraries that the application depends on. Also includes the plugins
|
||||||
|
subdirectory. If the app has frozen rails, those gems also go here, under
|
||||||
|
vendor/rails/. This directory is in the load path.
|
||||||
7
Rakefile
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/usr/bin/env rake
|
||||||
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
|
require File.expand_path('../config/application', __FILE__)
|
||||||
|
|
||||||
|
Osem::Application.load_tasks
|
||||||
BIN
app/assets/images/rails.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
app/assets/images/ui-bg_flat_0_aaaaaa_40x100.png
Normal file
|
After Width: | Height: | Size: 180 B |
BIN
app/assets/images/ui-bg_flat_55_fbec88_40x100.png
Normal file
|
After Width: | Height: | Size: 182 B |
BIN
app/assets/images/ui-bg_glass_75_d0e5f5_1x400.png
Normal file
|
After Width: | Height: | Size: 124 B |
BIN
app/assets/images/ui-bg_glass_85_dfeffc_1x400.png
Normal file
|
After Width: | Height: | Size: 123 B |
BIN
app/assets/images/ui-bg_glass_95_fef1ec_1x400.png
Normal file
|
After Width: | Height: | Size: 149 B |
BIN
app/assets/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
app/assets/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
Normal file
|
After Width: | Height: | Size: 104 B |
BIN
app/assets/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
Normal file
|
After Width: | Height: | Size: 88 B |
BIN
app/assets/images/ui-icons_217bc0_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_2e83ff_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_469bdd_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_6da8d5_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_cd0a0a_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_d8e7f3_256x240.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/ui-icons_f9bd01_256x240.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
3
app/assets/javascripts/admin/admin.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/javascripts/admin/call_for_papers.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/javascripts/admin/conference.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/javascripts/admin/people.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/javascripts/admin/users.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/javascripts/admin/venue.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
74
app/assets/javascripts/application.js
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||||
|
// listed below.
|
||||||
|
//
|
||||||
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||||
|
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||||
|
//
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// the compiled file.
|
||||||
|
//
|
||||||
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||||
|
// GO AFTER THE REQUIRES BELOW.
|
||||||
|
//
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require jquery-ui
|
||||||
|
//= require jquery-fileupload
|
||||||
|
//= require twitter/bootstrap
|
||||||
|
//= require cocoon
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
$('.dropdown-toggle').dropdown();
|
||||||
|
$("#conference-start-datepicker").datepicker({
|
||||||
|
dateFormat: 'yy/mm/dd',
|
||||||
|
numberOfMonths: 2,
|
||||||
|
onSelect: function(selected) {
|
||||||
|
$("#conference-end-datepicker").datepicker("option","minDate", selected)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$("#conference-end-datepicker").datepicker({
|
||||||
|
dateFormat: 'yy/mm/dd',
|
||||||
|
numberOfMonths: 2,
|
||||||
|
onSelect: function(selected) {
|
||||||
|
$("#conference-start-datepicker").datepicker("option","maxDate", selected)
|
||||||
|
$("#cfp-hard-datepicker").datepicker("option","minDate", selected)
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#cfp-hard-datepicker").datepicker({
|
||||||
|
dateFormat: 'yy/mm/dd',
|
||||||
|
numberOfMonths: 2,
|
||||||
|
onSelect: function(selected) {
|
||||||
|
$("#conference-end-datepicker").datepicker("option","maxDate", selected)
|
||||||
|
$("#conference-start-datepicker").datepicker("option","maxDate", selected)
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".comment-reply-link").click(function(){
|
||||||
|
$(".comment-reply", $(this).parent()).toggle();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#event-comment-link").click(function(){
|
||||||
|
$("#comments-div").toggle();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".comment-reply").hide();
|
||||||
|
$(".user-details-popover").popover();
|
||||||
|
$("#comments-div").hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
function word_count(text, divId){
|
||||||
|
var r = 0;
|
||||||
|
var input = text.value.replace(/\s/g,' ');
|
||||||
|
var word_array = input.split(' ');
|
||||||
|
for (var i=0; i < word_array.length; i++) {
|
||||||
|
if (word_array[i].length > 0) r++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#' + divId).text(r);
|
||||||
|
}
|
||||||
4
app/assets/javascripts/bootstrap.js.coffee
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
jQuery ->
|
||||||
|
$("a[rel=popover]").popover()
|
||||||
|
$(".tooltip").tooltip()
|
||||||
|
$("a[rel=tooltip]").tooltip()
|
||||||
3
app/assets/javascripts/home.js.coffee
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Place all the behaviors and hooks related to the matching controller here.
|
||||||
|
# All this logic will automatically be available in application.js.
|
||||||
|
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||||
3
app/assets/stylesheets/admin/admin.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/admin controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
3
app/assets/stylesheets/admin/call_for_papers.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/call_for_papers controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
3
app/assets/stylesheets/admin/conference.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/conference controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
3
app/assets/stylesheets/admin/people.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/people controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
3
app/assets/stylesheets/admin/users.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/users controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
3
app/assets/stylesheets/admin/venue.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the admin/venue controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
7
app/assets/stylesheets/application.css
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
*= require formtastic-bootstrap
|
||||||
|
*= require bootstrap_and_overrides
|
||||||
|
*= require osem
|
||||||
|
*= require jquery-ui-1.9.2.custom
|
||||||
|
*= require jquery.fileupload-ui
|
||||||
|
*/
|
||||||
7
app/assets/stylesheets/bootstrap_and_overrides.css
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
=require twitter-bootstrap-static/bootstrap
|
||||||
|
|
||||||
|
Use Font Awesome icons (default)
|
||||||
|
To use Glyphicons sprites instead of Font Awesome, replace with "require twitter-bootstrap-static/sprites"
|
||||||
|
=require twitter-bootstrap-static/fontawesome
|
||||||
|
*/
|
||||||
33
app/assets/stylesheets/bootstrap_and_overrides.css.less
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
@import "twitter/bootstrap/bootstrap";
|
||||||
|
@import "twitter/bootstrap/responsive";
|
||||||
|
|
||||||
|
// Set the correct sprite paths
|
||||||
|
@iconSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings");
|
||||||
|
@iconWhiteSpritePath: asset-path("twitter/bootstrap/glyphicons-halflings-white");
|
||||||
|
|
||||||
|
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
|
||||||
|
// Note: If you use asset_path() here, your compiled bootstrap_and_overrides.css will not
|
||||||
|
// have the proper paths. So for now we use the absolute path.
|
||||||
|
@fontAwesomeEotPath: asset-path("fontawesome-webfont.eot");
|
||||||
|
@fontAwesomeEotPath_iefix: asset-path("fontawesome-webfont.eot#iefix");
|
||||||
|
@fontAwesomeWoffPath: asset-path("fontawesome-webfont.woff");
|
||||||
|
@fontAwesomeTtfPath: asset-path("fontawesome-webfont.ttf");
|
||||||
|
@fontAwesomeSvgPath: asset-path("fontawesome-webfont.svg");
|
||||||
|
|
||||||
|
// Font Awesome
|
||||||
|
@import "fontawesome";
|
||||||
|
|
||||||
|
// Glyphicons
|
||||||
|
//@import "twitter/bootstrap/sprites.less";
|
||||||
|
|
||||||
|
// Your custom LESS stylesheets goes here
|
||||||
|
//
|
||||||
|
// Since bootstrap was imported above you have access to its mixins which
|
||||||
|
// you may use and inherit here
|
||||||
|
//
|
||||||
|
// If you'd like to override bootstrap's own variables, you can do so here as well
|
||||||
|
// See http://twitter.github.com/bootstrap/customize.html#variables for their names and documentation
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// @linkColor: #ff0000;
|
||||||
|
@navbarBackground: #000000;
|
||||||
3
app/assets/stylesheets/home.css.scss
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Place all the styles related to the home controller here.
|
||||||
|
// They will automatically be included in application.css.
|
||||||
|
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||||
325
app/assets/stylesheets/jquery-ui-1.9.2.custom.css
vendored
Normal file
|
|
@ -0,0 +1,325 @@
|
||||||
|
/*! jQuery UI - v1.9.2 - 2012-12-28
|
||||||
|
* http://jqueryui.com
|
||||||
|
* Includes: jquery.ui.core.css, jquery.ui.datepicker.css
|
||||||
|
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande%2CLucida%20Sans%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
|
||||||
|
* Copyright (c) 2012 jQuery Foundation and other contributors Licensed MIT */
|
||||||
|
|
||||||
|
/* Layout helpers
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-helper-hidden { display: none; }
|
||||||
|
.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
|
||||||
|
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||||
|
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
|
||||||
|
.ui-helper-clearfix:after { clear: both; }
|
||||||
|
.ui-helper-clearfix { zoom: 1; }
|
||||||
|
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||||
|
|
||||||
|
|
||||||
|
/* Interaction Cues
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-disabled { cursor: default !important; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Icons
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* states and images */
|
||||||
|
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc visuals
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* Overlays */
|
||||||
|
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||||
|
.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; }
|
||||||
|
.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }
|
||||||
|
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }
|
||||||
|
.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }
|
||||||
|
.ui-datepicker .ui-datepicker-prev { left:2px; }
|
||||||
|
.ui-datepicker .ui-datepicker-next { right:2px; }
|
||||||
|
.ui-datepicker .ui-datepicker-prev-hover { left:1px; }
|
||||||
|
.ui-datepicker .ui-datepicker-next-hover { right:1px; }
|
||||||
|
.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }
|
||||||
|
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
|
||||||
|
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
|
||||||
|
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
|
||||||
|
.ui-datepicker select.ui-datepicker-month,
|
||||||
|
.ui-datepicker select.ui-datepicker-year { width: 49%;}
|
||||||
|
.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }
|
||||||
|
.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }
|
||||||
|
.ui-datepicker td { border: 0; padding: 1px; }
|
||||||
|
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }
|
||||||
|
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }
|
||||||
|
|
||||||
|
/* with multiple calendars */
|
||||||
|
.ui-datepicker.ui-datepicker-multi { width:auto; }
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group { float:left; }
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }
|
||||||
|
.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }
|
||||||
|
.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }
|
||||||
|
.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }
|
||||||
|
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }
|
||||||
|
.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }
|
||||||
|
.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; }
|
||||||
|
|
||||||
|
/* RTL support */
|
||||||
|
.ui-datepicker-rtl { direction: rtl; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group { float:right; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||||
|
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
|
||||||
|
|
||||||
|
/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
|
||||||
|
.ui-datepicker-cover {
|
||||||
|
position: absolute; /*must have*/
|
||||||
|
z-index: -1; /*must have*/
|
||||||
|
filter: mask(); /*must have*/
|
||||||
|
top: -4px; /*must have*/
|
||||||
|
left: -4px; /*must have*/
|
||||||
|
width: 200px; /*must have*/
|
||||||
|
height: 200px; /*must have*/
|
||||||
|
}
|
||||||
|
/* Component containers
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-widget { font-family: Lucida Grande,Lucida Sans,Arial,sans-serif; font-size: 1.1em; }
|
||||||
|
.ui-widget .ui-widget { font-size: 1em; }
|
||||||
|
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande,Lucida Sans,Arial,sans-serif; font-size: 1em; }
|
||||||
|
.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
|
||||||
|
.ui-widget-content a { color: #222222; }
|
||||||
|
.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
|
||||||
|
.ui-widget-header a { color: #ffffff; }
|
||||||
|
|
||||||
|
/* Interaction states
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; }
|
||||||
|
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; }
|
||||||
|
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; }
|
||||||
|
.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #1d5987; text-decoration: none; }
|
||||||
|
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; }
|
||||||
|
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; }
|
||||||
|
|
||||||
|
/* Interaction Cues
|
||||||
|
----------------------------------*/
|
||||||
|
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; }
|
||||||
|
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
|
||||||
|
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
|
||||||
|
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
|
||||||
|
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
|
||||||
|
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
|
||||||
|
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
|
||||||
|
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
|
||||||
|
.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */
|
||||||
|
|
||||||
|
/* Icons
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* states and images */
|
||||||
|
.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); }
|
||||||
|
.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); }
|
||||||
|
.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
|
||||||
|
.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); }
|
||||||
|
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); }
|
||||||
|
.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); }
|
||||||
|
.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
|
||||||
|
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
|
||||||
|
|
||||||
|
/* positioning */
|
||||||
|
.ui-icon-carat-1-n { background-position: 0 0; }
|
||||||
|
.ui-icon-carat-1-ne { background-position: -16px 0; }
|
||||||
|
.ui-icon-carat-1-e { background-position: -32px 0; }
|
||||||
|
.ui-icon-carat-1-se { background-position: -48px 0; }
|
||||||
|
.ui-icon-carat-1-s { background-position: -64px 0; }
|
||||||
|
.ui-icon-carat-1-sw { background-position: -80px 0; }
|
||||||
|
.ui-icon-carat-1-w { background-position: -96px 0; }
|
||||||
|
.ui-icon-carat-1-nw { background-position: -112px 0; }
|
||||||
|
.ui-icon-carat-2-n-s { background-position: -128px 0; }
|
||||||
|
.ui-icon-carat-2-e-w { background-position: -144px 0; }
|
||||||
|
.ui-icon-triangle-1-n { background-position: 0 -16px; }
|
||||||
|
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
|
||||||
|
.ui-icon-triangle-1-e { background-position: -32px -16px; }
|
||||||
|
.ui-icon-triangle-1-se { background-position: -48px -16px; }
|
||||||
|
.ui-icon-triangle-1-s { background-position: -64px -16px; }
|
||||||
|
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
|
||||||
|
.ui-icon-triangle-1-w { background-position: -96px -16px; }
|
||||||
|
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
|
||||||
|
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
|
||||||
|
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
|
||||||
|
.ui-icon-arrow-1-n { background-position: 0 -32px; }
|
||||||
|
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
|
||||||
|
.ui-icon-arrow-1-e { background-position: -32px -32px; }
|
||||||
|
.ui-icon-arrow-1-se { background-position: -48px -32px; }
|
||||||
|
.ui-icon-arrow-1-s { background-position: -64px -32px; }
|
||||||
|
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
|
||||||
|
.ui-icon-arrow-1-w { background-position: -96px -32px; }
|
||||||
|
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
|
||||||
|
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
|
||||||
|
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
|
||||||
|
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
|
||||||
|
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
|
||||||
|
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
|
||||||
|
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
|
||||||
|
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
|
||||||
|
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
|
||||||
|
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
|
||||||
|
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
|
||||||
|
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
|
||||||
|
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
|
||||||
|
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
|
||||||
|
.ui-icon-arrow-4 { background-position: 0 -80px; }
|
||||||
|
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
|
||||||
|
.ui-icon-extlink { background-position: -32px -80px; }
|
||||||
|
.ui-icon-newwin { background-position: -48px -80px; }
|
||||||
|
.ui-icon-refresh { background-position: -64px -80px; }
|
||||||
|
.ui-icon-shuffle { background-position: -80px -80px; }
|
||||||
|
.ui-icon-transfer-e-w { background-position: -96px -80px; }
|
||||||
|
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
|
||||||
|
.ui-icon-folder-collapsed { background-position: 0 -96px; }
|
||||||
|
.ui-icon-folder-open { background-position: -16px -96px; }
|
||||||
|
.ui-icon-document { background-position: -32px -96px; }
|
||||||
|
.ui-icon-document-b { background-position: -48px -96px; }
|
||||||
|
.ui-icon-note { background-position: -64px -96px; }
|
||||||
|
.ui-icon-mail-closed { background-position: -80px -96px; }
|
||||||
|
.ui-icon-mail-open { background-position: -96px -96px; }
|
||||||
|
.ui-icon-suitcase { background-position: -112px -96px; }
|
||||||
|
.ui-icon-comment { background-position: -128px -96px; }
|
||||||
|
.ui-icon-person { background-position: -144px -96px; }
|
||||||
|
.ui-icon-print { background-position: -160px -96px; }
|
||||||
|
.ui-icon-trash { background-position: -176px -96px; }
|
||||||
|
.ui-icon-locked { background-position: -192px -96px; }
|
||||||
|
.ui-icon-unlocked { background-position: -208px -96px; }
|
||||||
|
.ui-icon-bookmark { background-position: -224px -96px; }
|
||||||
|
.ui-icon-tag { background-position: -240px -96px; }
|
||||||
|
.ui-icon-home { background-position: 0 -112px; }
|
||||||
|
.ui-icon-flag { background-position: -16px -112px; }
|
||||||
|
.ui-icon-calendar { background-position: -32px -112px; }
|
||||||
|
.ui-icon-cart { background-position: -48px -112px; }
|
||||||
|
.ui-icon-pencil { background-position: -64px -112px; }
|
||||||
|
.ui-icon-clock { background-position: -80px -112px; }
|
||||||
|
.ui-icon-disk { background-position: -96px -112px; }
|
||||||
|
.ui-icon-calculator { background-position: -112px -112px; }
|
||||||
|
.ui-icon-zoomin { background-position: -128px -112px; }
|
||||||
|
.ui-icon-zoomout { background-position: -144px -112px; }
|
||||||
|
.ui-icon-search { background-position: -160px -112px; }
|
||||||
|
.ui-icon-wrench { background-position: -176px -112px; }
|
||||||
|
.ui-icon-gear { background-position: -192px -112px; }
|
||||||
|
.ui-icon-heart { background-position: -208px -112px; }
|
||||||
|
.ui-icon-star { background-position: -224px -112px; }
|
||||||
|
.ui-icon-link { background-position: -240px -112px; }
|
||||||
|
.ui-icon-cancel { background-position: 0 -128px; }
|
||||||
|
.ui-icon-plus { background-position: -16px -128px; }
|
||||||
|
.ui-icon-plusthick { background-position: -32px -128px; }
|
||||||
|
.ui-icon-minus { background-position: -48px -128px; }
|
||||||
|
.ui-icon-minusthick { background-position: -64px -128px; }
|
||||||
|
.ui-icon-close { background-position: -80px -128px; }
|
||||||
|
.ui-icon-closethick { background-position: -96px -128px; }
|
||||||
|
.ui-icon-key { background-position: -112px -128px; }
|
||||||
|
.ui-icon-lightbulb { background-position: -128px -128px; }
|
||||||
|
.ui-icon-scissors { background-position: -144px -128px; }
|
||||||
|
.ui-icon-clipboard { background-position: -160px -128px; }
|
||||||
|
.ui-icon-copy { background-position: -176px -128px; }
|
||||||
|
.ui-icon-contact { background-position: -192px -128px; }
|
||||||
|
.ui-icon-image { background-position: -208px -128px; }
|
||||||
|
.ui-icon-video { background-position: -224px -128px; }
|
||||||
|
.ui-icon-script { background-position: -240px -128px; }
|
||||||
|
.ui-icon-alert { background-position: 0 -144px; }
|
||||||
|
.ui-icon-info { background-position: -16px -144px; }
|
||||||
|
.ui-icon-notice { background-position: -32px -144px; }
|
||||||
|
.ui-icon-help { background-position: -48px -144px; }
|
||||||
|
.ui-icon-check { background-position: -64px -144px; }
|
||||||
|
.ui-icon-bullet { background-position: -80px -144px; }
|
||||||
|
.ui-icon-radio-on { background-position: -96px -144px; }
|
||||||
|
.ui-icon-radio-off { background-position: -112px -144px; }
|
||||||
|
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||||
|
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||||
|
.ui-icon-play { background-position: 0 -160px; }
|
||||||
|
.ui-icon-pause { background-position: -16px -160px; }
|
||||||
|
.ui-icon-seek-next { background-position: -32px -160px; }
|
||||||
|
.ui-icon-seek-prev { background-position: -48px -160px; }
|
||||||
|
.ui-icon-seek-end { background-position: -64px -160px; }
|
||||||
|
.ui-icon-seek-start { background-position: -80px -160px; }
|
||||||
|
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
|
||||||
|
.ui-icon-seek-first { background-position: -80px -160px; }
|
||||||
|
.ui-icon-stop { background-position: -96px -160px; }
|
||||||
|
.ui-icon-eject { background-position: -112px -160px; }
|
||||||
|
.ui-icon-volume-off { background-position: -128px -160px; }
|
||||||
|
.ui-icon-volume-on { background-position: -144px -160px; }
|
||||||
|
.ui-icon-power { background-position: 0 -176px; }
|
||||||
|
.ui-icon-signal-diag { background-position: -16px -176px; }
|
||||||
|
.ui-icon-signal { background-position: -32px -176px; }
|
||||||
|
.ui-icon-battery-0 { background-position: -48px -176px; }
|
||||||
|
.ui-icon-battery-1 { background-position: -64px -176px; }
|
||||||
|
.ui-icon-battery-2 { background-position: -80px -176px; }
|
||||||
|
.ui-icon-battery-3 { background-position: -96px -176px; }
|
||||||
|
.ui-icon-circle-plus { background-position: 0 -192px; }
|
||||||
|
.ui-icon-circle-minus { background-position: -16px -192px; }
|
||||||
|
.ui-icon-circle-close { background-position: -32px -192px; }
|
||||||
|
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
|
||||||
|
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
|
||||||
|
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
|
||||||
|
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
|
||||||
|
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
|
||||||
|
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
|
||||||
|
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
|
||||||
|
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
|
||||||
|
.ui-icon-circle-zoomin { background-position: -176px -192px; }
|
||||||
|
.ui-icon-circle-zoomout { background-position: -192px -192px; }
|
||||||
|
.ui-icon-circle-check { background-position: -208px -192px; }
|
||||||
|
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
|
||||||
|
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
|
||||||
|
.ui-icon-circlesmall-close { background-position: -32px -208px; }
|
||||||
|
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
|
||||||
|
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
|
||||||
|
.ui-icon-squaresmall-close { background-position: -80px -208px; }
|
||||||
|
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
|
||||||
|
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
|
||||||
|
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
|
||||||
|
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
|
||||||
|
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
|
||||||
|
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc visuals
|
||||||
|
----------------------------------*/
|
||||||
|
|
||||||
|
/* Corner radius */
|
||||||
|
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -khtml-border-top-left-radius: 5px; border-top-left-radius: 5px; }
|
||||||
|
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -khtml-border-top-right-radius: 5px; border-top-right-radius: 5px; }
|
||||||
|
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -khtml-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
|
||||||
|
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; -khtml-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
|
||||||
|
|
||||||
|
/* Overlays */
|
||||||
|
.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); }
|
||||||
|
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }
|
||||||
102
app/assets/stylesheets/osem.css
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
html, body,.container,.content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#push,
|
||||||
|
#footer {
|
||||||
|
height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container, .content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#inner-content {
|
||||||
|
padding-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrap {
|
||||||
|
min-height: 100%;
|
||||||
|
height: auto !important;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto -60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
position: relative;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
.navbar-inner {
|
||||||
|
background: #299a0b; /* Old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #299a0b 0%, #299a0b 100%); /* FF3.6+ */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#299a0b), color-stop(100%,#299a0b)); /* Chrome,Safari4+ */
|
||||||
|
background: -webkit-linear-gradient(top, #299a0b 0%,#299a0b 100%); /* Chrome10+,Safari5.1+ */
|
||||||
|
background: -o-linear-gradient(top, #299a0b 0%,#299a0b 100%); /* Opera 11.10+ */
|
||||||
|
background: -ms-linear-gradient(top, #299a0b 0%,#299a0b 100%); /* IE10+ */
|
||||||
|
background: linear-gradient(to bottom, #299a0b 0%,#299a0b 100%); /* W3C */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#299a0b', endColorstr='#299a0b',GradientType=0 ); /* IE6-9 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav .active > a, .navbar .nav .active > a:hover {
|
||||||
|
background-color: #DFE0DF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .divider-vertical {
|
||||||
|
background-color: #b4e391;
|
||||||
|
border-right: 1px solid #eab92d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-fixed-top .brand {
|
||||||
|
color: #ffffff;
|
||||||
|
text-shadow:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav > li > a {
|
||||||
|
float: none;
|
||||||
|
padding: 10px 15px 10px;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
margin:0 auto;
|
||||||
|
float:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-text {
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
||||||
|
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
||||||
|
box-sizing: border-box; /* Opera/IE 8+ */
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainbutton {
|
||||||
|
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #9dce2c), color-stop(1, #8cb82b) );
|
||||||
|
background:-moz-linear-gradient( center top, #9dce2c 5%, #8cb82b 100% );
|
||||||
|
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9dce2c', endColorstr='#8cb82b');
|
||||||
|
background-color:#9dce2c;
|
||||||
|
-moz-border-radius:6px;
|
||||||
|
-webkit-border-radius:6px;
|
||||||
|
border-radius:6px;
|
||||||
|
border:1px solid #83c41a;
|
||||||
|
display:inline-block;
|
||||||
|
color:#ffffff;
|
||||||
|
font-family:Arial;
|
||||||
|
font-size:20px;
|
||||||
|
font-weight:bold;
|
||||||
|
padding:6px 24px;
|
||||||
|
text-decoration:none;
|
||||||
|
text-shadow:1px 1px 9px #689324;
|
||||||
|
}.mainbutton:hover {
|
||||||
|
background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #8cb82b), color-stop(1, #9dce2c) );
|
||||||
|
background:-moz-linear-gradient( center top, #8cb82b 5%, #9dce2c 100% );
|
||||||
|
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#8cb82b', endColorstr='#9dce2c');
|
||||||
|
background-color:#8cb82b;
|
||||||
|
}.mainbutton:active {
|
||||||
|
position:relative;
|
||||||
|
top:1px;
|
||||||
|
}
|
||||||
28
app/controllers/admin/callforpapers_controller.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class Admin::CallforpapersController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def show
|
||||||
|
@cfp = @conference.call_for_papers
|
||||||
|
if @cfp.nil?
|
||||||
|
@cfp = CallForPapers.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@cfp = @conference.call_for_papers
|
||||||
|
@cfp.update_attributes(params[:call_for_papers])
|
||||||
|
redirect_to(admin_conference_cfp_info_path(:id => @conference.short_title), :notice => 'Call for Papers was successfully updated.')
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@cfp = CallForPapers.new(params[:call_for_papers])
|
||||||
|
@conference.call_for_papers = @cfp
|
||||||
|
if @cfp.save
|
||||||
|
redirect_to(admin_conference_cfp_info_path(:id => @conference.short_title), :notice => 'Call for Papers was successfully updated.')
|
||||||
|
else
|
||||||
|
redirect_to(admin_conference_cfp_info_path(:id => @conference.short_title), :error => 'Call for Papers failed.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
36
app/controllers/admin/conference_controller.rb
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
class Admin::ConferenceController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@conferences = Conference.all
|
||||||
|
if @conferences.count == 0
|
||||||
|
redirect_to new_admin_conference_path
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@conference = Conference.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@conference = Conference.new(params[:conference])
|
||||||
|
if @conference.save
|
||||||
|
redirect_to(admin_conference_path(:id => @conference.short_title), :notice => 'Conference was successfully created.')
|
||||||
|
else
|
||||||
|
render :action => "new"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@conference = Conference.find_all_by_short_title(params[:id]).first
|
||||||
|
@conference.update_attributes(params[:conference])
|
||||||
|
flash[:notice] = "Updated Conference"
|
||||||
|
redirect_to(admin_conference_path(:id => @conference.short_title), :notice => 'Conference was successfully updated.')
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@conference = Conference.find_all_by_short_title(params[:id]).first
|
||||||
|
end
|
||||||
|
end
|
||||||
41
app/controllers/admin/events_controller.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
class Admin::EventsController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@events = @conference.events
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@event = @conference.events.find(params[:id])
|
||||||
|
@comments = @event.root_comments
|
||||||
|
@comment_count = @event.comment_threads.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@event_types = @conference.event_types
|
||||||
|
@event = Event.find_by_id(params[:id])
|
||||||
|
@person = @event.submitter
|
||||||
|
@url = edit_admin_conference_event_path(@conference.short_title, @event)
|
||||||
|
end
|
||||||
|
|
||||||
|
def comment
|
||||||
|
event = @conference.events.find_by_id(params[:id])
|
||||||
|
comment = Comment.build_from(event, current_user.id, params[:comment])
|
||||||
|
comment.save!
|
||||||
|
if !params[:parent].nil?
|
||||||
|
comment.move_to_child_of(params[:parent])
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to admin_conference_event_path(:conference_id => @conference.short_title, :id => params[:id])
|
||||||
|
end
|
||||||
|
def create
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_state
|
||||||
|
event = Event.find(params[:id])
|
||||||
|
event.send(:"#{params[:transition]}!", :send_mail => params[:send_mail])
|
||||||
|
redirect_to(admin_conference_events_path(:conference_id => @conference.short_title), :notice => "Updated state")
|
||||||
|
end
|
||||||
|
end
|
||||||
17
app/controllers/admin/eventtype_controller.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
class Admin::EventtypeController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def show
|
||||||
|
render :event_type_list
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
begin
|
||||||
|
@conference.update_attributes!(params[:conference])
|
||||||
|
redirect_to(admin_conference_eventtype_list_path(:conference_id => @conference.short_title), :notice => 'Event types were successfully updated.')
|
||||||
|
rescue Exception => e
|
||||||
|
redirect_to(admin_conference_eventtype_list_path(:conference_id => @conference.short_title), :alert => 'Event types update failed: #{e.message}')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
24
app/controllers/admin/people_controller.rb
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
class Admin::PeopleController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@people = Person.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@person = Person.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
16
app/controllers/admin/registrations_controller.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
class Admin::RegistrationsController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def show
|
||||||
|
session[:return_to] ||= request.referer
|
||||||
|
@pdf_filename = "#{@conference.title}.pdf"
|
||||||
|
@registrations = @conference.registrations.all(:joins => :person,
|
||||||
|
:order => "people.last_name ASC",
|
||||||
|
:select => "registrations.*,
|
||||||
|
people.last_name AS last_name,
|
||||||
|
people.first_name AS first_name,
|
||||||
|
people.public_name AS public_name,
|
||||||
|
people.email AS email")
|
||||||
|
end
|
||||||
|
end
|
||||||
18
app/controllers/admin/rooms_controller.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Admin::RoomsController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def show
|
||||||
|
render :rooms_list
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @conference.update_attributes(params[:conference])
|
||||||
|
redirect_to(admin_conference_rooms_list_path(:conference_id => @conference.short_title), :notice => 'Rooms were successfully updated.')
|
||||||
|
else
|
||||||
|
redirect_to(admin_conference_rooms_list_path(:conference_id => @conference.short_title), :notice => 'Room update failed.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
18
app/controllers/admin/tracks_controller.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Admin::TracksController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def show
|
||||||
|
render :tracks_list
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @conference.update_attributes(params[:conference])
|
||||||
|
redirect_to(admin_conference_tracks_list_path(:conference_id => @conference.short_title), :notice => 'Tracks were successfully updated.')
|
||||||
|
else
|
||||||
|
redirect_to(admin_conference_tracks_list_path(:conference_id => @conference.short_title), :notice => 'Tracks update failed.')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
20
app/controllers/admin/users_controller.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Admin::UsersController < ApplicationController
|
||||||
|
before_filter :verify_admin
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def index
|
||||||
|
@users = User.all(:joins => :person,
|
||||||
|
:order => "people.last_name ASC",
|
||||||
|
:select => "users.*,
|
||||||
|
people.last_name AS last_name,
|
||||||
|
people.first_name AS first_name,
|
||||||
|
people.public_name AS public_name,
|
||||||
|
people.email AS email")
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
user = User.find(params[:id])
|
||||||
|
user.update_attributes!(params[:user])
|
||||||
|
redirect_to admin_users_path, :notice => "Updated #{user.email}"
|
||||||
|
end
|
||||||
|
end
|
||||||
24
app/controllers/admin/venue_controller.rb
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
class Admin::VenueController < ApplicationController
|
||||||
|
before_filter :verify_organizer
|
||||||
|
layout "admin"
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@venue = @conference.venue
|
||||||
|
venue_params = params[:venue]
|
||||||
|
@venue.name = venue_params[:name]
|
||||||
|
@venue.address= venue_params[:address]
|
||||||
|
@venue.website = venue_params[:website]
|
||||||
|
@venue.description = venue_params[:description]
|
||||||
|
@venue.save
|
||||||
|
redirect_to(admin_conference_venue_info_path(:conference_id => @conference.short_title), :notice => 'Venue was successfully updated.')
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@venue = @conference.venue
|
||||||
|
render :venue_info
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
42
app/controllers/application_controller.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
class ApplicationController < ActionController::Base
|
||||||
|
include ApplicationHelper
|
||||||
|
|
||||||
|
protect_from_forgery
|
||||||
|
|
||||||
|
def verify_user
|
||||||
|
:authenticate_user!
|
||||||
|
|
||||||
|
if (current_user.nil?)
|
||||||
|
redirect_to '/accounts/sign_in'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@conference = Conference.find_all_by_short_title(params[:conference_id]).first
|
||||||
|
end
|
||||||
|
|
||||||
|
def organizer_or_admin?
|
||||||
|
has_role?(current_user, 'admin') || has_role?(current_user, 'organizer')
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_organizer
|
||||||
|
verify_user
|
||||||
|
|
||||||
|
## Todo simplify this
|
||||||
|
redirect_to '/' unless has_role?(current_user, 'admin') || has_role?(current_user, 'organizer')
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_admin
|
||||||
|
verify_user
|
||||||
|
|
||||||
|
redirect_to '/' unless has_role?(current_user, 'admin')
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_ability
|
||||||
|
@current_ability ||= AdminAbility.new(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue_from CanCan::AccessDenied do |exception|
|
||||||
|
Rails.logger.debug("Access denied!")
|
||||||
|
redirect_to '/', :alert => exception.message
|
||||||
|
end
|
||||||
|
end
|
||||||
51
app/controllers/conference_registration_controller.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
class ConferenceRegistrationController < ApplicationController
|
||||||
|
before_filter :verify_user
|
||||||
|
|
||||||
|
def register
|
||||||
|
# TODO Figure out how to change the route's id from :id to :conference_id
|
||||||
|
@conference = Conference.find_all_by_short_title(params[:id]).first
|
||||||
|
@person = current_user.person
|
||||||
|
@registration = @person.registrations.where(:conference_id => @conference.id).first
|
||||||
|
@registered = true
|
||||||
|
if @registration.nil?
|
||||||
|
@registered = false
|
||||||
|
@registration = @person.registrations.new(:conference_id => @conference.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
conference = Conference.find_all_by_short_title(params[:id]).first
|
||||||
|
person = current_user.person
|
||||||
|
registration = person.registrations.where(:conference_id => conference.id).first
|
||||||
|
update_registration = true
|
||||||
|
begin
|
||||||
|
if registration.nil?
|
||||||
|
update_registration = false
|
||||||
|
person.update_attributes(params[:registration][:person_attributes])
|
||||||
|
params[:registration].delete :person_attributes
|
||||||
|
registration = person.registrations.new(params[:registration])
|
||||||
|
registration.conference_id = conference.id
|
||||||
|
registration.save!
|
||||||
|
else
|
||||||
|
registration.update_attributes!(params[:registration])
|
||||||
|
end
|
||||||
|
rescue Exception => e
|
||||||
|
redirect_to(register_conference_path(:id => conference.short_title), :alert => 'Registration failed:' + e.message)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_message = "You are now registered."
|
||||||
|
if update_registration
|
||||||
|
redirect_message = "Registration updated."
|
||||||
|
end
|
||||||
|
redirect_to(register_conference_path(:id => conference.short_title), :notice => redirect_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unregister
|
||||||
|
conference = Conference.find_all_by_short_title(params[:id]).first
|
||||||
|
person = current_user.person
|
||||||
|
registration = person.registrations.where(:conference_id => conference.id).first
|
||||||
|
registration.destroy
|
||||||
|
redirect_to :root
|
||||||
|
end
|
||||||
|
end
|
||||||
97
app/controllers/event_attachments_controller.rb
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
class EventAttachmentsController < ApplicationController
|
||||||
|
before_filter :verify_user
|
||||||
|
skip_before_filter :verify_user, :only => [:show]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@proposal = current_user.person.events.find(params[:proposal_id])
|
||||||
|
@uploads = @proposal.event_attachments
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html # index.html.erb
|
||||||
|
format.json { render json: @uploads.map{|upload| upload.to_jq_upload } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
upload = EventAttachment.find(params[:id])
|
||||||
|
if upload.public?
|
||||||
|
send_file upload.attachment.path
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if current_user.nil?
|
||||||
|
verify_user
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if organizer_or_admin? || current_user.person == upload.event.submitter
|
||||||
|
send_file upload.attachment.path
|
||||||
|
else
|
||||||
|
raise ActionController::RoutingError.new('Not Found')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@upload = EventAttachment.new
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html # new.html.erb
|
||||||
|
format.json { render json: @upload }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@upload = EventAttachment.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
params[:event_attachment][:title] = params[:title][0]
|
||||||
|
params[:event_attachment][:public] = false
|
||||||
|
params[:event_attachment][:event_id] = params[:proposal_id]
|
||||||
|
|
||||||
|
if params.has_key?(:public)
|
||||||
|
params[:event_attachment][:public] = true
|
||||||
|
end
|
||||||
|
@upload = EventAttachment.new(params[:event_attachment])
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @upload.save
|
||||||
|
format.html {
|
||||||
|
render :json => [@upload.to_jq_upload].to_json,
|
||||||
|
:content_type => 'text/html',
|
||||||
|
:layout => false
|
||||||
|
}
|
||||||
|
format.json { render json: [@upload.to_jq_upload].to_json, status: :created,
|
||||||
|
location: conference_proposal_event_attachment_path(@upload.event.conference.short_title, @upload.event, @upload) }
|
||||||
|
else
|
||||||
|
format.html { render action: "new" }
|
||||||
|
format.json { render json: @upload.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@upload = EventAttachment.find(params[:proposal_id])
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @upload.update_attributes(params[:upload])
|
||||||
|
format.html { redirect_to @upload, notice: 'Upload was successfully updated.' }
|
||||||
|
format.json { head :no_content }
|
||||||
|
else
|
||||||
|
format.html { render action: "edit" }
|
||||||
|
format.json { render json: @upload.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@proposal = current_user.person.events.find(params[:proposal_id])
|
||||||
|
@upload = @proposal.event_attachments.find(params[:id])
|
||||||
|
@upload.destroy
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to uploads_url }
|
||||||
|
format.json { head :no_content }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
7
app/controllers/home_controller.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
class HomeController < ApplicationController
|
||||||
|
def index
|
||||||
|
@today = Date.current
|
||||||
|
@conferences = Conference.where("start_date >= ?", @today)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
97
app/controllers/proposal_controller.rb
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
class ProposalController < ApplicationController
|
||||||
|
before_filter :verify_user
|
||||||
|
|
||||||
|
def index
|
||||||
|
@person = current_user.person
|
||||||
|
@events = @person.proposals @conference
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
current_user.person.withdraw_proposal(params[:id])
|
||||||
|
redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :alert => 'Proposal withdrawn.')
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@url = conference_proposal_index_path(@conference.short_title)
|
||||||
|
@event = Event.new
|
||||||
|
@event_types = @conference.event_types
|
||||||
|
@person = current_user.person
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@url = conference_proposal_path(@conference.short_title, params[:id])
|
||||||
|
@person = current_user.person
|
||||||
|
@event_types = @conference.event_types
|
||||||
|
@event = @person.events.find_by_id(params[:id])
|
||||||
|
@attachments = @event.event_attachments
|
||||||
|
|
||||||
|
if @event.nil?
|
||||||
|
redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :alert => 'Invalid proposal.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
person = current_user.person
|
||||||
|
session[:return_to] ||= request.referer
|
||||||
|
submitter = params[:person]
|
||||||
|
|
||||||
|
params[:event].delete :people_attributes
|
||||||
|
params[:event].delete :person
|
||||||
|
|
||||||
|
if submitter[:public_name] != person.public_name || submitter[:biography] != person.biography
|
||||||
|
person.update_attributes(submitter)
|
||||||
|
end
|
||||||
|
|
||||||
|
event = Event.find_by_id(params[:id])
|
||||||
|
|
||||||
|
if event.update_attributes!(params[:event])
|
||||||
|
redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :notice => "'#{event.title}' was successfully updated.")
|
||||||
|
else
|
||||||
|
redirect_to session[:return_to], :alert => "'#{event.title}' was NOT updated!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
person = current_user.person
|
||||||
|
session[:return_to] ||= request.referer
|
||||||
|
|
||||||
|
event_params = params[:event]
|
||||||
|
submitter = params[:person]
|
||||||
|
params[:event].delete :person
|
||||||
|
|
||||||
|
# First, update the submitter's info, if they've changed anything
|
||||||
|
if submitter[:public_name] != person.public_name || submitter[:biography] != person.biography
|
||||||
|
person.update_attributes(submitter)
|
||||||
|
end
|
||||||
|
|
||||||
|
@event = Event.new(event_params)
|
||||||
|
@event.conference = @conference
|
||||||
|
@event.event_people.new(:person => person,
|
||||||
|
:event_role => "submitter")
|
||||||
|
@event.event_people.new(:person => person,
|
||||||
|
:event_role => "speaker")
|
||||||
|
|
||||||
|
begin
|
||||||
|
@event.save!
|
||||||
|
rescue Exception => e
|
||||||
|
@url = conference_proposal_index_path(@conference.short_title)
|
||||||
|
@event_types = @conference.event_types
|
||||||
|
@person = current_user.person
|
||||||
|
|
||||||
|
flash[:error] = "Could not submit proposal: #{e.message}"
|
||||||
|
render :action => 'new'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
registration = person.registrations.where(:conference_id => @conference.id).first
|
||||||
|
if registration.nil?
|
||||||
|
redirect_to(register_conference_path(@conference.short_title), :notice => 'Event was successfully submitted. You probably want to register for the conference now!')
|
||||||
|
else
|
||||||
|
redirect_to(conference_proposal_index_path(:conference_id => @conference.short_title), :notice => 'Event was successfully submitted.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
52
app/controllers/registrations_controller.rb
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
class RegistrationsController < Devise::RegistrationsController
|
||||||
|
def update
|
||||||
|
@user = User.find(current_user.id)
|
||||||
|
email_changed = false
|
||||||
|
|
||||||
|
if !params[:user][:email].nil?
|
||||||
|
if @user.email != params[:user][:email]
|
||||||
|
email_changed = true
|
||||||
|
else
|
||||||
|
params[:user].delete :email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
password_changed = false
|
||||||
|
if !params[:user][:password].nil?
|
||||||
|
if !params[:user][:password].empty?
|
||||||
|
password_changed = true
|
||||||
|
else
|
||||||
|
params[:user].delete :password
|
||||||
|
params[:user].delete :password_confirmation
|
||||||
|
params[:user].delete :current_password
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
successfully_updated = if email_changed or password_changed
|
||||||
|
@user.update_with_password(params[:user])
|
||||||
|
else
|
||||||
|
@user.update_without_password(params[:user])
|
||||||
|
end
|
||||||
|
|
||||||
|
if successfully_updated
|
||||||
|
set_flash_message :notice, :updated
|
||||||
|
# Sign in the user bypassing validation in case his password changed
|
||||||
|
sign_in @user, :bypass => true
|
||||||
|
redirect_to after_update_path_for(@user)
|
||||||
|
else
|
||||||
|
render "edit"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def after_update_path_for(resource)
|
||||||
|
edit_user_registration_path(resource)
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_sign_up_path_for(resource)
|
||||||
|
edit_user_registration_path(resource)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
2
app/helpers/admin/call_for_papers_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Admin::CallForPapersHelper
|
||||||
|
end
|
||||||
2
app/helpers/admin/conference_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Admin::ConferenceHelper
|
||||||
|
end
|
||||||
2
app/helpers/admin/people_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Admin::PeopleHelper
|
||||||
|
end
|
||||||
2
app/helpers/admin/users_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Admin::UsersHelper
|
||||||
|
end
|
||||||
2
app/helpers/admin/venue_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module Admin::VenueHelper
|
||||||
|
end
|
||||||
43
app/helpers/application_helper.rb
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
module ApplicationHelper
|
||||||
|
|
||||||
|
def add_association_link(association_name, form_builder, div_class, html_options = {})
|
||||||
|
link_to_add_association "Add " + association_name.to_s.singularize, form_builder, div_class, html_options.merge(:class => "assoc btn btn-success")
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_association_link(association_name, form_builder)
|
||||||
|
link_to_remove_association("Remove " + association_name.to_s.singularize, form_builder, :class => "assoc btn btn-danger") + tag(:hr)
|
||||||
|
end
|
||||||
|
|
||||||
|
def dynamic_association(association_name, title, form_builder, options = {})
|
||||||
|
render "shared/dynamic_association", :association_name => association_name, :title => title, :f => form_builder, :hint => options[:hint]
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_role?(current_user, role)
|
||||||
|
return !!current_user.role?(role.to_s.camelize)
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO Output better html
|
||||||
|
def format_comments(comment, padding = 0)
|
||||||
|
result = ""
|
||||||
|
result += "<div style='padding-left:#{padding}px'>"
|
||||||
|
result += "<div class='well'>"
|
||||||
|
result += "<b>#{comment.user.person.public_name}</b> <i>#{comment.created_at}</i><br><br>"
|
||||||
|
result += comment.body
|
||||||
|
result += "<br><div><a href='#' class='pull-right comment-reply-link'>Reply</a><br><br>"
|
||||||
|
result += "<div class='comment-reply'>"
|
||||||
|
result += "<form method='post' action='#{comment_admin_conference_event_path(@conference.short_title, comment.commentable_id)}'>"
|
||||||
|
result += "<input type=hidden name=parent value='#{comment.id}'/>"
|
||||||
|
result += "<input name='authenticity_token' type='hidden' value='#{form_authenticity_token}' />"
|
||||||
|
result += "<textarea name='comment'></textarea>"
|
||||||
|
result += "<button class='btn btn-primary pull-right' name='button' type='submit'>Add Reply</button>"
|
||||||
|
result += "</form></div></div>"
|
||||||
|
result += "</div>"
|
||||||
|
#result += edit_admin_conference_event_path(@conference.short_title, @event)
|
||||||
|
comment.children.each do |child|
|
||||||
|
result += format_comments(child, 50)
|
||||||
|
result += "</div>"
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
2
app/helpers/home_helper.rb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
module HomeHelper
|
||||||
|
end
|
||||||
0
app/mailers/.gitkeep
Normal file
0
app/models/.gitkeep
Normal file
28
app/models/ability.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class Ability
|
||||||
|
include CanCan::Ability
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
# Define abilities for the passed in user here. For example:
|
||||||
|
#
|
||||||
|
# user ||= User.new # guest user (not logged in)
|
||||||
|
# if user.admin?
|
||||||
|
# can :manage, :all
|
||||||
|
# else
|
||||||
|
# can :read, :all
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# The first argument to `can` is the action you are giving the user permission to do.
|
||||||
|
# If you pass :manage it will apply to every action. Other common actions here are
|
||||||
|
# :read, :create, :update and :destroy.
|
||||||
|
#
|
||||||
|
# The second argument is the resource the user can perform the action on. If you pass
|
||||||
|
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
|
||||||
|
#
|
||||||
|
# The third argument is an optional hash of conditions to further filter the objects.
|
||||||
|
# For example, here the user can only update published articles.
|
||||||
|
#
|
||||||
|
# can :update, Article, :published => true
|
||||||
|
#
|
||||||
|
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
|
||||||
|
end
|
||||||
|
end
|
||||||
17
app/models/admin_ability.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
class AdminAbility
|
||||||
|
include CanCan::Ability
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
@user = user || User.new # for guest
|
||||||
|
@user.get_roles.each { |role| send(role.name.downcase) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def organizer
|
||||||
|
can :manage, Event
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin
|
||||||
|
organizer
|
||||||
|
can :manage, :all
|
||||||
|
end
|
||||||
|
end
|
||||||
7
app/models/call_for_papers.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
class CallForPapers < ActiveRecord::Base
|
||||||
|
attr_accessible :start_date, :end_date, :hard_deadline, :description
|
||||||
|
belongs_to :conference
|
||||||
|
|
||||||
|
validates_presence_of :start_date, :end_date, :hard_deadline
|
||||||
|
|
||||||
|
end
|
||||||
48
app/models/comment.rb
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
class Comment < ActiveRecord::Base
|
||||||
|
acts_as_nested_set :scope => [:commentable_id, :commentable_type]
|
||||||
|
attr_accessible :commentable, :body, :user_id
|
||||||
|
validates_presence_of :body
|
||||||
|
validates_presence_of :user
|
||||||
|
|
||||||
|
# NOTE: install the acts_as_votable plugin if you
|
||||||
|
# want user to vote on the quality of comments.
|
||||||
|
#acts_as_votable
|
||||||
|
|
||||||
|
belongs_to :commentable, :polymorphic => true
|
||||||
|
|
||||||
|
# NOTE: Comments belong to a user
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
# Helper class method that allows you to build a comment
|
||||||
|
# by passing a commentable object, a user_id, and comment text
|
||||||
|
# example in readme
|
||||||
|
def self.build_from(obj, user_id, comment)
|
||||||
|
new \
|
||||||
|
:commentable => obj,
|
||||||
|
:body => comment,
|
||||||
|
:user_id => user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
#helper method to check if a comment has children
|
||||||
|
def has_children?
|
||||||
|
self.children.any?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Helper class method to lookup all comments assigned
|
||||||
|
# to all commentable types for a given user.
|
||||||
|
scope :find_comments_by_user, lambda { |user|
|
||||||
|
where(:user_id => user.id).order('created_at DESC')
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper class method to look up all comments for
|
||||||
|
# commentable class name and commentable id.
|
||||||
|
scope :find_comments_for_commentable, lambda { |commentable_str, commentable_id|
|
||||||
|
where(:commentable_type => commentable_str.to_s, :commentable_id => commentable_id).order('created_at DESC')
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper class method to look up a commentable object
|
||||||
|
# given the commentable class name and id
|
||||||
|
def self.find_commentable(commentable_str, commentable_id)
|
||||||
|
commentable_str.constantize.find(commentable_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
87
app/models/conference.rb
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
class Conference < ActiveRecord::Base
|
||||||
|
attr_accessible :title, :short_title, :social_tag, :contact_email, :timezone, :html_export_path,
|
||||||
|
:start_date, :end_date, :rooms_attributes, :tracks_attributes, :cfp_open, :registration_open,
|
||||||
|
:event_types_attributes
|
||||||
|
|
||||||
|
has_one :call_for_papers, :dependent => :destroy
|
||||||
|
has_many :events, :dependent => :destroy
|
||||||
|
has_many :event_types, :dependent => :destroy
|
||||||
|
has_many :tracks, :dependent => :destroy
|
||||||
|
has_many :rooms, :dependent => :destroy
|
||||||
|
has_many :registrations, :dependent => :destroy
|
||||||
|
|
||||||
|
belongs_to :venue
|
||||||
|
|
||||||
|
accepts_nested_attributes_for :rooms, :reject_if => proc {|r| r["name"].blank?}, :allow_destroy => true
|
||||||
|
accepts_nested_attributes_for :tracks, :reject_if => proc {|r| r["name"].blank?}, :allow_destroy => true
|
||||||
|
accepts_nested_attributes_for :venue
|
||||||
|
accepts_nested_attributes_for :event_types, :allow_destroy => true
|
||||||
|
|
||||||
|
validates_presence_of :title,
|
||||||
|
:short_title,
|
||||||
|
:social_tag
|
||||||
|
validates_uniqueness_of :short_title
|
||||||
|
validates_format_of :short_title, :with => /^[a-zA-Z0-9_-]*$/
|
||||||
|
before_create :generate_guid
|
||||||
|
before_create :create_venue
|
||||||
|
|
||||||
|
|
||||||
|
def self.current
|
||||||
|
self.order("created_at DESC").first
|
||||||
|
end
|
||||||
|
|
||||||
|
def date_range_string
|
||||||
|
startstr = "Unknown - "
|
||||||
|
endstr = "Unknown"
|
||||||
|
if start_date.month == end_date.month && start_date.year == end_date.year
|
||||||
|
startstr = start_date.strftime("%B %d - ")
|
||||||
|
endstr = end_date.strftime("%d, %Y")
|
||||||
|
elsif start_date.month != end_date.month && start_date.year == end_date.year
|
||||||
|
startstr = start_date.strftime("%B %d - ")
|
||||||
|
endstr = end_date.strftime("%B %d, %Y")
|
||||||
|
else
|
||||||
|
startstr = start_date.strftime("%B %d, %Y - ")
|
||||||
|
endstr = end_date.strftime("%B %d, %Y")
|
||||||
|
end
|
||||||
|
|
||||||
|
result = startstr + endstr
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_registered? user
|
||||||
|
return nil if user.nil?
|
||||||
|
return nil if user.person.nil?
|
||||||
|
|
||||||
|
if self.registrations.where(:person_id => user.person.id).count == 0
|
||||||
|
Rails.logger.debug("Returning false")
|
||||||
|
false
|
||||||
|
else
|
||||||
|
Rails.logger.debug("Returning true")
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cfp_open?
|
||||||
|
today = Date.current
|
||||||
|
cfp = self.call_for_papers
|
||||||
|
if !cfp.nil? && (cfp.start_date.. cfp.end_date).cover?(today)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_venue
|
||||||
|
self.venue_id = Venue.create.id
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while Person.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
101
app/models/event.rb
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
class Event < ActiveRecord::Base
|
||||||
|
include ActiveRecord::Transitions
|
||||||
|
|
||||||
|
attr_accessible :title, :subtitle, :abstract, :description, :event_type_id, :people_attributes, :person,
|
||||||
|
:proposal_additional_speakers
|
||||||
|
acts_as_commentable
|
||||||
|
|
||||||
|
has_many :event_people, :dependent => :destroy
|
||||||
|
has_many :event_attachments, :dependent => :destroy
|
||||||
|
has_many :people, :through => :event_people
|
||||||
|
belongs_to :event_type
|
||||||
|
|
||||||
|
belongs_to :track
|
||||||
|
belongs_to :room
|
||||||
|
belongs_to :conference
|
||||||
|
|
||||||
|
accepts_nested_attributes_for :event_people
|
||||||
|
accepts_nested_attributes_for :event_attachments, :allow_destroy => true, :reject_if => :all_blank
|
||||||
|
accepts_nested_attributes_for :people
|
||||||
|
before_create :generate_guid
|
||||||
|
validate :abstract_limit
|
||||||
|
|
||||||
|
state_machine :initial => :new do
|
||||||
|
state :new
|
||||||
|
state :review
|
||||||
|
state :withdrawn
|
||||||
|
state :accepted
|
||||||
|
state :unconfirmed
|
||||||
|
state :confirmed
|
||||||
|
state :canceled
|
||||||
|
state :rejected
|
||||||
|
|
||||||
|
event :start_review do
|
||||||
|
transitions :to => :review, :from => [:new, :rejected]
|
||||||
|
end
|
||||||
|
event :withdraw do
|
||||||
|
transitions :to => :withdrawn, :from => [:new, :review, :unconfirmed]
|
||||||
|
end
|
||||||
|
event :accept do
|
||||||
|
transitions :to => :unconfirmed, :from => [:new, :review], :on_transition => :process_acceptance
|
||||||
|
end
|
||||||
|
event :unconfirm do
|
||||||
|
transitions :to => :review, :from=>[:confirmed]
|
||||||
|
end
|
||||||
|
event :confirm do
|
||||||
|
transitions :to => :confirmed, :from => :unconfirmed
|
||||||
|
end
|
||||||
|
event :cancel do
|
||||||
|
transitions :to => :canceled, :from => [:unconfirmed, :confirmed]
|
||||||
|
end
|
||||||
|
event :reject do
|
||||||
|
transitions :to => :rejected, :from => [:new, :review], :on_transition => :process_rejection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def submitter
|
||||||
|
result = self.event_people.where(:event_role => "submitter").first
|
||||||
|
if !result.nil?
|
||||||
|
result.person
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def transition_possible?(transition)
|
||||||
|
self.class.state_machine.events_for(self.current_state).include?(transition)
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_acceptance(options)
|
||||||
|
# if options[:send_mail]
|
||||||
|
# self.event_people.presenter.each do |event_person|
|
||||||
|
# event_person.generate_token!
|
||||||
|
# SelectionNotification.acceptance_notification(event_person).deliver
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def abstract_word_count
|
||||||
|
if self.abstract.nil?
|
||||||
|
0
|
||||||
|
else
|
||||||
|
self.abstract.split.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private
|
||||||
|
|
||||||
|
def abstract_limit
|
||||||
|
if self.abstract.split.size > 250
|
||||||
|
errors.add(:abstract, "cannot have more than 250 words")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while self.class.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
28
app/models/event_attachment.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class EventAttachment < ActiveRecord::Base
|
||||||
|
belongs_to :event
|
||||||
|
scope :public, where(:public => true)
|
||||||
|
attr_accessible :public, :attachment, :event_id, :title
|
||||||
|
|
||||||
|
has_attached_file :attachment, :path => ":rails_root/storage/:rails_env/attachments/:id/:style/:basename.:extension"
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
|
|
||||||
|
def to_jq_upload
|
||||||
|
{
|
||||||
|
"name" => read_attribute(:attachment_file_name),
|
||||||
|
"size" => read_attribute(:attachment_file_size),
|
||||||
|
"title" => read_attribute(:title),
|
||||||
|
"public" => read_attribute(:public),
|
||||||
|
#"url" => attachment.url(:original),
|
||||||
|
"url" => conference_proposal_event_attachment_path(self.event.conference.short_title, self.event_id, self.id),
|
||||||
|
"delete_url" => conference_proposal_event_attachment_path(self.event.conference.short_title, self.event_id, self.id),
|
||||||
|
"delete_type" => "DELETE"
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
#:path => ":rails_root/public/system/:attachment/:id/:style/:filename",
|
||||||
|
# :url => "/system/:attachment/:id/:style/:filename"
|
||||||
|
|
||||||
|
#has_paper_trail :meta => {:associated_id => :event_id, :associated_type => "Event"}
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
8
app/models/event_person.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
class EventPerson < ActiveRecord::Base
|
||||||
|
attr_accessible :event, :person, :person_id, :event_role
|
||||||
|
# TODO Do we need these roles?
|
||||||
|
ROLES = [["Speaker","speaker"], ["Submitter","submitter"], ["Moderator","moderator"]]
|
||||||
|
|
||||||
|
belongs_to :event
|
||||||
|
belongs_to :person
|
||||||
|
end
|
||||||
5
app/models/event_type.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
class EventType < ActiveRecord::Base
|
||||||
|
attr_accessible :title, :length
|
||||||
|
|
||||||
|
belongs_to :conference
|
||||||
|
end
|
||||||
71
app/models/person.rb
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
class Person < ActiveRecord::Base
|
||||||
|
attr_accessible :email, :first_name, :last_name, :public_name, :biography, :company
|
||||||
|
|
||||||
|
has_many :event_people, :dependent => :destroy
|
||||||
|
has_many :events, :through => :event_people, :uniq => true
|
||||||
|
has_many :registrations, :dependent => :destroy
|
||||||
|
validates :first_name, :presence => true
|
||||||
|
validates :last_name, :presence => true
|
||||||
|
validate :biography_limit
|
||||||
|
|
||||||
|
before_create :generate_guid
|
||||||
|
before_save :set_public_name
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
if self.public_name.empty?
|
||||||
|
self.first_name + " " + self.last_name
|
||||||
|
else
|
||||||
|
self.public_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def withdraw_proposal id
|
||||||
|
proposal = self.events.find_by_id(id)
|
||||||
|
if !proposal.nil?
|
||||||
|
proposal.withdraw
|
||||||
|
proposal.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def attending_conference? conference
|
||||||
|
Registration.where(:conference_id => conference.id,
|
||||||
|
:person_id => self.id).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def proposals conference
|
||||||
|
self.events.where("conference_id = ? AND state != ? AND state != ?", conference.id, "withdrawn", "rejected")
|
||||||
|
end
|
||||||
|
|
||||||
|
def proposal_count conference
|
||||||
|
proposals(conference).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def biography_word_count
|
||||||
|
if self.biography.nil?
|
||||||
|
0
|
||||||
|
else
|
||||||
|
self.biography.split.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def biography_limit
|
||||||
|
if self.biography.split.size > 150
|
||||||
|
errors.add(:abstract, "cannot have more than 150 words")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_public_name
|
||||||
|
if public_name.empty?
|
||||||
|
self.public_name = "#{first_name} #{last_name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while Person.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
9
app/models/registration.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
class Registration < ActiveRecord::Base
|
||||||
|
belongs_to :person
|
||||||
|
belongs_to :conference
|
||||||
|
|
||||||
|
attr_accessible :person_id, :conference_id, :attending_social_events, :attending_social_events_with_partner,
|
||||||
|
:using_affiliated_lodging, :arrival, :departure, :person_attributes
|
||||||
|
accepts_nested_attributes_for :person
|
||||||
|
|
||||||
|
end
|
||||||
4
app/models/role.rb
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
class Role < ActiveRecord::Base
|
||||||
|
attr_accessible :name
|
||||||
|
has_and_belongs_to_many :users
|
||||||
|
end
|
||||||
18
app/models/room.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Room < ActiveRecord::Base
|
||||||
|
attr_accessible :name, :size, :public
|
||||||
|
|
||||||
|
belongs_to :conference
|
||||||
|
has_many :events
|
||||||
|
|
||||||
|
before_create :generate_guid
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while Person.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
17
app/models/track.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
class Track < ActiveRecord::Base
|
||||||
|
attr_accessible :name, :description, :color
|
||||||
|
|
||||||
|
belongs_to :conference
|
||||||
|
|
||||||
|
before_create :generate_guid
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while Person.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
55
app/models/user.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
class User < ActiveRecord::Base
|
||||||
|
|
||||||
|
# Include default devise modules. Others available are:
|
||||||
|
# :token_authenticatable, :confirmable,
|
||||||
|
# :lockable, :timeoutable and :omniauthable
|
||||||
|
devise :database_authenticatable, :registerable,
|
||||||
|
:recoverable, :rememberable, :trackable, :validatable
|
||||||
|
|
||||||
|
has_and_belongs_to_many :roles
|
||||||
|
has_one :person
|
||||||
|
|
||||||
|
attr_accessible :email, :password, :password_confirmation, :remember_me, :role_id, :role_ids, :person_attributes
|
||||||
|
accepts_nested_attributes_for :person
|
||||||
|
accepts_nested_attributes_for :roles
|
||||||
|
|
||||||
|
before_save :setup_role
|
||||||
|
before_create :create_person
|
||||||
|
|
||||||
|
def role?(role)
|
||||||
|
Rails.logger.debug("Checking role in user")
|
||||||
|
return !!self.roles.find_by_name(role.to_s.camelize)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_roles
|
||||||
|
return self.roles
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_role
|
||||||
|
if self.role_ids.empty?
|
||||||
|
self.role_ids = [1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def popup_details
|
||||||
|
details = "<b>Sign-in Count</b><br>"
|
||||||
|
details += "#{self.sign_in_count}<br>"
|
||||||
|
details += "<b>Current Sign-in</b><br>"
|
||||||
|
details += "#{self.current_sign_in_at}<br>"
|
||||||
|
details += "<b>Last Sign-in</b><br>"
|
||||||
|
details += "#{self.last_sign_in_at}<br>"
|
||||||
|
details += "<b>Current Sign-in IP</b><br>"
|
||||||
|
details += "#{self.current_sign_in_ip}<br>"
|
||||||
|
details += "<b>Last Sign-in IP</b><br>"
|
||||||
|
details += "#{self.last_sign_in_ip}<br>"
|
||||||
|
details += "<b>Created at</b><br>"
|
||||||
|
details += "#{self.created_at}<br>"
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def create_person
|
||||||
|
# TODO Search people for existing email address, add to their account
|
||||||
|
build_person(:email => self.email)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
14
app/models/venue.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Venue < ActiveRecord::Base
|
||||||
|
has_many :conferences
|
||||||
|
before_create :generate_guid
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def generate_guid
|
||||||
|
begin
|
||||||
|
guid = SecureRandom.urlsafe_base64
|
||||||
|
end while Venue.where(:guid => guid).exists?
|
||||||
|
self.guid = guid
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
11
app/views/admin/callforpapers/show.html.haml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
.container-fluid
|
||||||
|
.row-fluid
|
||||||
|
.span3
|
||||||
|
= render 'admin/conference/sidebar', :activated => "Call for Papers"
|
||||||
|
.span9
|
||||||
|
= semantic_form_for(@cfp, :url => admin_conference_cfp_update_path(@conference.short_title),:html => {:multipart => true}) do |f|
|
||||||
|
= f.input :start_date, :as => :string, :input_html => { :id => "conference-start-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :hard_deadline, :as => :string, :input_html => { :id => "cfp-hard-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :description, :hint => "Welcome text for the Call for Papers"
|
||||||
|
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
||||||
26
app/views/admin/conference/_sidebar.html.haml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
.well.sidebar-nav
|
||||||
|
%ul.nav.nav-list
|
||||||
|
- if activated == "Conference"
|
||||||
|
%li.active= link_to "Conference", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Conference", admin_conference_path(@conference.short_title)
|
||||||
|
- if activated == "Call for Papers"
|
||||||
|
%li.active= link_to "Call for Papers", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Call for Papers", admin_conference_cfp_info_path(@conference.short_title)
|
||||||
|
- if activated == "Venue"
|
||||||
|
%li.active= link_to "Venue", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Venue", admin_conference_venue_info_path(@conference.short_title)
|
||||||
|
- if activated == "Rooms"
|
||||||
|
%li.active= link_to "Rooms", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Rooms", admin_conference_rooms_list_path(@conference.short_title)
|
||||||
|
- if activated == "Tracks"
|
||||||
|
%li.active= link_to "Tracks", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Tracks", admin_conference_tracks_list_path(@conference.short_title)
|
||||||
|
- if activated == "Event Types"
|
||||||
|
%li.active= link_to "Event Types", "#"
|
||||||
|
- else
|
||||||
|
%li= link_to "Event Types", admin_conference_eventtype_list_path(@conference.short_title)
|
||||||
3
app/views/admin/conference/index.html.haml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
%ul
|
||||||
|
- @conferences.each do |conference|
|
||||||
|
%li= link_to conference.title, admin_conference_path(conference.short_title)
|
||||||
13
app/views/admin/conference/new.html.haml
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
= semantic_form_for(@conference, :url => admin_conference_index_path) do |f|
|
||||||
|
= f.inputs "Basic Information" do
|
||||||
|
= f.input :title, :hint => "The name of your conference as it shall appear throughout the site. Example: 'OpenSUSE Conference 2013'"
|
||||||
|
= f.input :short_title, :hint => "A short and unique handle for your conference, using only lower-case letters, numbers and underscores. This will be used to identify your conference in URLs etc. Example: 'froscon2011'"
|
||||||
|
= f.input :social_tag, :hint => "The hashtag you'll use on Twitter and Google+. Don't include the '#' sign!'"
|
||||||
|
= f.input :contact_email, :hint => "Contact email address for your conference. Will be used as reply-to address in emails sent out by the system."
|
||||||
|
= f.inputs "Scheduling" do
|
||||||
|
= f.input :timezone, :as => :time_zone, :hint => "Please select in what time zone your conference will take place. This is needed to correctly display times for your events."
|
||||||
|
= f.input :start_date, :as => :string, :input_html => { :id => "conference-start-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :html_export_path, :hint => "The path for static HTML exports"
|
||||||
|
= f.actions do
|
||||||
|
= f.action :submit, :button_html => {:class => "btn primary"}
|
||||||
17
app/views/admin/conference/show.html.haml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
.container-fluid
|
||||||
|
.row-fluid
|
||||||
|
.span3
|
||||||
|
= render 'admin/conference/sidebar', :activated => "Conference"
|
||||||
|
.span9
|
||||||
|
= semantic_form_for(@conference, :url => admin_conference_path(@conference.short_title),:html => {:multipart => true}) do |f|
|
||||||
|
= f.input :title, :hint => "The full name of the conference, such as 'OpenSUSE Conference 2013'"
|
||||||
|
= f.input :short_title, :hint => "A short title, such as 'osc2013', to be used in URLs"
|
||||||
|
= f.input :social_tag, :hint => "The hashtag you'll use on Twitter and Google+. Don't include the '#' sign!'"
|
||||||
|
= f.input :contact_email, :hint => "Contact email address for your conference. Will be used as reply-to address in emails sent out by the system."
|
||||||
|
= f.input :timezone, :as => :time_zone, :hint => "The conference time zone"
|
||||||
|
= f.input :start_date, :as => :string, :input_html => { :id => "conference-start-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" }
|
||||||
|
= f.input :html_export_path, :hint => "The path for static HTML exports"
|
||||||
|
= f.input :cfp_open, :label => false, :hint => "Allow people to submit papers?"
|
||||||
|
= f.input :registration_open, :label => false, :hint => "Allow people to register as attendees?"
|
||||||
|
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
||||||
6
app/views/admin/events/_person_fields.html.haml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
.nested-fields
|
||||||
|
= f.inputs do
|
||||||
|
= f.input :email
|
||||||
|
= f.input :public_name
|
||||||
|
= remove_association_link :person, f
|
||||||
|
|
||||||
2
app/views/admin/events/edit.html.haml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.container
|
||||||
|
= render 'proposal/form'
|
||||||
48
app/views/admin/events/index.html.haml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
.row-fluid
|
||||||
|
.span12
|
||||||
|
%table.table.table-striped.table-bordered.table-hover
|
||||||
|
%thead
|
||||||
|
%th
|
||||||
|
%b Title
|
||||||
|
%th
|
||||||
|
%b Submitter
|
||||||
|
%th
|
||||||
|
%b Type
|
||||||
|
%th
|
||||||
|
%b State
|
||||||
|
- @events.each do |event|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
=link_to event.title, admin_conference_event_path(@conference.short_title, event)
|
||||||
|
%td
|
||||||
|
- if !event.submitter.nil?
|
||||||
|
=link_to event.submitter.public_name, admin_person_path(event.submitter)
|
||||||
|
- else
|
||||||
|
Unknown submitter
|
||||||
|
%td
|
||||||
|
= event.event_type.title
|
||||||
|
%td
|
||||||
|
- if event.state == "withdrawn"
|
||||||
|
Withdrawn
|
||||||
|
- else
|
||||||
|
.dropdown
|
||||||
|
= link_to "#", :class => "dropdown-toggle" do
|
||||||
|
= event.state.humanize
|
||||||
|
<b class="caret"></b>
|
||||||
|
%ul.dropdown-menu
|
||||||
|
- if event.transition_possible? :accept
|
||||||
|
%li= link_to "Accept event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :accept, :send_mail => false),
|
||||||
|
:method => :put, :hint => "Accept this event without sending an automated email."
|
||||||
|
- if event.transition_possible? :reject
|
||||||
|
%li= link_to "Reject event (no email)", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :reject, :send_mail => false),
|
||||||
|
:method => :put, :confirm => "Are you sure?",
|
||||||
|
:hint => "Reject this event without sending an automated email."
|
||||||
|
- if event.transition_possible? :start_review
|
||||||
|
%li= link_to "Start review", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :start_review),
|
||||||
|
:method => :put
|
||||||
|
- if event.transition_possible? :confirm
|
||||||
|
%li= link_to "Confirm event", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :confirm),
|
||||||
|
:method => :put, :hint => "Confirm that the speaker(s) will be present and that the event will actually take place."
|
||||||
|
- if event.transition_possible? :cancel
|
||||||
|
%li= link_to "Cancel event", update_state_admin_conference_event_path(@conference.short_title, event, :transition => :cancel),
|
||||||
|
:method => :put, :hint => "Mark this event as cancelled. Usually this means that the speakers had to cancel their appearance."
|
||||||
112
app/views/admin/events/show.html.haml
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
.row-fluid
|
||||||
|
.span10
|
||||||
|
%h3
|
||||||
|
= @event.title
|
||||||
|
%i= @event.subtitle
|
||||||
|
|
||||||
|
.span2
|
||||||
|
= link_to "Edit Submission", edit_admin_conference_event_path(@conference.short_title, @event),
|
||||||
|
:class => "btn btn-mini btn-primary pull-right", :style => "margin-top:20px;"
|
||||||
|
|
||||||
|
.row-fluid
|
||||||
|
.span12
|
||||||
|
%table.table
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b State
|
||||||
|
%td
|
||||||
|
.dropdown
|
||||||
|
= link_to "#", :class => "dropdown-toggle" do
|
||||||
|
= @event.state.humanize
|
||||||
|
<b class="caret"></b>
|
||||||
|
%ul.dropdown-menu
|
||||||
|
- if @event.transition_possible? :accept
|
||||||
|
%li= link_to "Accept event (no email)", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :accept, :send_mail => false),
|
||||||
|
:method => :put, :hint => "Accept this event without sending an automated email."
|
||||||
|
- if @event.transition_possible? :reject
|
||||||
|
%li= link_to "Reject event (no email)", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :reject, :send_mail => false),
|
||||||
|
:method => :put, :confirm => "Are you sure?",
|
||||||
|
:hint => "Reject this event without sending an automated email."
|
||||||
|
- if @event.transition_possible? :start_review
|
||||||
|
%li= link_to "Start review", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :start_review),
|
||||||
|
:method => :put
|
||||||
|
- if @event.transition_possible? :confirm
|
||||||
|
%li= link_to "Confirm event", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :confirm),
|
||||||
|
:method => :put, :hint => "Confirm that the speaker(s) will be present and that the event will actually take place."
|
||||||
|
- if @event.transition_possible? :cancel
|
||||||
|
%li= link_to "Cancel event", update_state_admin_conference_event_path(@conference.short_title, @event, :transition => :cancel),
|
||||||
|
:method => :put, :hint => "Mark this event as cancelled. Usually this means that the speakers had to cancel their appearance."
|
||||||
|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Submitter
|
||||||
|
%td
|
||||||
|
= link_to @event.submitter.public_name, admin_person_path(@conference.short_title, @event.submitter)
|
||||||
|
(
|
||||||
|
= link_to @event.submitter.email, "mailto: #{@event.submitter.email}"
|
||||||
|
)
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Biography
|
||||||
|
%td
|
||||||
|
= simple_format(@event.submitter.biography)
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Submitted on
|
||||||
|
%td= @event.created_at
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Last updated on
|
||||||
|
%td= @event.updated_at
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Abstract
|
||||||
|
%td= simple_format(@event.abstract)
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Description
|
||||||
|
%td= simple_format(@event.description)
|
||||||
|
- if @event.event_attachments.size > 0
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%th
|
||||||
|
%b Filename
|
||||||
|
%th
|
||||||
|
%b Title
|
||||||
|
%th
|
||||||
|
%b Size
|
||||||
|
%th
|
||||||
|
%b Public?
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
- @event.event_attachments.each do |a|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= link_to a.attachment_file_name, conference_proposal_event_attachment_path(@conference.short_title, @event.id, a.id)
|
||||||
|
%td
|
||||||
|
= a.title
|
||||||
|
%td
|
||||||
|
= number_to_human_size a.attachment_file_size
|
||||||
|
%td
|
||||||
|
- if a.public?
|
||||||
|
Public
|
||||||
|
- else
|
||||||
|
Not Public
|
||||||
|
%td
|
||||||
|
= link_to "Delete", conference_proposal_event_attachment_path(@conference.short_title, @event.id, a.id),
|
||||||
|
:method => :delete, :confirm => "Are you sure you want to delete this attachment? It's permanant!"
|
||||||
|
|
||||||
|
.row-fluid
|
||||||
|
= link_to "Comments (#{@comment_count})", "#", :id => "event-comment-link"
|
||||||
|
#comments-div
|
||||||
|
%hr
|
||||||
|
%ul.media
|
||||||
|
%div
|
||||||
|
.row-fluid
|
||||||
|
= form_tag(comment_admin_conference_event_path(@conference.short_title, @event.id), :method => :post) do
|
||||||
|
= text_area_tag(:comment, "")
|
||||||
|
= submit_tag "Add Comment", :class => "btn btn-primary pull-right"
|
||||||
|
%br
|
||||||
|
- @comments.each do |comment|
|
||||||
|
%div
|
||||||
|
= raw format_comments(comment)
|
||||||
7
app/views/admin/eventtype/_event_type_fields.html.erb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="nested-fields">
|
||||||
|
<%= f.inputs do %>
|
||||||
|
<%= f.input :title %>
|
||||||
|
<%= f.input :length, :input_html => {:size => 3} %>
|
||||||
|
<%= remove_association_link :event_type, f %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
8
app/views/admin/eventtype/event_type_list.html.haml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
.container-fluid
|
||||||
|
.row-fluid
|
||||||
|
.span3
|
||||||
|
= render 'admin/conference/sidebar', :activated => "Event Types"
|
||||||
|
.span9
|
||||||
|
= semantic_form_for(@conference, :url => admin_conference_eventtype_update_path(@conference.short_title)) do |f|
|
||||||
|
= dynamic_association :event_types, "Event Types", f
|
||||||
|
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
||||||
18
app/views/admin/people/index.html.haml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
%table.table.table-striped.table-bordered.table-hover
|
||||||
|
%thead
|
||||||
|
%th
|
||||||
|
%b Last Name
|
||||||
|
%th
|
||||||
|
%b First Name
|
||||||
|
%th
|
||||||
|
%b Public Name
|
||||||
|
%th
|
||||||
|
%b # of Conference Registrations
|
||||||
|
%th
|
||||||
|
- @people.each do |person|
|
||||||
|
%tr
|
||||||
|
%td= person.last_name
|
||||||
|
%td= person.first_name
|
||||||
|
%td= person.public_name
|
||||||
|
%td= person.registrations.count
|
||||||
|
%td= link_to "View", admin_person_path(person)
|
||||||
49
app/views/admin/people/show.html.haml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
%table.table
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b First Name
|
||||||
|
%td
|
||||||
|
= @person.first_name
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Last Name
|
||||||
|
%td
|
||||||
|
= @person.last_name
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Public Name
|
||||||
|
%td
|
||||||
|
= @person.public_name
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Company
|
||||||
|
%td
|
||||||
|
= @person.company
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Email
|
||||||
|
%td
|
||||||
|
= @person.email
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Created At
|
||||||
|
%td
|
||||||
|
= @person.created_at
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Updated At
|
||||||
|
%td
|
||||||
|
= @person.updated_at
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Biography
|
||||||
|
%td
|
||||||
|
= @person.biography
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%b Registered to attend
|
||||||
|
%td
|
||||||
|
- if @person.registrations.count == 0
|
||||||
|
None
|
||||||
|
- else
|
||||||
|
= @person.registrations.map { |r| r.conference.title }.join ','
|
||||||
48
app/views/admin/registrations/show.html.haml
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
.row-fluid
|
||||||
|
.span12
|
||||||
|
.pull-right{:style=>"margin-top:20px; margin-bottom:20px;"}
|
||||||
|
= link_to "Export PDF", admin_conference_registrations_path(@conference.short_title, :format => :pdf), :class => "btn btn-success"
|
||||||
|
.row-fluid
|
||||||
|
.span12
|
||||||
|
%table.table.table-striped.table-bordered.table-hover
|
||||||
|
%thead
|
||||||
|
%th
|
||||||
|
%b Last Name
|
||||||
|
%th
|
||||||
|
%b First Name
|
||||||
|
%th
|
||||||
|
%b Public Name
|
||||||
|
%th
|
||||||
|
%b Email
|
||||||
|
%th
|
||||||
|
%b Attending Social Events
|
||||||
|
%th
|
||||||
|
%b Attending With Partner
|
||||||
|
%th
|
||||||
|
%b Arrival Date
|
||||||
|
%th
|
||||||
|
%b Departure Date
|
||||||
|
%th
|
||||||
|
%th
|
||||||
|
- @registrations.each do |registration|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= registration.last_name
|
||||||
|
%td
|
||||||
|
= registration.first_name
|
||||||
|
%td
|
||||||
|
= registration.public_name
|
||||||
|
%td
|
||||||
|
= registration.email
|
||||||
|
%td
|
||||||
|
= registration.attending_social_events
|
||||||
|
%td
|
||||||
|
= registration.attending_social_events_with_partner
|
||||||
|
%td
|
||||||
|
= registration.arrival
|
||||||
|
%td
|
||||||
|
= registration.departure
|
||||||
|
%td
|
||||||
|
= link_to "Edit", "#", :class => "btn btn-primary"
|
||||||
|
%td
|
||||||
|
= link_to "Delete", "#", :class => "btn btn-danger", :confirm => "Really delete registration for #{registration.public_name}?"
|
||||||
38
app/views/admin/registrations/show.pdf.prawn
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
prawn_document(:force_download=>true, :filename => @pdf_filename) do |pdf|
|
||||||
|
table_array = []
|
||||||
|
header_array = [" ",
|
||||||
|
"Last Name",
|
||||||
|
"First Name",
|
||||||
|
"Public Name",
|
||||||
|
"Email",
|
||||||
|
"Attending Social Events",
|
||||||
|
"Attending With Partner",
|
||||||
|
"Arrival Date",
|
||||||
|
"Departure Date"]
|
||||||
|
table_array << header_array
|
||||||
|
@registrations.each do |registration|
|
||||||
|
row = []
|
||||||
|
row << ""
|
||||||
|
row << registration.last_name
|
||||||
|
row << registration.first_name
|
||||||
|
row << registration.public_name
|
||||||
|
row << registration.email
|
||||||
|
if registration.attending_social_events
|
||||||
|
row << "X"
|
||||||
|
else
|
||||||
|
row << " "
|
||||||
|
end
|
||||||
|
|
||||||
|
if registration.attending_social_events_with_partner.to_s
|
||||||
|
row << "X"
|
||||||
|
else
|
||||||
|
row << " "
|
||||||
|
end
|
||||||
|
row << registration.arrival
|
||||||
|
row << registration.departure
|
||||||
|
table_array << row
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf.text "#{@conference.title} Registrations", :font_size => 25
|
||||||
|
pdf.table table_array, :header => true, :cell_style => {:size => 5, :border_width => 1}
|
||||||
|
end
|
||||||
8
app/views/admin/rooms/_room_fields.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="nested-fields">
|
||||||
|
<%= f.inputs do %>
|
||||||
|
<%= f.input :name %>
|
||||||
|
<%= f.input :size, :input_html => {:size => 5} %>
|
||||||
|
<%= f.input :public, :as => :boolean %>
|
||||||
|
<%= remove_association_link :room, f %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
8
app/views/admin/rooms/rooms_list.html.haml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
.container-fluid
|
||||||
|
.row-fluid
|
||||||
|
.span3
|
||||||
|
= render 'admin/conference/sidebar', :activated => "Rooms"
|
||||||
|
.span9
|
||||||
|
= semantic_form_for(@conference, :url => admin_conference_rooms_update_path(@conference.short_title)) do |f|
|
||||||
|
= dynamic_association :rooms, "Rooms", f
|
||||||
|
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
||||||
8
app/views/admin/tracks/_track_fields.html.erb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="nested-fields">
|
||||||
|
<%= f.inputs do %>
|
||||||
|
<%= f.input :name %>
|
||||||
|
<%= f.input :color, :input_html => {:size => 6} %>
|
||||||
|
<%= f.input :description, :input_html => {:rows => 2 } %>
|
||||||
|
<%= remove_association_link :track, f %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||