qcourses 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +75 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/config.ru +3 -0
- data/db/migrations/001_initial_database.rb +25 -0
- data/db/migrations/002_create_registrations.rb +29 -0
- data/demo_app.rb +11 -0
- data/lib/factories.rb +111 -0
- data/lib/qcourses/configuration.rb +35 -0
- data/lib/qcourses/controllers/base.rb +20 -0
- data/lib/qcourses/controllers/courses_controller.rb +16 -0
- data/lib/qcourses/controllers/events_controller.rb +54 -0
- data/lib/qcourses/controllers/registrations_controller.rb +51 -0
- data/lib/qcourses/controllers.rb +5 -0
- data/lib/qcourses/date_ex.rb +18 -0
- data/lib/qcourses/models/course.rb +30 -0
- data/lib/qcourses/models/course_repository.rb +90 -0
- data/lib/qcourses/models/event.rb +54 -0
- data/lib/qcourses/models/location.rb +17 -0
- data/lib/qcourses/models/registration.rb +36 -0
- data/lib/qcourses/models.rb +28 -0
- data/lib/qcourses/qcourses.rake.rb +21 -0
- data/lib/qcourses/renderers.rb +26 -0
- data/lib/qcourses/resource_paths.rb +45 -0
- data/lib/qcourses/string_ex.rb +5 -0
- data/lib/qcourses/view_helpers.rb +70 -0
- data/lib/qcourses/web_app.rb +29 -0
- data/lib/qcourses.rb +21 -0
- data/public/css/default.css +91 -0
- data/public/img/delete.gif +0 -0
- data/public/javascript/jquery-1.7.js +9300 -0
- data/public/javascript/jquery-1.7.min.js +4 -0
- data/public/javascript/qcourses.js +20 -0
- data/spec/factories_spec.rb +131 -0
- data/spec/qcourses/configuration_spec.rb +37 -0
- data/spec/qcourses/controllers/courses_controller_spec.rb +43 -0
- data/spec/qcourses/controllers/events_controller_spec.rb +100 -0
- data/spec/qcourses/controllers/registrations_controller_spec.rb +100 -0
- data/spec/qcourses/models/course_repository_spec.rb +147 -0
- data/spec/qcourses/models/event_spec.rb +74 -0
- data/spec/qcourses/models/location_spec.rb +19 -0
- data/spec/qcourses/models/registration_spec.rb +55 -0
- data/spec/qcourses/renderers_spec.rb +82 -0
- data/spec/qcourses/string_ex_spec.rb +11 -0
- data/spec/qcourses/view_helpers_spec.rb +90 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/factories.rb +24 -0
- data/spec/support/matchers.rb +61 -0
- data/spec/support/request_specs.rb +4 -0
- data/spec/support/test_files.rb +20 -0
- data/views/admin.haml +9 -0
- data/views/events/index.haml +18 -0
- data/views/events/new.haml +34 -0
- data/views/layout.haml +9 -0
- data/views/registration.haml +9 -0
- data/views/registrations/new.haml +37 -0
- data/views/registrations/participant.haml +12 -0
- data/views/registrations/success.haml +4 -0
- data/views/trainings/error.haml +1 -0
- data/views/trainings/index.haml +9 -0
- metadata +306 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
module Qcourses
|
2
|
+
|
3
|
+
class MemoryCourseRepository
|
4
|
+
def initialize
|
5
|
+
@courses = {}
|
6
|
+
end
|
7
|
+
def create_course(attributes)
|
8
|
+
raise "should supply course identification" unless attributes.has_key?(:identification)
|
9
|
+
@courses[attributes[:identification]] = Course.new(attributes)
|
10
|
+
end
|
11
|
+
def all()
|
12
|
+
@courses.values
|
13
|
+
end
|
14
|
+
def find(course_id)
|
15
|
+
@courses[course_id]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class CourseRepository
|
20
|
+
class Error < Exception; end
|
21
|
+
|
22
|
+
@@instance = nil
|
23
|
+
def self.configure(instance = CourseRepository.new)
|
24
|
+
@@instance = instance
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.destroy
|
28
|
+
@@instance = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.in_memory
|
32
|
+
configure MemoryCourseRepository.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.on_file_system
|
36
|
+
configure CourseRepository.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.method_missing(method, *args)
|
40
|
+
raise Error.new "CourseRepository not configured while calling #{method}" unless @@instance
|
41
|
+
@@instance.send(method, *args)
|
42
|
+
end
|
43
|
+
|
44
|
+
KEY_VALUE_SEPARATOR = ":"
|
45
|
+
|
46
|
+
def initialize(directory = Dir, file_opener = File)
|
47
|
+
@directory = directory
|
48
|
+
@file_opener = file_opener
|
49
|
+
end
|
50
|
+
|
51
|
+
def all
|
52
|
+
courses.values
|
53
|
+
end
|
54
|
+
|
55
|
+
def find(course_id)
|
56
|
+
courses[course_id]
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def courses
|
61
|
+
@courses ||= Hash[ parse_courses.map {|course| [course.identification, course] }]
|
62
|
+
end
|
63
|
+
|
64
|
+
def parse_courses
|
65
|
+
course_files.collect { |file| parse_course(file) }.uniq
|
66
|
+
end
|
67
|
+
def course_files
|
68
|
+
files = (@directory.glob("**/courses/*.mdown") + @directory.glob("**/cursussen/*.mdown"))
|
69
|
+
files.delete_if {|file| file.end_with?('index.mdown')}
|
70
|
+
end
|
71
|
+
|
72
|
+
def parse_course(filename)
|
73
|
+
@file_opener.open(filename) do |file|
|
74
|
+
course_identification = File.basename(filename, '.mdown')
|
75
|
+
Course.new parse_attributes(file, Course.default_attributes(course_identification))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_attributes(file, attributes)
|
80
|
+
file.each_line do |line|
|
81
|
+
line.strip!
|
82
|
+
return attributes unless line.include?(KEY_VALUE_SEPARATOR)
|
83
|
+
key, value = line.split(KEY_VALUE_SEPARATOR, 2)
|
84
|
+
attributes[:name] = value.strip if key.strip == 'Name'
|
85
|
+
attributes[:subtitle] = value.strip if key.strip == 'Subtitle'
|
86
|
+
end
|
87
|
+
return attributes
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Qcourses
|
2
|
+
|
3
|
+
class Event < Sequel::Model
|
4
|
+
plugin :validation_helpers
|
5
|
+
many_to_one :location
|
6
|
+
|
7
|
+
def self.opens(object_id)
|
8
|
+
first{ ({id => object_id}) & (from > Time.now) }
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate
|
12
|
+
super
|
13
|
+
validates_presence :from
|
14
|
+
errors.add(:from, "must be a time") unless is_a_time?(from)
|
15
|
+
errors.add(:location, "must be an associated location") unless location && location.valid?
|
16
|
+
end
|
17
|
+
|
18
|
+
def location=(new_location)
|
19
|
+
if new_location.is_a?(String)
|
20
|
+
new_location = Location.find_or_create_bij_insensitive_name(new_location)
|
21
|
+
end
|
22
|
+
super(new_location)
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
return "removed course (#{course_id})" unless course
|
27
|
+
course.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def subtitle
|
31
|
+
return '' unless course
|
32
|
+
course.subtitle
|
33
|
+
end
|
34
|
+
|
35
|
+
def location_name
|
36
|
+
return 'unknown' unless location
|
37
|
+
location.name
|
38
|
+
end
|
39
|
+
|
40
|
+
def course
|
41
|
+
@course ||= CourseRepository.find(course_id)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def is_a_time?(date)
|
46
|
+
return true if date.is_a?(Time)
|
47
|
+
return false unless date.is_a?(String)
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Qcourses
|
2
|
+
|
3
|
+
class Location < Sequel::Model
|
4
|
+
plugin :validation_helpers
|
5
|
+
one_to_many :events
|
6
|
+
|
7
|
+
def validate
|
8
|
+
validates_presence :name
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_or_create_bij_insensitive_name(new_location)
|
12
|
+
return nil if new_location.empty?
|
13
|
+
filter(:name.ilike("#{new_location}%") ).first || create(name: new_location)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Qcourses
|
2
|
+
class Company < Sequel::Model
|
3
|
+
plugin :validation_helpers
|
4
|
+
one_to_many :employees
|
5
|
+
def validate
|
6
|
+
validates_presence :name
|
7
|
+
validates_presence :contact_person
|
8
|
+
validates_presence :contact_email
|
9
|
+
validates_presence :invoice_address
|
10
|
+
validates_presence :postal_code
|
11
|
+
validates_presence :city
|
12
|
+
validates_format EMAIL_REGEXP, :contact_email
|
13
|
+
end
|
14
|
+
end
|
15
|
+
class Employee < Sequel::Model
|
16
|
+
plugin :validation_helpers
|
17
|
+
many_to_one :company
|
18
|
+
def validate
|
19
|
+
validates_presence :name
|
20
|
+
validates_presence :email
|
21
|
+
validates_format EMAIL_REGEXP, :email
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Registration < Sequel::Model
|
27
|
+
plugin :validation_helpers
|
28
|
+
many_to_one :employee
|
29
|
+
many_to_one :event
|
30
|
+
|
31
|
+
def validate
|
32
|
+
validates_presence :employee
|
33
|
+
validates_presence :event
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'sequel/extensions/migration'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Qcourses
|
6
|
+
def self.db
|
7
|
+
@@db ||= create_connection
|
8
|
+
end
|
9
|
+
def self.create_connection(environment = Qcourses.env)
|
10
|
+
environment = environment.to_s
|
11
|
+
connection = Sequel.connect(YAML::load(File.read(File.join(config.root, 'config', 'database.yml')))[environment])
|
12
|
+
schema_definition.apply(connection, :up) if environment == 'test'
|
13
|
+
connection
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.schema_definition
|
17
|
+
eval(`sequel -d sqlite://data/development.sqlite3`)
|
18
|
+
end
|
19
|
+
EMAIL_REGEXP = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
20
|
+
end
|
21
|
+
|
22
|
+
Qcourses.create_connection
|
23
|
+
|
24
|
+
require_relative 'models/course_repository'
|
25
|
+
require_relative 'models/course'
|
26
|
+
require_relative 'models/location'
|
27
|
+
require_relative 'models/event'
|
28
|
+
require_relative 'models/registration'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
desc "project console"
|
3
|
+
task :console => :environment do
|
4
|
+
sh "irb -I #{File.expand_path('lib', File.dirname(__FILE__)) } -r qcourses"
|
5
|
+
end
|
6
|
+
|
7
|
+
desc "project environment"
|
8
|
+
task :environment do
|
9
|
+
ENV['RACK_ENV'] ||= 'development'
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace :db do
|
13
|
+
desc "migrate the database"
|
14
|
+
task :migrate, [:version] => :environment do |t, args|
|
15
|
+
migration_dir = File.expand_path('../../db/migrations', File.dirname(__FILE__))
|
16
|
+
command = ["sequel -E config/database.yml -m #{migration_dir}"]
|
17
|
+
command << "-M #{args[:version]}" if args[:version]
|
18
|
+
sh command.join(' ')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Qcourses
|
2
|
+
module Renderers
|
3
|
+
private
|
4
|
+
def render(engine, data, options={}, locals={}, &block)
|
5
|
+
super(engine, data, override_options(options, data, engine), locals, &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
def override_options(options,template, engine)
|
9
|
+
options = options.merge(views:file_path_for_template(template, engine))
|
10
|
+
end
|
11
|
+
|
12
|
+
def file_path_for_template(template, engine)
|
13
|
+
views_path = File.join(root, views)
|
14
|
+
if template_exists?(template, engine, views_path)
|
15
|
+
views_path
|
16
|
+
else
|
17
|
+
File.join(local_root, 'views')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def template_exists?(template, engine, root_dir)
|
22
|
+
path = File.expand_path("#{template}.#{engine}", root_dir)
|
23
|
+
File.exists?(path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Qcourses
|
2
|
+
module ResourcePaths
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
base.helpers do
|
6
|
+
include UrlHelpers
|
7
|
+
end
|
8
|
+
end
|
9
|
+
module UrlHelpers
|
10
|
+
def adminprefix
|
11
|
+
settings.admin_url
|
12
|
+
end
|
13
|
+
def basepath
|
14
|
+
settings.basepath
|
15
|
+
end
|
16
|
+
def request_url(param = nil)
|
17
|
+
[basepath, param_symbol(param)].compact.join('/')
|
18
|
+
end
|
19
|
+
def new_request_url(param = nil)
|
20
|
+
[request_url, 'new', param_symbol(param)].compact.join('/')
|
21
|
+
end
|
22
|
+
def admin_request_url
|
23
|
+
adminprefix + request_url
|
24
|
+
end
|
25
|
+
def admin_new_request_url
|
26
|
+
adminprefix + new_request_url
|
27
|
+
end
|
28
|
+
private
|
29
|
+
def param_symbol(param)
|
30
|
+
param && param.inspect || param
|
31
|
+
end
|
32
|
+
end
|
33
|
+
module ClassMethods
|
34
|
+
def resource(name)
|
35
|
+
set :basepath, name
|
36
|
+
end
|
37
|
+
def resource_admin_on(url)
|
38
|
+
set :admin_url, url
|
39
|
+
end
|
40
|
+
include UrlHelpers
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Qcourses
|
2
|
+
module ViewHelpers
|
3
|
+
def options_for_select options
|
4
|
+
options.collect {|option| haml "%option(value='#{option[0]}') #{option[1]}", :layout => false}.join
|
5
|
+
end
|
6
|
+
def course_options
|
7
|
+
options_for_select CourseRepository.all.collect { |course| [course.identification, course.name] }
|
8
|
+
end
|
9
|
+
def location_options
|
10
|
+
options_for_select(Location.all.collect { |location| [location.id, location.name] } + [['0', 'new location']])
|
11
|
+
end
|
12
|
+
def display_if_locations
|
13
|
+
Location.all.empty? && "display:none;" || "display:block"
|
14
|
+
end
|
15
|
+
def display_unless_locations
|
16
|
+
Location.all.empty? && "display:block;" || "display:none"
|
17
|
+
end
|
18
|
+
|
19
|
+
def human_period(from, to)
|
20
|
+
if (from.year != to.year)
|
21
|
+
"#{from.strftime('%e/%m/%Y').strip} - #{to.strftime('%e/%m/%Y').strip}"
|
22
|
+
elsif (from.month != to.month)
|
23
|
+
"#{from.strftime('%e/%m')} - #{to.strftime('%e/%m %Y').strip}"
|
24
|
+
else
|
25
|
+
"#{from.day} - #{to.strftime('%e %B %Y').strip}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def input_for(object, attribute_name, options={})
|
30
|
+
object = instance_variable_get("@#{object}") if object.is_a?(Symbol)
|
31
|
+
return '' unless object
|
32
|
+
tag_attributes = {:type => 'text', :name => input_name(object, attribute_name, options[:array_element])}
|
33
|
+
tag_attributes[:value] = object.send(attribute_name) || ''
|
34
|
+
tag_classes = []
|
35
|
+
tag_classes << 'error' if object.errors.on(attribute_name)
|
36
|
+
tag_classes << options[:class] if options[:class]
|
37
|
+
tag_attributes[:class] = tag_classes.join(' ') unless tag_classes.empty?
|
38
|
+
result = haml("%input#{tag_attributes.inspect}")
|
39
|
+
result += haml("%span{:class => 'error'} #{object.errors.on(attribute_name).first}" ) if object.errors.on(attribute_name) && !options[:suppress_error_messages]
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
def textarea_for(object, attribute_name, options={})
|
44
|
+
object = instance_variable_get("@#{object}") if object.is_a?(Symbol)
|
45
|
+
return '' unless object
|
46
|
+
tag_attributes = {:name => input_name(object, attribute_name, options[:array_element])}
|
47
|
+
value = object.send(attribute_name) || ''
|
48
|
+
tag_classes = []
|
49
|
+
tag_classes << 'error' if object.errors.on(attribute_name)
|
50
|
+
tag_classes << options[:class] if options[:class]
|
51
|
+
tag_attributes[:class] = tag_classes.join(' ') unless tag_classes.empty?
|
52
|
+
"<textarea #{text_hash(tag_attributes)}>#{value}</textarea>"
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def text_hash(hash)
|
57
|
+
hash.to_a.map {|e| "#{e[0]}=\"#{e[1]}\"" }.join(' ')
|
58
|
+
end
|
59
|
+
def input_name(object, attribute_name, array)
|
60
|
+
if (array)
|
61
|
+
"#{class_name(object)}[][#{attribute_name}]"
|
62
|
+
else
|
63
|
+
"#{class_name(object)}[#{attribute_name}]"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def class_name(object)
|
67
|
+
object.class.name.split('::').last.underscore
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'haml'
|
3
|
+
require 'qcourses'
|
4
|
+
|
5
|
+
module Qcourses
|
6
|
+
class WebApp < Sinatra::Application
|
7
|
+
use Qcourses::CoursesController
|
8
|
+
use Qcourses::EventsController
|
9
|
+
use Qcourses::RegistrationsController
|
10
|
+
|
11
|
+
enable :sessions
|
12
|
+
configure :production do
|
13
|
+
end
|
14
|
+
configure :development do
|
15
|
+
enable :logging
|
16
|
+
end
|
17
|
+
helpers do
|
18
|
+
include Rack::Utils
|
19
|
+
alias_method :h, :escape_html
|
20
|
+
end
|
21
|
+
end
|
22
|
+
module Helpers
|
23
|
+
def qcourses_get(url)
|
24
|
+
Qcourses::WebApp.call(env.merge("PATH_INFO" => url)).last.join
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#Dir.glob('lib/controllers/*_controller.rb').each { |controller| require controller }
|
data/lib/qcourses.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'qcourses/configuration'
|
2
|
+
module Qcourses
|
3
|
+
def self.env
|
4
|
+
@@env ||= (ENV['RACK_ENV'] || ENV['QCOURSES_ENV'] || 'development')
|
5
|
+
end
|
6
|
+
def self.config
|
7
|
+
@@config
|
8
|
+
end
|
9
|
+
def self.configure(&configuration_block)
|
10
|
+
@@config = Configuration.instance
|
11
|
+
@@config.local_root = File.expand_path('..', File.dirname(__FILE__))
|
12
|
+
self.config.configure(&configuration_block)
|
13
|
+
require 'qcourses/date_ex'
|
14
|
+
require 'qcourses/string_ex'
|
15
|
+
require 'qcourses/models'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
require 'qcourses/renderers'
|
19
|
+
require 'qcourses/view_helpers'
|
20
|
+
require 'qcourses/controllers'
|
21
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
body {
|
2
|
+
width:800px;
|
3
|
+
margin: 0 auto;
|
4
|
+
font-family: Helvetica, Arial, sans-serif;
|
5
|
+
color: #737373;
|
6
|
+
}
|
7
|
+
|
8
|
+
.clear {
|
9
|
+
display: block;
|
10
|
+
clear: both;
|
11
|
+
}
|
12
|
+
|
13
|
+
|
14
|
+
.form {
|
15
|
+
background: #F4F4F4;
|
16
|
+
margin: 10px 10px;
|
17
|
+
padding: 10px 10px;
|
18
|
+
border-radius: 6px;
|
19
|
+
}
|
20
|
+
|
21
|
+
.form .label {
|
22
|
+
clear:left;
|
23
|
+
float:left;
|
24
|
+
width: 200px;
|
25
|
+
position:relative;
|
26
|
+
padding-top: 4px;
|
27
|
+
}
|
28
|
+
|
29
|
+
.form .input {
|
30
|
+
float:left;
|
31
|
+
position:relative;
|
32
|
+
}
|
33
|
+
|
34
|
+
#add-participant {
|
35
|
+
margin-left:215px;
|
36
|
+
}
|
37
|
+
|
38
|
+
span.error {
|
39
|
+
color: red;
|
40
|
+
}
|
41
|
+
|
42
|
+
fieldset {
|
43
|
+
border: 1px solid #e3e3e3;
|
44
|
+
border-radius: 3px;
|
45
|
+
}
|
46
|
+
legend {
|
47
|
+
font-size: smaller;
|
48
|
+
}
|
49
|
+
|
50
|
+
textarea, input[type="text"] {
|
51
|
+
border: 1px solid #e3e3e3;
|
52
|
+
padding: 5px 0;
|
53
|
+
width: 348px;
|
54
|
+
}
|
55
|
+
|
56
|
+
input.error {
|
57
|
+
border-color:red;
|
58
|
+
}
|
59
|
+
|
60
|
+
input.postal-code {
|
61
|
+
width: 98px;
|
62
|
+
}
|
63
|
+
|
64
|
+
input.city {
|
65
|
+
padding-left: 3px;
|
66
|
+
width: 241px;
|
67
|
+
}
|
68
|
+
|
69
|
+
textarea {
|
70
|
+
height: 3em;
|
71
|
+
}
|
72
|
+
|
73
|
+
select {
|
74
|
+
border: 1px solid #e3e3e3;
|
75
|
+
padding: 5px 0 5px 3px;
|
76
|
+
width: 200px;
|
77
|
+
}
|
78
|
+
input.date {
|
79
|
+
}
|
80
|
+
|
81
|
+
input.submit {
|
82
|
+
}
|
83
|
+
|
84
|
+
.event {border-bottom: solid lightgrey 1px; padding:3px 0px; color: #8B8B89; font-family: Lucida Grande, Lucida Sans Unicode,Arial,Helvetica,Sans,FreeSans,Jamrul,Garuda,Kalimati; line-height: 120%;}
|
85
|
+
.event .event_name {font-size: 15px; font-weight:bold; cursor: pointer; }
|
86
|
+
.event .event_subtitle {font-size:12px; margin:2px; color: #6B6B69; cursor: pointer; }
|
87
|
+
.event .event_registration {text-align:right; font-size: 12px; font-style: italic;}
|
88
|
+
.event .event_date_location {float:right; width:190px;}
|
89
|
+
.event .event_registration {float:right; width:60px;}
|
90
|
+
.event .clear {clear:both;}
|
91
|
+
|
Binary file
|