first (mostly) working version of full elections.
author<mako@atdot.cc> <>
Thu, 31 Jan 2008 03:05:21 +0000 (22:05 -0500)
committer<mako@atdot.cc> <>
Thu, 31 Jan 2008 03:05:21 +0000 (22:05 -0500)
Lots of work, the vast majority of it superficial, to get full election
support ready. The creation is still a little rough and results are not
online yet but everything else is good to go.

36 files changed:
app/controllers/election_controller.rb
app/controllers/voter_controller.rb
app/models/election.rb
app/views/election/_candidate_form.rhtml
app/views/election/_candidate_line.rhtml
app/views/election/_candidate_line_edit.rhtml
app/views/election/_candidate_list.rhtml
app/views/election/_overview_form.rhtml
app/views/election/_voters_form.rhtml
app/views/election/edit_candidate.rhtml [deleted file]
app/views/election/edit_candidates.rhtml
app/views/election/edit_voters.rhtml
app/views/election/general_information.rhtml
app/views/election/list.rhtml [deleted file]
app/views/election/remind_voter.rhtml [deleted file]
app/views/election/show.rhtml
app/views/front/_basic_login.rhtml
app/views/front/_user_summary.rhtml
app/views/front/index.rhtml
app/views/quickvote/create.rhtml
app/views/quickvote/index.rhtml
app/views/voter/_sortable_vote.rhtml
app/views/voter/forgot_password.rhtml [deleted file]
app/views/voter/full_vote.rhtml
app/views/voter/index.rhtml
app/views/voter/reminder.rhtml [new file with mode: 0644]
app/views/voter/reminder_sent.rhtml [new file with mode: 0644]
app/views/voter/review.rhtml
app/views/voter/thanks.rhtml
app/views/voter_notify/reminder.rhtml
app/views/voter_notify/votestart.rhtml
config/environment.rb
config/routes.rb
public/stylesheets/main.css
public/stylesheets/quickvote.css
public/stylesheets/voter.css

index 89a2c22ef10e5b4fa588d9235f1651ba74827644..acf47ccd94e4fb928ab4eb0f6afac4d331d4a025 100644 (file)
@@ -43,6 +43,9 @@ class ElectionController < ApplicationController
   end
 
   def show
+    @sidebar_content = render_to_string :partial => 'progress',
+                                        :locals => { :page => 'review' }
+
     @election = Election.find(params[:id])
   end
 
@@ -94,34 +97,6 @@ class ElectionController < ApplicationController
     candidate.destroy
   end
 
-  def lessinfo_candidate
-    @show_details = false
-    @current_candidate = Candidate.find( params[:id] )
-    render :partial => 'candidate_line'
-  end
-
-  def moreinfo_candidate
-    @show_details = true
-    @current_candidate = Candidate.find( params[:id] )
-    render :partial => 'candidate_line'
-  end
-
-  def edit_candidate
-    @candidate = Candidate.find( params[:id] )
-    @election = @candidate.election
-  end
-
-  def update_candidate
-    @candidate = Candidate.find(params[:id])
-    @election = @candidate.election
-
-    if @candidate.update_attributes(params[:candidate])
-      redirect_to :action => 'edit_candidates', :id => @candidate.election.id
-    else
-      render :action => 'edit_candidate'
-    end
-  end
-
   def candidate_picture
     candidate = Candidate.find( params[:id] )
     send_data( candidate.picture.data,
@@ -134,10 +109,13 @@ class ElectionController < ApplicationController
   ## for a particular election
   ####################################################################
   def new_voters
-    edit_voters
+    redirect_to :action => 'edit_voters', :id => params[:id]
   end
   
   def edit_voters
+    @sidebar_content = render_to_string :partial => 'progress',
+                                        :locals => { :page => 'voters' }
+
     @election = Election.find( params[:id] )
     if params.has_key?( :raw_voter_list )
       process_incoming_voters( params[:raw_voter_list] )
@@ -150,14 +128,6 @@ class ElectionController < ApplicationController
     voter.destroy
   end
   
-  def remind_voter
-    voter_array= FullVoter.find(:all, :conditions => ["email = ?", params[:email]])
-    voter_array.delete_if {|voter| voter.election.active == 0}
-    unless voter_array.empty?
-      VoterNotify.deliver_reminder(voter_array)
-    end
-  end
-  
   ## methods for computing and printing results
   ####################################################################
   def results
index fb1bec7a0f69f84b1063b6e936722763d022b8f3..461be29d252d480831413544e449e66bb2d024da 100644 (file)
@@ -5,12 +5,30 @@ class VoterController < ApplicationController
   require_dependency "election"
 
   def index
-    password = params[:id]
-    password = params[:vote][:password] if params[:vote]
-    if @voter = FullVoter.find(:all, :conditions => [ "password = ?", password ] )[0]
+    if params[:urlpassword]
+      password = params[:urlpassword]
+    else
+      password = nil
+    end
+
+    if @voter = FullVoter.find(:all, :conditions =>
+                                       [ "password = ?", password ] )[0]
       @voter.vote = Vote.new if @voter.vote.nil?
       @voter.vote.set_defaults! if @voter.vote.rankings.empty?
+
+      @election = @voter.election
+      @sidebar_content = render_to_string(:partial => 'sortable_vote')
       render :action => 'full_vote'
+    elsif params[:urlpassword] 
+      redirect_to :action => 'index'
+    end
+  end
+
+  def login
+    if params[:vote] and params[:vote][:password]
+      redirect_to votepassword_url( :action => 'index', :urlpassword => params[:vote][:password])
+    else
+      redirect_to :action => 'index'
     end
   end
   
@@ -33,6 +51,18 @@ class VoterController < ApplicationController
     end
   end
   
+  def reminder
+    if params[:email]
+      voter_array= FullVoter.find(:all, :conditions => ["email = ?", params[:email]])
+      voter_array.delete_if {|voter| voter.election.active == 0}
+      unless voter_array.empty?
+        VoterNotify.deliver_reminder(voter_array)
+      end
+      render :action => 'reminder_sent'
+    end
+  end
+  
+  
   private
   def authenticate
     password = params[:id]
index cd809ab5b94e28a06c6ed4cdbaaaacaf4cc90148..99d64f93cc55424b34f82dac24d0dce9a1e4fc73 100644 (file)
@@ -91,14 +91,14 @@ class Election < ActiveRecord::Base
   #Calculate results if not in memcache
   def results
     # Assignment is intentional
-    if defined? Cache and c = Cache.get("election_results:#{id}:#{self.votes.length}")
+    if Cache and c = Cache.get("election_results:#{id}:#{self.votes.length}")
       @plurality_result = c['plurality']
       @approval_result = c['approval']
       @condorcet_result = c['condorcet']
       @ssd_result = c['ssd']
       @borda_result = c['borda']
       return c
-    elsif defined? Cache
+    elsif Cache
       # memcache is available, but missed.
       results = self.results!
       Cache.set("election_results:#{id}:#{self.votes.length}", results)
index ed14dffe288b9e513b6b46a5969215bf77eecbed..fcbf0721eeec4417ca084b26edc131e016d32df7 100644 (file)
@@ -1,11 +1,11 @@
-<% %>
-
-<p>New candidate name:<br />
+<p><label for="candidate_name">Name</label><br />
 <%= text_field :candidate, :name, :size => 60 %></p>
  
-<p>Candidate description/platform (optional):<br />
+<p><label for="candidate_description">Description/Platform</label> (optional)<br />
 <%= text_area :candidate, :description, :cols => 60, :rows => 5 %></p>
 
-<p>Candidate picture (optional and < 100x100 pixels):<br />
+
+<p style="float: left;"><label for="candidate_picture">Picture</label> (optional and &lt; 100x100 pixels)<br />
 <%= file_field :candidate, :picture %></p>
 
+<div class="clear-div"></div>
index e5bcf07b22b22275675f00fa799d1857042c7d68..6b5b5530735ad8048f98d0cbb5f2f27a68d0b324 100644 (file)
@@ -1,19 +1,17 @@
 <div id="cand<%= @current_candidate.id %>">
   <li><%=h @current_candidate.name -%>
-    <% if @show_details %>
-      (<%= link_to_remote "Hide Details",
-                         :update => "cand#{@current_candidate.id}",
-                         :url => { :action => :lessinfo_candidate,
-                                      :id => @current_candidate.id } %>)
-      <br />
-      <blockquote>
-      <%=h (@current_candidate.description) %>
-      </blockquote>
-    <% else %>
-      (<%= link_to_remote "Show Details",
-                         :update => "cand#{@current_candidate.id}",
-                         :url => { :action => :moreinfo_candidate,
-                                              :id => @current_candidate.id } %>)
-    <% end %>
+    <span id="show_candidate_link_<%= @current_candidate.id %>">
+    (<%= link_to "Show Details", "#",
+         :onclick => "show_candidate_info(#{@current_candidate.id}); return false;"  %>)
+    </span>
+    <span style="display: none;" id="hide_candidate_link_<%= @current_candidate.id %>">
+    (<%= link_to "Hide Details", "#",
+         :onclick => "hide_candidate_info(#{@current_candidate.id}); return false;" %>)
+    <br />
+
+    <div style="display: none;" id="candidate_description_<%= @current_candidate.id %>">
+    <%=h (@current_candidate.description) %>
+    </>
+    </span>
   </li>
 </div>
index 61a9f6324cde461485f414975bd5f7cfdbd29783..0fd5b67ecceb0a842979c9e4a76ed1897f108c98 100644 (file)
@@ -1,29 +1,28 @@
-<% -%>
-<div id="cand<%= @current_candidate.id %>">
-<p><strong><%=h @current_candidate.name %></strong>
-  (<%= link_to_remote "Delete",
+<div class="candidate_box" id="cand<%= @current_candidate.id %>">
+  <div class="candidate_box_name"><%=h @current_candidate.name %></div>
+  <div class="candidate_box_menu">
+  <%= link_to_remote "Delete",
                        :complete => "Element.remove('cand#{@current_candidate.id}')",
                        :url => { :action => :delete_candidate,
-                      :id => @current_candidate.id } %> |
-    <%= link_to "Edit", :action => 'edit_candidate', :id =>
-    @current_candidate.id %>)<br />
-    <blockquote>
-    <table><tr><td valign="top">
-      <% if @current_candidate.picture? %>
-      <img src="<%= url_for :action => 'candidate_picture',
-                            :id => @current_candidate.id %>"
-           align="top" width="80px" />
-      <% end %>
-      </td>
-      <% if @current_candidate.description.length > 0 %>
-      <td valign="top">
-        <em>Description:</em><br />
-         <%= h(@current_candidate.description) %>
-      </td>
-      <% else %>
-      <td></td>
-      <% end %>
-    </tr></table>
-    </blockquote>
+                      :id => @current_candidate.id } %>
+   </div>
+   <div class="clear-div"></div>
+
+   <div class="candidate_box_info">
+     <div class="candidate_box_picture">
+       <% if @current_candidate.picture? %>
+       <img src="<%= url_for :action => 'candidate_picture',
+                             :id => @current_candidate.id %>" />
+       <% end %>
+     </div>
+     <div class="candidate_box_description">
+       <% if @current_candidate.description.length > 0 %>
+          <%= h(@current_candidate.description) %>
+       <% else %>
+         <!-- no description -->
+       <% end %>
+     </div>
+     <div class="clear-div"></div>
+  </div>
 </p>
 </div>
index 881c0a5fb84d466a08338d25326793fa9401e18c..2691f5bb552c6c07f382ae5664024bf2c9300daf 100644 (file)
@@ -1,7 +1,20 @@
-<% %>
 <ul id="candidate_list">
   <% @election.candidates.each do |candidate| %>
       <% @current_candidate = candidate %>
-      <%= render(:partial => 'candidate_line')%>
+      <%= render(:partial => 'election/candidate_line')%>
     <% end %>
 </ul>
+
+<script>
+function show_candidate_info(id) {
+    Element.hide($("show_candidate_link_" + id));
+    Element.show($("candidate_description_" + id));
+    Element.show($("hide_candidate_link_" + id));
+}
+
+function hide_candidate_info(id) {
+    Element.hide($("hide_candidate_link_" + id));
+    Element.hide($("candidate_description_" + id));
+    Element.show($("show_candidate_link_" + id));
+}
+</script>
index 7d575e960e5301d204e8743b23dcb4f7a6cf5d64..8efa1b3769651142c5455f41c7516be1c8618d81 100644 (file)
 <%= datetime_select :election, :startdate %></p>
 --> 
 
-<p>Election End Date<br />
+<p><label for="election_enddate">Election End Date</label><br />
 <font size="-1"><em>All elections end at 23:59.</em></font><br />
 <%= date_select :election, :enddate %></p>
 
+<p><label for="election_election_method">Election Method</label><br />
+<% type_hash = {}; ELECTION_TYPES.each {|k,v| type_hash[v] = k} %>
+<%= select_tag 'election[election_method]', options_for_select(type_hash, @election.election_method) %></p>
+
 <!--[eoform:election]-->
 
index 87df4ce71848d064aefe4fec235efe3b3a8bf50d..8130ade671508151d596998c08af3aaa4ab110a2 100644 (file)
@@ -11,4 +11,5 @@ address per line).</p>
 -->
 <%= hidden_field :raw_voter_list, :email, :value => 2 %>
 </p>
-<%= submit_tag "Add Voters" %>
+
+<p><%= submit_tag "Add Voters" %></p>
diff --git a/app/views/election/edit_candidate.rhtml b/app/views/election/edit_candidate.rhtml
deleted file mode 100644 (file)
index 7e1dd65..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<h1>Editing <%=h @candidate.name %></h1>
-
-<%= error_messages_for :candidate %>
-<% form_tag( { :action => :update_candidate, :id => @candidate.id },
-              :multipart => true ) do %>
-<%= render :partial => 'candidate_form' %>
-<%= submit_tag "Save" %>
-<% end %>
-
index dcd601a9cf72b3501061a3b18bfb83126e30367b..7e1f315c9506f86268f94046fedee7c361689ee1 100644 (file)
@@ -1,10 +1,31 @@
-<h2>Edit/Add Candidates</h2>
+<div id="title-header">
+  <span class="header">Edit Candidates</span>
+  <span class="subheader"></span>
+</div>
+
+<div class="clear-div"></div>
+
+<div class="normal-header">
+  <span class="header">Enter New Candidate</span>
+  <span class="subheader"></span>
+</div>
 
 <%= error_messages_for :candidate %>
 
-<% unless @election.candidates.empty? %>
-  <p>The following are valid options or candidates in this election:</p>
+<% form_tag( { :action => :add_candidate, :id => @election.id },
+              :multipart => true ) do %>
+<%= render :partial => 'candidate_form' %>
+<p><%= submit_tag "Add Candidate" %></p>
+<% end %>
+
 
+<div class="normal-header">
+  <span class="header">Current Candidates</span>
+  <span class="subheader"></span>
+</div>
+
+
+<% unless @election.candidates.empty? %>
   <% @election.candidates.each do |candidate| %>
     <% @current_candidate = candidate %>
     <%= render :partial => 'candidate_line_edit' %>
   <p>There are no candidates registered for this election.</p>
 <% end %>
 
-<p>Please enter new candidates below.</p>
+<div class="normal-header">
+  <span class="header">Continue</span>
+  <span class="subheader"></span>
+</div>
 
-<% form_tag( { :action => :add_candidate, :id => @election.id },
-              :multipart => true ) do %>
-<%= render :partial => 'candidate_form' %>
-<%= submit_tag "Add Candidate" %>
-<% end %>
+<p>When you are done entering candidates, please click the button below
+to proceed to the next step.</p>
 
-<%= button_to "Done!", :action => 'new_voters', :id => @election %>
+<%= button_to "Proceed to Next Step", :action => 'new_voters', :id => @election %>
index 1e98fbaf93d39ac0dd636d14fe1675749af94203..8819b952d03b158e4334d8c2115ea873506f57cb 100644 (file)
@@ -1,5 +1,7 @@
-<% @edit = true %>
-<h1>Edit Voter List</h1>
+<div id="title-header">
+  <span class="header">Edit Voter List</span>
+  <span class="subheader"></span>
+</div>
 
 <%= render :partial => 'voter_list' %>
 
@@ -7,4 +9,12 @@
 <%= render :partial => 'voters_form' %>
 <% end %>
 
-<%= button_to 'Done!', :action => 'show', :id => @election.id %>
+<div class="normal-header">
+  <span class="header">Continue</span>
+  <span class="subheader"></span>
+</div>
+
+<p>When you are done entering voters, please click the button below
+to proceed to the next step.</p>
+
+<%= button_to 'Proceed to Next Step!', :action => 'show', :id => @election.id %>
index be099531509a3de17d63227daf58093403c03f23..dd1271c8febcbd94dd916b06ecd372864ddb1ee2 100644 (file)
@@ -1,4 +1,7 @@
-<h2>Vote Overview</h2>
+<div id="title-header">
+  <span class="header">Election Overview</span>
+  <span class="subheader"></span>
+</div>
 
 <% form_tag (:action => 'create_election') do %>
   <%= render :partial => 'overview_form' %>
diff --git a/app/views/election/list.rhtml b/app/views/election/list.rhtml
deleted file mode 100644 (file)
index 321bf46..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<% %>
-<h1>Listing elections</h1>
-
-<table cellpadding="10px">
-
-<% for election in @elections %>
-  <tr>
-    <td valign="top"><h2><%=h link_to election.name, :action => 'show', :id => election %></h2>
-        <p><strong>Description:</strong></p>
-       <blockquote><%=h election.description %></blockquote>
-       
-        <p><strong>Election Information:</strong></p>
-       <ul>
-          <li><%= election.voters.length %> registered voters</li>
-          <li><%= "<strong>Not</strong> " unless election.anonymous == 1 %>Anonymous</li>
-         <li>Starts <%= election.startdate %></li>
-         <li>Ends <%= election.enddate %></li>
-        </ul> 
-    </td>
-    <td valign="top">
-        <p><strong>Candidates:</strong></p>
-       <% @election = election %><%= render :partial => 'candidate_list', :id => election.id %>
-    </td>
-    <td valign="top">
-        <%= link_to 'Destroy', { :action => 'destroy', :id => election }, :confirm => 'Are you sure?' %></td>
-  </tr>
-<% end %>
-</table>
-
-<%= link_to 'Previous page', { :page => @election_pages.current.previous } if @election_pages.current.previous %>
-<%= link_to 'Next page', { :page => @election_pages.current.next } if @election_pages.current.next %> 
-
-<br />
-
-<%= link_to 'New election', :action => 'new' %>
diff --git a/app/views/election/remind_voter.rhtml b/app/views/election/remind_voter.rhtml
deleted file mode 100644 (file)
index 40d7a20..0000000
+++ /dev/null
@@ -1 +0,0 @@
-The message has been sent, please check your inbox soon.
\ No newline at end of file
index 2a2316861f40fb95096ea7ada6b4fd1aee945572..3e636281fcccbbb099d294ea624d0e84d7aded53 100644 (file)
@@ -1,4 +1,7 @@
-<h1>Vote Information</h1>
+<div id="title-header">
+  <span class="header">Election Overview</span>
+  <span class="subheader"></span>
+</div>
 
 <% if @election.active? %>
   <div id="status">Vote is in currently in progress. Return to
@@ -8,8 +11,6 @@
   :action => 'results', :id => @election.id %>.</div>
 <% end %>
 
-<h2>Overview</h2> 
-
 <p><strong>Summary</strong></p>
 
 <blockquote>
 <p><%= link_to "Edit overview.", :action => 'edit', :id => @election.id %></p>
 <% end %>
 
-<h2>Candidates</h2> 
-<% %>
+<div class="normal-header">
+  <span class="header">Candidates</span>
+  <span class="subheader"></span>
+</div>
+
 <% unless @election.candidates.empty? %>
   <%= render :partial => 'candidate_list' %>
   <% unless @election.active %>
 
 <% end %>
 
-<h2>Voters</h2>
+<div class="normal-header">
+  <span class="header">Voters</span>
+  <span class="subheader"></span>
+</div>
 
 <% unless @election.voters.empty? %>
   <%= render :partial => 'voter_list' %>
 <% end %>
 
 <% unless @election.active? %>
-  <h2>Start Election</h2>
+
+<div class="normal-header">
+  <span class="header">Start Election</span>
+  <span class="subheader"></span>
+</div>
 
   <% if @election.start_blockers.length > 0 %>
     <p>Your vote cannot be started for the following reasons:</p>
index 16ddc8dadd89ee1baeb4b12eb68c794d2ce8cedb..bd03a9d40788a47de5270425ec5660f64b2300c8 100644 (file)
@@ -8,5 +8,5 @@
   <p><%= submit_tag 'Log in' %></p>
 <% end %>
 
-<p><%= link_to 'Lost or forgot your password?', :controller => 'account', :action => 'forgot_password' %></p>
+<!-- <p><%= link_to 'Lost or forgot your password?', :controller => 'account', :action => 'forgot_password' %></p> -->
 
index 3b541c8f49975859d28c1d49049985dac4001446..ce65bbac698f7207bca27446e0a6e081b17a4468 100644 (file)
@@ -9,3 +9,5 @@
   </ul>
 <% end %>
 
+<p><%= link_to "Create a new election", :controller => 'election', :action => 'new' %>.</p>
+
index 54e468865523fb20eb92325dec1e785f6e2e6f31..afdf35d61e9c8217479ad9a9636f2fe44faca55b 100644 (file)
@@ -5,12 +5,12 @@
   <p>If you have received an email with a token inviting you to vote in
   an ongoing election, you can log in to vote using your token below.</p>
 
-  <% form_tag(:controller => 'voter', :action => 'index') do %>
+  <% form_tag(:controller => 'voter', :action => 'login') do %>
   <p><%= text_field :vote, :password %></p>
   <p><%= submit_tag "Log In" %></p>
   <% end %>
 
-  <p><%= link_to 'Lost or forgot your token?', :controller => 'voter', :action => 'forgot_password' %></p>
+  <p><%= link_to 'Lost or forgot your token?', :controller => 'voter', :action => 'reminder' %></p>
 
   <h3>SMS Interface</h3>
   <p>For information on accessing Selectricity over email or via SMS/text messages from your mobile phone, email <%= link_to "vote\@selectricity.org", "mailto:vote@selectricity.org" %> with "help" in the body or read the <%= link_to "Selectricity Anywhere documentation", :controller => 'about', :action => 'anywhere' %>.</p>
     existing vote. You can log in <!-- or create a new account -->below.</p>
     
     <%= render :partial => 'basic_login' %>
+  
+    <p>Full elections creation is not yet public. <a
+    href="mailto:team@selectricity.org">Contact us</a> for access.</p>
+    
+    <!-- <p>If you do not yet have an account, you should <%= link_to "create
+    one", :controller => 'account', :action => 'signup' %>.</p> -->
   <% end %>
-  <p>Full elections creation is not yet public. <%= link_to("Contact us",
-   "mailto:team@selectricity.org") %> for access.</p>
+
 
   </div>
 </div>
index c05424e119bfac8b521e12eb8cd87c4916230c96..eecb4fb8ca4f44bb6e0d65142a0efd24e00f243d 100644 (file)
 
     <p><label for="quickvote_election_method">Election Method</label></p>
 
+<!--
+<% type_hash = {}; ELECTION_TYPES.each {|k,v| type_hash[v] = k} %>
+<%= select_tag 'election_election_method', options_for_select(type_hash, @quickvote.election_method) %></p>
+-->
     <p><%= quickform.select('election_method', 
         %w(ssd condorcet plurality approval borda) ) %></p>
 
index d1018cf0a1da36563edf27d2f5fedf53b13bc06b..ccc7ec62073be033e7af17ca215555be4491b5c0 100644 (file)
@@ -1,6 +1,6 @@
 <div id="title-header">
-       <span class="header">Quickvote</span>
-       <span class="subheader"><%=h @voter.election.description.capitalize %></span>
+  <span class="header">Quickvote</span>
+  <span class="subheader"><%=h @voter.election.description.capitalize %></span>
 </div>
 
 <div class="clear-div"></div>
index 512a4ee7371c301ed615cf496d478e355db12e58..2452476d7f71ed0ae26f3457d5c6a64819d95e96 100644 (file)
@@ -1,3 +1,8 @@
+<h2>Your Vote</h2>
+
+<p>Please vote by dragging items in the list below into your preferred
+order.</p>
+
 <div id="sortable_list">
 <ol id="rankings-list">
   <% for ranking in @voter.vote.rankings %>
@@ -12,3 +17,7 @@
 <%= sortable_element 'rankings-list',
     :url => { :action => "sort_candidates", :id => @voter.vote.id },
     :complete => visual_effect(:highlight, 'rankings-list') %>
+
+<div style="margin-left: 30pt;">
+<%= button_to "Confirm Vote", :action => 'review', :id => @voter.password %>
+</div>
diff --git a/app/views/voter/forgot_password.rhtml b/app/views/voter/forgot_password.rhtml
deleted file mode 100644 (file)
index 43d1d03..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<h4>Deleted your email? Lost your password?</h4>
-<p>Not to worry, enter the email at which you were supposed to receive your
-password, and we'll hook you up with a set of magic numbers that shall grant
-access to the chambers within. Hoo-rah!</p>
-
-<% form_tag :controller => 'election', :action => 'remind_voter' do %>
-
-  <p><span label for="email">Email</label></span>
-  <%= text_field_tag :email %></p>
-
-  <%= submit_tag "Submit" %>
-<% end -%>
index cfc20e3c0e40fbfd05cd935dec9238638ddfc906..5534090db12f11b5c38311dfb838e9854f98a92e 100644 (file)
@@ -1,10 +1,41 @@
-<% %>
+<div id="title-header">
+  <span class="header">Vote Recorded</span>
+  <span class="subheader"></span>
+</div>
 
-<p><strong>Election:</strong> <%= @voter.election.name %></p>
-<p><strong>Voter:</strong> <%= @voter.email %></p>
 <p><strong>Description:</strong></p>
-<blockquote><%= @voter.election.description %></blockquote>
+<p><%= @voter.election.description %></p>
 
-<%= render :partial => 'sortable_vote' %>
+<div class="normal-header">
+  <span class="header">Current Voter</span>
+  <span class="subheader"></span>
+</div>
 
-<%= button_to "Submit Vote", :action => 'review', :id => @voter.password %>
+<p><strong><%= @voter.email %></strong></p>
+
+<div class="normal-header">
+  <span class="header">Instructions</span>
+  <span class="subheader"></span>
+</div>
+
+<p>Drag and drop the items on <strong>list in the right column</strong>
+until they are in order from most preferred at the top to least
+preferred at the bottom. When you are done, press confirm to record your
+vote.</p>
+
+<div class="normal-header">
+  <span class="header">Candidate List</span>
+  <span class="subheader"></span>
+</div>
+
+<% @voter.election.candidates.each do |candidate| %>
+  <% @current_candidate = candidate %>
+
+  <div id="cand<%= @current_candidate.id %>">
+  <h3><%=h @current_candidate.name -%></h3>
+      <blockquote>
+      <%=h (@current_candidate.description) %>
+      </blockquote>
+  </div>
+    <% end %>
+</ul>
index 5c2ea2702c6e91ef88d0cb219ba165d46e06b141..e92081d4991e47bea0e993563e04eae95dcd7aa4 100644 (file)
@@ -1,8 +1,11 @@
-<% %>
+<div id="title-header">
+  <span class="header">Voter Login</span>
+  <span class="subheader"></span>
+</div>
 
 <p>Please enter your password/token to log in and vote:</p>
 
-<% form_tag(:action => 'index') do %>
+<% form_tag(:action => 'login') do %>
 <%= text_field :vote, :password %>
 <%= submit_tag "Log In" %>
 <% end %>
diff --git a/app/views/voter/reminder.rhtml b/app/views/voter/reminder.rhtml
new file mode 100644 (file)
index 0000000..ad757e4
--- /dev/null
@@ -0,0 +1,16 @@
+<div id="title-header">
+  <span class="header">Password Reminder</span>
+  <span class="subheader"></span>
+</div>
+
+<p>Enter the email at which you were supposed to receive your password,
+and we'll send you a new password over email for every election that you
+are currently registered.</p>
+
+<% form_tag :action => 'reminder' do %>
+
+  <p><span label for="email">Email</label></span>
+  <%= text_field_tag :email %></p>
+
+  <%= submit_tag "Submit" %>
+<% end -%>
diff --git a/app/views/voter/reminder_sent.rhtml b/app/views/voter/reminder_sent.rhtml
new file mode 100644 (file)
index 0000000..4bb88e8
--- /dev/null
@@ -0,0 +1,6 @@
+<div id="title-header">
+  <span class="header">Reminder Sent</span>
+  <span class="subheader"></span>
+</div>
+
+<p>The message has been sent, please check your inbox.</p>
index b8b9089f2775500478d97e8baaa17f7923d2539f..d9ecf19cdd427d9583103665a56d2d458d13f48d 100644 (file)
@@ -1,7 +1,11 @@
-<% %>
+<div id="title-header">
+  <span class="header">Review</span>
+  <span class="subheader"><%= @voter.election.name %></span>
+</div>
 
-<% %>
-<h1>Please review your vote carefully before confirming it.</h1>
+<p><strong>Your vote will not be recorded until you confirm it on this
+page.</strong> Please review your vote carefully before clicking 
+confirm.</p>
 
 <p>You have ranked the candidates in the following order (from most
 preferred to least preferred:</p>
@@ -12,21 +16,23 @@ preferred to least preferred:</p>
   <% end %>
 </ol>
 
-<table>
-<tr>
-  <td valign="top"><%= button_to 'Confirm', :action => 'confirm', :id => @voter.password %></td>
-  <td valign="top">Confirm this vote now. You will be able to go back and
-    change it.</td>
-</tr>
+<div class="normal-header">
+  <span class="header">Confirm/Discard</span>
+  <span class="subheader"></span>
+</div>
 
-<tr>
-  <td valign="top"><%= button_to 'Change', :action => 'index', :id => @voter.password %></td>
-  <td valign="top">Go back to the voting page and vote again.</td>
-</tr>
+<p>Please select from one of the following pages.</p>
 
-<tr>
-  <td valign="top"><%= button_to 'Discard', :action => 'discard' %></td>
-  <td valign="top">Discard this tentative vote and log out.</td>
-</tr>
+<div style="text-align: center;">
+  <p><%= button_to 'Confirm This Vote', :action => 'confirm', :id => @voter.password %></p>
+
+  <p>If you choose, you will be able to go back<br />and change it up until
+  the end of hte voting period.</p>
 
-</table>
+  <p><%= button_to 'Discard This Vote', votepassword_url(
+                   :action => 'index', :urlpassword => @voter.password) %></p>
+
+  <p>You will be returned to the voting page to vote<br /> again, if you choose.</p>
+
+</tr>
+</div>
index ab8992cd47345bf73a1c0ebc082b32d996a6ece5..b19cb04e694bdab2a0ae88b3e2d9e110fc6d1822 100644 (file)
@@ -1,6 +1,10 @@
-<% %>
+<div id="title-header">
+  <span class="header">Vote Recorded</span>
+  <span class="subheader"></span>
+</div>
 
-<p>Your vote has been recorded.</p>
+<p>Your vote has been recorded for the <strong><%= @voter.election.name
+%></strong>.</p>
 
 <p>Your unique token for this vote is: <strong><%= @voter.vote.token %></strong></p>
 
index 1373bc2ef2db79e42bafb4c8bda6fdde2322140c..0a9074621aec0c13c5ec04b3fd7911148f663a61 100644 (file)
@@ -1,16 +1,18 @@
 Voter!
 
-Either you or an election administrator has requested you receive a reminder for an election you've been registered in.
+Either you or an election administrator has requested you receive a
+reminder for an election you've been registered in.
+
+Here are the election(s) for which you are currently registered and your
+tokens to enter each election:
 
-Here are the election(s) for which you are currently registered and your tokens to enter each election:
 <% @voter_array.each do |voter| -%>
 <%= voter.election.name %>: <%= voter.password %>
 <% end -%>
 
-
 If you feel there is a technical error, please contact:
 
-  help@selectricity.org
+  team@selectricity.org
   (Selectricity Tech Support)
 
 Thanks and happy voting!
index f9dbfc6c90c4cc56282be87e545ed97cb4a8da7a..e2c480ff408ec5116ba821fa25ebbf71ca719f3e 100644 (file)
@@ -11,7 +11,7 @@ need to use the following token to log in to Selectricity:
   <%= @voter.password %>
 
 Alternatively, you can just click this URL:
-  http://selectricity.org<%= url_for :controller => 'voter' %>
+  <%= votepassword_url( :host => 'selectricity.org', :urlpassword => @voter.password) %>
 
 If you have any questions or if you feel you have received this message
 in error, you should contact:
@@ -21,7 +21,7 @@ in error, you should contact:
 
 Alternatively, if you feel there is a technical error, please contact:
 
-  help@selectricity.org
+  team@selectricity.org
   (Selectricity Tech Support)
 
 Thanks and happy voting!
index 3e5f1c6b4408031dbba3bdb81fd3401acbb3de00..32d313b2ed47ea9e358256050c62d6f38f1519cd 100644 (file)
@@ -59,7 +59,7 @@ end
 
 # Include your application configuration below
 
-MAIL_CONFIG = { :from => 'Selectricity <info@selectricity.org>'} 
+MAIL_CONFIG = { :from => 'Selectricity <team@selectricity.org>'} 
 
 require 'uniq_token'
 require 'randarray'
index f763da980f30581afe26449b168263812e239a0b..e2f458d3e2afeed8eea48e44df290ed4b8c0b728 100644 (file)
@@ -15,6 +15,13 @@ ActionController::Routing::Routes.draw do |map|
 
   map.connect '/sitealizer/:action', :controller => 'sitealizer' 
 
+  map.connect 'voter/:action',
+              :controller => 'voter',
+              :requirements => { :action => /(review|confirm|authenticate|index|login|reminder)/ }
+
+  map.votepassword 'voter/:urlpassword',
+                   :controller => 'voter',
+                   :action => 'index'
 
   map.connect 'quickvote/:action/:id',
                :controller => 'quickvote',
index 50863c1cadb807adf2adee481dc5e41327182068..97c684858052b9f400493531ca63a5997c4cc797 100644 (file)
@@ -246,20 +246,6 @@ blockquote {
   background-color: #f0f0f0;
 }
 
-li.moveable {
-  background-color: #E5FFCC;
-  border:1px solid #4D801A;
-  cursor: move;
-  padding: 4px;
-  margin: 4px;
-}
-
-#sortable_list {
-  font-size: 24pt;
-  display: float;
-  float: left;
-}
-
 .result_table {
  text-align: center;
  margin-bottom: 1em;
@@ -464,3 +450,34 @@ div.photo img {
  margin: 0;
  padding: 0;
 }
+
+/* main election candidate stylesheet information */
+
+.candidate_box {
+}
+.candidate_box_name {
+ float: left;
+ font-size: 1.3em;
+ font-weight: bold;
+}
+.candidate_box_menu {
+ text-align: right;
+ float: right;
+ font-size: 0.8em;
+ font-weight: bold;
+}
+.candidate_box_info {
+ margin: 0.5em 0 0.5em 3em;
+}
+/*.candidate_box_picture {
+ width: 100px;
+ float: left;
+ margin: 0 0.8em 0.5em 0;
+}*/
+.candidate_box_picture img {
+ width: 100px;
+ border: 1px solid black;
+}
+.candidate_box_description {
+ display: inline;
+}
index b18da44ee55495cdc796762e62e0f2fbd0ea6865..5b7c8b472e7ba63fc3f661137076d614ab484dc0 100644 (file)
@@ -9,3 +9,18 @@ a {
 #title-header .subheader {
        color: #74ce00;
 }
+
+#sortable_list {
+  font-size: 24pt;
+  display: float;
+  float: left;
+}
+
+li.moveable {
+  background-color: #E5FFCC;
+  border:1px solid #4D801A;
+  cursor: move;
+  padding: 4px;
+  margin: 4px;
+}
+
index 98b94dc456159ad119b348b5b2748ab557bcd2a9..5a38cae6f0edc054b19fc0f6cc630a9eba18840e 100644 (file)
@@ -10,3 +10,17 @@ a {
        color: #005cd9;
        background-color: #e5e5e5;
 }
+
+#sortable_list {
+  display: float;
+  float: left;
+}
+
+li.moveable {
+  background-color: #c0d9fb;
+  border:1px solid #005cd9;
+  cursor: move;
+  padding: 4px;
+  margin: 4px;
+}
+

Benjamin Mako Hill || Want to submit a patch?