Added twitter bootstrap layout. Adapt home page.

This commit is contained in:
benni 2012-10-06 17:14:57 +02:00
parent 31735f35ab
commit f20ae890dd
18 changed files with 334 additions and 264 deletions

View file

@ -31,6 +31,9 @@ gem 'localize_input', :git => "git://github.com/bennibu/localize_input.git"
gem 'wikicloth'
gem 'daemons'
gem 'delayed_job_active_record'
gem 'twitter-bootstrap-rails'
gem 'simple-navigation'
gem 'simple-navigation-bootstrap'
group :production do
gem 'exception_notification', :require => 'exception_notifier'

View file

@ -45,6 +45,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.3.3)
commonjs (0.2.6)
daemons (1.1.9)
delayed_job (3.0.3)
activesupport (~> 3.0)
@ -76,6 +77,11 @@ GEM
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
json (1.7.5)
less (2.2.2)
commonjs (~> 0.2.6)
less-rails (2.2.3)
actionpack (>= 3.1)
less (~> 2.2.0)
libv8 (3.3.10.4)
mail (2.4.4)
i18n (>= 0.4.0)
@ -134,6 +140,10 @@ GEM
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
simple-navigation (3.9.0)
activesupport (>= 2.3.2)
simple-navigation-bootstrap (0.0.4)
simple-navigation (>= 3.7.0)
simple_form (2.0.3)
actionpack (~> 3.0)
activemodel (~> 3.0)
@ -149,6 +159,11 @@ GEM
polyglot
polyglot (>= 0.3.1)
ttfunk (1.0.3)
twitter-bootstrap-rails (2.1.3)
actionpack (>= 3.1)
less-rails (~> 2.2.3)
railties (>= 3.1)
therubyracer (~> 0.10.2)
tzinfo (0.3.33)
uglifier (1.3.0)
execjs (>= 0.3.0)
@ -178,8 +193,11 @@ DEPENDENCIES
rails (= 3.2.8)
rails3_acts_as_paranoid (~> 0.1.4)
sass-rails (~> 3.2.3)
simple-navigation
simple-navigation-bootstrap
simple_form
therubyracer
twitter-bootstrap-rails
uglifier (>= 1.0.3)
wikicloth
will_paginate (~> 3.0.pre2)

View file

@ -1,6 +1,7 @@
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require twitter/bootstrap
//= require jquery.tokeninput
//= require jquery.observe_field
//= require jquery.fancybox-1.3.4.pack

View file

@ -0,0 +1,4 @@
jQuery ->
$("a[rel=popover]").popover()
$(".tooltip").tooltip()
$("a[rel=tooltip]").tooltip()

View file

@ -1,8 +1,6 @@
/*
*= require main
*= require rails_messages
*= require nav
*= require simple_form
*= require bootstrap_and_overrides
*= require foodsoft
*= require token-input
*= require jquery.fancybox-1.3.4
*/

View file

@ -0,0 +1,32 @@
@import "twitter/bootstrap/bootstrap";
body {
padding-top: 60px;
}
@import "twitter/bootstrap/responsive";
// Set the correct sprite paths
@iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
@iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');
// Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
// Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
// have the proper paths. So for now we use the absolute path.
@fontAwesomeEotPath: '/assets/fontawesome-webfont.eot';
@fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff';
@fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf';
@fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg';
// Font Awesome
@import "fontawesome";
// 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/less.html for their names and documentation
//
// Example:
// @linkColor: #ff0000;

View file

@ -0,0 +1,5 @@
section {
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px solid #d3d3d3;
}

View file

@ -1,14 +1,10 @@
Engagement Deiner Bestellgruppe
.stats-bar{style: "width:#{apple_bar.length_of_group_bar}px; background-color:#{apple_bar.group_bar_color}"}
= apple_bar.apples
= " Äpfel" if apple_bar.length_of_group_bar > 50
Durchschnittsengagement
.stats-bar{style: "width:#{apple_bar.length_of_global_bar}px"}
100 Birnen
Deine aktueller Äpfelpunktestand: #{apple_bar.apples}
.progress
%div{class: "bar bar-#{apple_bar.group_bar_state}", style: "width: #{apple_bar.group_bar_width}%"}
%span.description
Abgebildet ist das Verhältnis von erledigten Aufgaben zu dem Bestellvolumen Deiner Bestellgruppe im Vergleich zum Durchschnitt in der Foodcoop.
Konkret: Pro #{number_to_currency(apple_bar.mean_order_amount_per_job, :precision => 0 )} Bestellsumme solltest Du eine Aufgabe machen!
- if FoodsoftConfig[:stop_ordering_under].present?
Achtung, hast Du weniger als #{FoodsoftConfig[:stop_ordering_under]} Äpfel, darfst Du nicht mehr bestellen!
%strong Achtung,
hast Du weniger als #{FoodsoftConfig[:stop_ordering_under]} Äpfel, darfst Du nicht mehr bestellen!

View file

@ -1,44 +1,34 @@
%h2 Direkt zu ...
%ul
%li
Foodcoop
%ul
.well.well-small
%h3 Direkt zu ...
%ul.nav.nav-list
%li.nav-header Foodcoop
%li= link_to "Mitglieder", foodcoop_users_path
%li= link_to "Meine Aufgaben", user_tasks_path
%li= link_to "Nachricht schreiben", :controller => "messages", :action => "new"
// Orders
- has_ordergroup = !@current_user.ordergroup.nil?
- has_orders_role = @current_user.role_orders?
- if has_ordergroup || has_orders_role
%li
Bestellungen
%ul
%li.nav-header Bestellungen
- if has_ordergroup
%li= link_to "Bestellübersicht", group_orders_path
- if has_orders_role
%li= link_to "Bestellungen beenden", :controller => 'orders'
// Articles
- if @current_user.role_article_meta? || @current_user.role_suppliers?
%li
Artikelverwaltung
%ul
%li.nav-header Artikelverwaltung
%li= link_to "Artikel aktualisieren", suppliers_path
%li= link_to "Lagerverwaltung", :controller => 'stockit'
%li= link_to "Lieferanten verwalten", suppliers_path
// Finance
- if @current_user.role_finance?
%li
Finanzbereich
%ul
%li.nav-header Finanzbereich
%li= link_to "Konten aktualisieren", finance_new_transaction_collection_path
%li= link_to "Bestellungen abrechnen", finance_root_path
// Administration
- if @current_user.role_admin?
%li
Administration
%ul
%li.nav-header Administration
%li= link_to "Neue Bestellgruppe", new_admin_ordergroup_path
%li= link_to "Neues Mitglied", new_admin_user_path

View file

@ -1,17 +1,15 @@
- title t('.title')
- title t('.title'), false
#start_nav
- content_for(:sidebar) do
= render :partial => 'start_nav'
.right_column{:style => "width:70%"}
- unless @unaccepted_tasks.empty? && @next_tasks.empty? && @unassigned_tasks_number == 0
.box_title
- unless @unaccepted_tasks.empty? && @next_tasks.empty? && @unassigned_tasks_number == 0
%section.well
%h2 Aufgaben
.column_content
-unless @next_tasks.empty?
%div{:style => "float:left, margin-bottom:2em"}
%h3 Deine Aufgaben für die nächste Woche:
%table{:style => "width:25em"}
%strong Deine Aufgaben für die nächste Woche:
%table.table(style="width:25em")
-for task in @next_tasks
%tr
%td= format_date task.due_date
@ -25,54 +23,46 @@
- unless @unassigned_tasks_number == 0
%h3 Offene Aufgaben
= "Es gibt #{@unassigned_tasks_number} #{link_to 'offene Aufgabe(n)', :controller => 'tasks'}".html_safe
%p{:style => "clear:both"}= link_to "Meine Aufgaben", user_tasks_path
%p= link_to "Meine Aufgaben", user_tasks_path
- if current_user.ordergroup
// Current orders
- if current_user.ordergroup
= render :partial => 'shared/open_orders', :locals => {:ordergroup => current_user.ordergroup}
// Stats
- if current_user.ordergroup
.box_title
// Stats
- if current_user.ordergroup
%section
%h2 Engagement Deiner Bestellgruppe
.column_content
= render :partial => "apple_bar", :locals => {:apple_bar => AppleBar.new(current_user.ordergroup)}
- unless Message.public.empty?
.box_title
- unless Message.public.empty?
%section
%h2 Neuste Nachrichten
.column_content
= render :partial => 'messages/messages',
:locals => {:messages => Message.public.order('created_at DESC').limit(5), :subject_length => 70}
%br/
= link_to "Alle Nachrichten einsehen", messages_path
%p= link_to "Alle Nachrichten einsehen", messages_path
- if current_user.ordergroup
- if current_user.ordergroup
// Ordergroup overview
.box_title
%section
%h2 Meine Bestellgruppe
.column_content
%p
%b= current_user.ordergroup.name
|
Verfügbares Guthaben:
| Verfügbares Guthaben:
= number_to_currency(current_user.ordergroup.get_available_funds)
%span.description
(Letzte Aktualisierung ist
= distance_of_time_in_words(Time.now, current_user.ordergroup.account_updated) + " her)"
%small (Letzte Aktualisierung ist #{distance_of_time_in_words(Time.now, current_user.ordergroup.account_updated)} her)
%h3 Letzte Transaktionen
%table
%table.table.table-striped
%tr
%th Wann
%th Wer
%th Notiz
%th Betrag
- for ft in current_user.ordergroup.financial_transactions.limit(5)
%tr{:class => cycle('even','odd')}
%tr
%td= format_time(ft.created_on)
%td= h(ft.user.nil? ? '?' : ft.user.nick)
%td= h(ft.note)
- color = ft.amount < 0 ? 'red' : 'black'
%td{:style => "color:#{color}; width:5em", :class => "currency"}= number_to_currency(ft.amount)
%br/
= link_to "mehr ...", my_ordergroup_path
%p= link_to "Kontoauszug anzeigen", my_ordergroup_path

View file

@ -1,80 +0,0 @@
<%
u = @current_user
tabs = [
{ :name => "Start", :url => root_path, :active => ["index", "home"],
:subnav => [
{ :name => "Meine Aufgaben", :url => user_tasks_path },
{ :name => "Meine Bestellgruppe", :url => my_ordergroup_path, :access_denied? => (!u.ordergroup)},
{ :name => "Mein Profil", :url => my_profile_path}
]
},
{ :name => "Foodcoop", :url => tasks_path,
:active => ["foodcoop", "tasks", "messages", "foodcoop/ordergroups", "foodcoop/workgroups", "foodcoop/users"],
:subnav => [
{ :name => "Mitglieder", :url => foodcoop_users_path},
{ :name => "Abeitsgruppen", :url => foodcoop_workgroups_path},
{ :name => "Bestellgruppen", :url => foodcoop_ordergroups_path},
{ :name => "Nachrichten", :url => messages_path},
{ :name => "Aufgaben", :url => tasks_path}
]
},
{ :name => "Wiki", :url => wiki_path, :active => ["pages", "wiki"],
:subnav => [
{ :name => "Startseite", :url => wiki_path },
{ :name => "Alle Seiten", :url => all_pages_path }
]
},
{ :name => "Bestellungen", :url => u.ordergroup ? group_orders_path : orders_path,
:active => ["orders", "ordering"],
:subnav => [
{ :name => "Bestellen!", :url => group_orders_path },
{ :name => "Meine Bestellungen", :url => archive_group_orders_path },
{ :name => "Bestellverwaltung", :url => orders_path, :access_denied? => (!u.role_orders?) }
]
},
{ :name => "Artikel", :url => suppliers_path,
:active => ["articles", "suppliers", "deliveries", "article_categories", "stockit", "stock_takings"],
:access_denied? => (!u.role_article_meta? && !u.role_suppliers?),
:subnav => [
{ :name => "Artikel", :url => suppliers_path },
{ :name => "Lager", :url => stock_articles_path },
{ :name => "Lieferantinnen", :url => suppliers_path, :access_denied? => (!u.role_suppliers?) },
{ :name => "Kategorien", :url => article_categories_path }
]
},
{ :name => "Finanzen", :url => finance_root_path,
:active => ["finance/"],
:access_denied? => (!u.role_finance?),
:subnav => [
{ :name => "Konten verwalten", :url => finance_ordergroups_path },
{ :name => "Bestellungen abrechnen", :url => finance_balancing_path },
{ :name => "Rechnungen", :url => finance_invoices_path }
]
},
{ :name => "Administration", :url => admin_root_path,
:active => ["admin/"],
:access_denied? => (!u.role_admin?),
:subnav => [
{ :name => "Benutzerinnen", :url => admin_users_path },
{ :name => "Bestellgruppen", :url => admin_ordergroups_path },
{ :name => "Arbeitsgruppen", :url => admin_workgroups_path }
]
}
]
-%>
<ul>
<% for tab in tabs -%>
<% unless tab[:access_denied?] -%>
<li class="<%= 'current' if tab_is_active?(tab) %>">
<%= link_to tab[:name], tab[:url] %>
<ul>
<% for subtab in tab[:subnav] -%>
<% unless subtab[:access_denied?] -%>
<li><%= link_to subtab[:name], subtab[:url] %></li>
<% end -%>
<% end -%>
</ul>
</li>
<% end -%>
<% end -%>
</ul>

View file

@ -1,32 +1,58 @@
!!!
%html
!!! 5
%html(lang="en")
%head
%meta{"http-equiv" => "content-type", :content => "text/html;charset=UTF-8"}
%title= "FoodSoft - " + (yield(:title) or controller.controller_name)
= stylesheet_link_tag 'application'
= stylesheet_link_tag "print", :media => "print"
<!--[if lte IE 7]>
= stylesheet_link_tag 'ie_hacks'
<![endif]-->
= javascript_include_tag 'application'
%meta(charset="utf-8")
%meta(http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1")
%meta(name="viewport" content="width=device-width, initial-scale=1.0")
%title= content_for?(:title) ? yield(:title) : "Foodsoft"
= csrf_meta_tags
= yield(:head)
/ Le HTML5 shim, for IE6-8 support of HTML elements
/[if lt IE 9]
= javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js"
= stylesheet_link_tag "application", :media => "all"
%link(href="images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144")
%link(href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114")
%link(href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72")
%link(href="images/apple-touch-icon.png" rel="apple-touch-icon-precomposed")
%link(href="images/favicon.ico" rel="shortcut icon")
%body
#logininfo= render :partial => 'shared/loginInfo'
.row-fluid
#header
#logo
= link_to root_path do
<span>food</span>soft
%span{:style => "color:white; font-size:45%; letter-spacing: -1px;"}= FoodsoftConfig[:name]
#nav= render :partial => 'layouts/main_tabnav'
.navbar.navbar-fixed-top
.navbar-inner
.container-fluid
%a.btn.btn-navbar(data-target=".nav-collapse" data-toggle="collapse")
%span.icon-bar
%span.icon-bar
%span.icon-bar
= link_to 'Foodsoft', root_path(anchor: ''), class: 'brand'
.container.nav-collapse
= render_navigation expand_all: true, renderer: :bootstrap
#main
#content
- flash.each do |name, msg|
= content_tag :h3, msg, :id => "flash#{name.to_s.camelize}", :class => "flash #{name}"
#loader{:style => "display:none;"}= image_tag("loader.gif", :border => 0)
.container-fluid
.row-fluid
- if content_for?(:sidebar)
.span2
= yield(:sidebar)
.span10
- if show_title?
.page-header
%h1= yield(:title)
= yield
#ajax_box(style="display:none")
- else
- if show_title?
.page-header
%h1= yield(:title)
= yield
%footer
%p
Foodsoft, open source software to manage a non-profit food coop.
/
Javascripts
\==================================================
/ Placed at the end of the document so the pages load faster
= javascript_include_tag "application"

View file

@ -0,0 +1,32 @@
!!!
%html
%head
%meta{"http-equiv" => "content-type", :content => "text/html;charset=UTF-8"}
%title= "FoodSoft - " + (yield(:title) or controller.controller_name)
= stylesheet_link_tag 'application'
= stylesheet_link_tag "print", :media => "print"
<!--[if lte IE 7]>
= stylesheet_link_tag 'ie_hacks'
<![endif]-->
= javascript_include_tag 'application'
= csrf_meta_tags
= yield(:head)
%body
#logininfo= render :partial => 'shared/loginInfo'
#header
#logo
= link_to root_path do
<span>food</span>soft
%span{:style => "color:white; font-size:45%; letter-spacing: -1px;"}= FoodsoftConfig[:name]
#nav= render :partial => 'layouts/main_tabnav'
#main
#content
- flash.each do |name, msg|
= content_tag :h3, msg, :id => "flash#{name.to_s.camelize}", :class => "flash #{name}"
#loader{:style => "display:none;"}= image_tag("loader.gif", :border => 0)
- if show_title?
%h1= yield(:title)
= yield
#ajax_box(style="display:none")

View file

@ -1,9 +1,9 @@
- unless messages.empty?
%table.list
%table.table.table-striped
%tbody
- for message in messages
%tr{:class => cycle('even','odd', :name => 'messages')}
%tr
%td= format_subject(message, subject_length)
%td= h(message.sender_name)
%td= format_time(message.created_at)
%td= link_to('Antworten', new_message_path(:message => {:reply_to => message.id}))
%td= link_to 'Antworten', new_message_path(:message => {:reply_to => message.id}), class: 'btn'

View file

@ -1,11 +1,9 @@
.box_title
%section
%h2 Laufende Bestellungen
.column_content
- if ordergroup.not_enough_apples?
.warning
%p Achtung, Deine Bestellgruppe hat zu wenig Äpfel um Bestellen zu können!
.alert Achtung, Deine Bestellgruppe hat zu wenig Äpfel um Bestellen zu können!
- unless Order.open.empty?
%table.list
%table.table.table-striped
%thead
%tr
%th Lieferantin
@ -15,7 +13,7 @@
%tbody
- total = 0
- Order.open.each do |order|
%tr{:class => cycle('even', 'odd', :name => 'open_orders')}
%tr
%td= link_to_ordering(order)
%td=h format_time(order.ends) unless order.ends.nil?
- if group_order = order.group_order(ordergroup)
@ -25,8 +23,10 @@
- else
%td{:colspan => 2}
- if total > 0
%p
Gesamtsumme:
%b= number_to_currency(total)
%tfooter
%tr
%th(colspan="2")
%th Gesamtsumme:
%th= number_to_currency(total)
- else
%i Derzeit gibt es keine laufenden Bestellungen

59
config/navigation.rb Normal file
View file

@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
# Configures your navigation
SimpleNavigation::Configuration.run do |navigation|
navigation.items do |primary|
primary.dom_class = 'nav'
primary.item :foodcoop, 'Foodcoop', '#' do |subnav|
subnav.item :members, 'Mitglieder', foodcoop_users_path
subnav.item :workgroups, 'Arbeitsgruppen', foodcoop_workgroups_path
subnav.item :ordergroups, 'Bestellgruppen', foodcoop_ordergroups_path
subnav.item :messages, 'Nachrichten', messages_path
subnav.item :tasks, 'Aufgaben', tasks_path
end
primary.item :wiki, 'Wiki', '#' do |subnav|
subnav.item :wiki_home, 'Startseite', wiki_path
subnav.item :all_pages, 'Alle Seiten', all_pages_path
end
primary.item :orders, 'Bestellungen', '#' do |subnav|
subnav.item :ordering, 'Bestellen!', group_orders_path
subnav.item :ordering_archive, 'Meine Bestellungen', archive_group_orders_path
subnav.item :orders, 'Bestellverwaltung', orders_path, if: Proc.new { current_user.role_orders? }
end
primary.item :articles, 'Artikel', '#',
if: Proc.new { current_user.role_article_meta? or current_user.role_suppliers? } do |subnav|
subnav.item :suppliers, 'Lieferanten/Artikel', suppliers_path
subnav.item :stockit, 'Lager', stock_articles_path
subnav.item :categories, 'Kategorien'
end
primary.item :finance, 'Finanzen', '#', if: Proc.new { current_user.role_finance? } do |subnav|
subnav.item :accounts, 'Konten verwalten', finance_ordergroups_path
subnav.item :balancing, 'Bestellungen abrechnen', finance_balancing_path
subnav.item :invoices, 'Rechnungen', finance_invoices_path
end
primary.item :admin, 'Administration', '#', if: Proc.new { current_user.role_admin? } do |subnav|
subnav.item :users, 'Benutzerinnen', admin_users_path
subnav.item :ordergroups, 'Bestellgruppen', admin_ordergroups_path
subnav.item :workgroups, 'Arbeitsgruppen', admin_workgroups_path
end
primary.item :divider, '', '#', class: 'divider'
if FoodsoftConfig[:homepage]
primary.item :homepage, FoodsoftConfig[:name], FoodsoftConfig[:homepage]
end
primary.item :help, 'Hilfe', 'https://github.com/bennibu/foodsoft/wiki/Doku'
primary.item :feedback, 'Feedback', 'new_feedback_path', title: "Fehler gefunden? Vorschlag? Idee? Kritik?"
primary.item :nick, current_user.nick, '#' do |subnav|
subnav.item :edit_profile, 'Profil bearbeiten', my_profile_path, title: 'Profil bearbeiten'
subnav.item :logout, 'Abmelden', logout_path
end
end
end

View file

@ -1,6 +1,6 @@
class AppleBar
BAR_MAX_WITH = 600
attr_reader :ordergroup
def initialize(ordergroup)
@ordergroup = ordergroup
@ -8,32 +8,28 @@ class AppleBar
@global_avg = Ordergroup.avg_jobs_per_euro
end
def length_of_global_bar
BAR_MAX_WITH / 2.0
end
def length_of_group_bar
length = (@group_avg / @global_avg) * length_of_global_bar
length > BAR_MAX_WITH ? BAR_MAX_WITH : length
end
# Show group bar in following colors:
# Green if higher than 100
# Yellow if lower than 100 an higher than stop_ordering_under option value
# Red if below stop_ordering_under, the ordergroup isn't allowed to participate in an order anymore
def group_bar_color
def group_bar_state
if apples >= 100
"#78b74e"
'success'
else
if FoodsoftConfig[:stop_ordering_under].present? and
apples >= FoodsoftConfig[:stop_ordering_under]
'yellow'
'warning'
else
'red'
'danger'
end
end
end
# Use apples as percentage, but show at least 10 percent
def group_bar_width
@ordergroup.apples < 2 ? 2 : @ordergroup.apples
end
def mean_order_amount_per_job
(1/@global_avg).round
end