Compare commits
5 commits
0e291dc31c
...
50ad689b28
| Author | SHA1 | Date | |
|---|---|---|---|
| 50ad689b28 | |||
| 125d2714b0 | |||
| 185e47c5ff | |||
| d5f77d338b | |||
| ecb4f16ec5 |
12 changed files with 200 additions and 97 deletions
|
|
@ -46,7 +46,7 @@ GEM
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
mini_mime (1.1.5)
|
mini_mime (1.1.5)
|
||||||
mini_portile2 (2.8.8)
|
mini_portile2 (2.8.9)
|
||||||
minitest (5.25.5)
|
minitest (5.25.5)
|
||||||
mustermann (3.0.3)
|
mustermann (3.0.3)
|
||||||
ruby2_keywords (~> 0.0.1)
|
ruby2_keywords (~> 0.0.1)
|
||||||
|
|
@ -91,11 +91,8 @@ GEM
|
||||||
activerecord (>= 4.1)
|
activerecord (>= 4.1)
|
||||||
sinatra (>= 1.0)
|
sinatra (>= 1.0)
|
||||||
singleton (0.3.0)
|
singleton (0.3.0)
|
||||||
sqlite3 (2.6.0)
|
sqlite3 (2.8.1)
|
||||||
mini_portile2 (~> 2.8.0)
|
mini_portile2 (~> 2.8.0)
|
||||||
sqlite3 (2.6.0-arm64-darwin)
|
|
||||||
sqlite3 (2.6.0-x86_64-darwin)
|
|
||||||
sqlite3 (2.6.0-x86_64-linux-gnu)
|
|
||||||
text (1.3.1)
|
text (1.3.1)
|
||||||
tilt (2.6.0)
|
tilt (2.6.0)
|
||||||
timeout (0.4.3)
|
timeout (0.4.3)
|
||||||
|
|
|
||||||
5
Rakefile
5
Rakefile
|
|
@ -25,3 +25,8 @@ desc "Close votes that have expired"
|
||||||
task :close_expired_votes do
|
task :close_expired_votes do
|
||||||
close_expired_votes
|
close_expired_votes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "Send email reminders"
|
||||||
|
task :send_reminders do
|
||||||
|
send_reminders
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,5 @@ set :values, [ { :id => 1, :label => _("Awful"), :color => '#ff4500' },
|
||||||
{ :id => 5, :label => _("Good"), :color => '#228b22' },
|
{ :id => 5, :label => _("Good"), :color => '#228b22' },
|
||||||
{ :id => 6, :label => _("Very good"), :color => '#006400' } ]
|
{ :id => 6, :label => _("Very good"), :color => '#006400' } ]
|
||||||
set :expire_after, 7 * 24 * 60 * 60 # 7 days
|
set :expire_after, 7 * 24 * 60 * 60 # 7 days
|
||||||
|
set :reminders, [ { :timeout => 48 * 60 * 60 },
|
||||||
|
{ :timeout => 24 * 60 * 60 } ]
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ set :environment_variable, 'RACK_ENV'
|
||||||
|
|
||||||
every 5.minutes do
|
every 5.minutes do
|
||||||
rake "close_expired_votes"
|
rake "close_expired_votes"
|
||||||
|
rake "send_email_reminders"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
5
db/migrate/20260323215246_add_reminders_to_votes.rb.rb
Normal file
5
db/migrate/20260323215246_add_reminders_to_votes.rb.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddRemindersToVotes < ActiveRecord::Migration[7.2]
|
||||||
|
def change
|
||||||
|
add_column :votes, :reminders, :integer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.2].define(version: 2025_06_08_223006) do
|
ActiveRecord::Schema[7.2].define(version: 2026_03_23_215246) do
|
||||||
create_table "candidates", force: :cascade do |t|
|
create_table "candidates", force: :cascade do |t|
|
||||||
t.integer "vote_id"
|
t.integer "vote_id"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
|
|
@ -56,6 +56,7 @@ ActiveRecord::Schema[7.2].define(version: 2025_06_08_223006) do
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "state"
|
t.string "state"
|
||||||
|
t.integer "reminders"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_foreign_key "ratings", "votes"
|
add_foreign_key "ratings", "votes"
|
||||||
|
|
|
||||||
115
po/ca/vedia.po
115
po/ca/vedia.po
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2026-01-21 09:32-0600\n"
|
"POT-Creation-Date: 2026-03-23 18:58-0600\n"
|
||||||
"PO-Revision-Date: 2025-03-29 20:41-0600\n"
|
"PO-Revision-Date: 2025-03-29 20:41-0600\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|
@ -41,17 +41,25 @@ msgstr "Bé"
|
||||||
msgid "Very good"
|
msgid "Very good"
|
||||||
msgstr "Molt bé"
|
msgstr "Molt bé"
|
||||||
|
|
||||||
#: ../vedia.rb:143
|
#: ../vedia.rb:137
|
||||||
msgid "Incorrect email or password."
|
msgid "Incorrect email or password."
|
||||||
msgstr "Correu o contrasenya incorrecte."
|
msgstr "Correu o contrasenya incorrecte."
|
||||||
|
|
||||||
#: ../vedia.rb:170
|
#: ../vedia.rb:164
|
||||||
msgid "Reset your password"
|
msgid "Reset your password"
|
||||||
msgstr "Reiniciar contrasenya"
|
msgstr "Reiniciar contrasenya"
|
||||||
|
|
||||||
#: ../vedia.rb:582
|
#: ../vedia.rb:593
|
||||||
msgid "Results of the vote: %{t}"
|
msgid "Results of the vote '%{t}'"
|
||||||
msgstr "Resultats de la votació: %{t}"
|
msgstr "Resultats de la votació '%{t}'"
|
||||||
|
|
||||||
|
#: ../vedia.rb:613
|
||||||
|
msgid "%{m} minutes left to vote on '%{t}'"
|
||||||
|
msgstr "Queden %{m} minuts per votar en '%{t}'"
|
||||||
|
|
||||||
|
#: ../vedia.rb:615
|
||||||
|
msgid "%{h} hours left to vote on '%{t}'"
|
||||||
|
msgstr "Queden %{h} hores per votar en '%{t}'"
|
||||||
|
|
||||||
#: ../views/admin.erb:1 ../views/admin_users.erb:1 ../views/admin_votes.erb:1
|
#: ../views/admin.erb:1 ../views/admin_users.erb:1 ../views/admin_votes.erb:1
|
||||||
#: ../views/layout.erb:30
|
#: ../views/layout.erb:30
|
||||||
|
|
@ -104,7 +112,7 @@ msgid "Organized votes"
|
||||||
msgstr "Votacions organitzades"
|
msgstr "Votacions organitzades"
|
||||||
|
|
||||||
#: ../views/admin_users.erb:19 ../views/admin_users.erb:38
|
#: ../views/admin_users.erb:19 ../views/admin_users.erb:38
|
||||||
#: ../views/admin_votes.erb:27 ../views/admin_votes.erb:46
|
#: ../views/admin_votes.erb:65 ../views/admin_votes.erb:84
|
||||||
#: ../views/votes_edit.erb:32
|
#: ../views/votes_edit.erb:32
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "Suprimir"
|
msgstr "Suprimir"
|
||||||
|
|
@ -113,12 +121,12 @@ msgstr "Suprimir"
|
||||||
msgid "No vote organized."
|
msgid "No vote organized."
|
||||||
msgstr "Cap votació organitzada."
|
msgstr "Cap votació organitzada."
|
||||||
|
|
||||||
#: ../views/admin_users.erb:30 ../views/admin_votes.erb:38
|
#: ../views/admin_users.erb:30 ../views/admin_votes.erb:76
|
||||||
#: ../views/votes_show_closed.erb:165
|
#: ../views/votes_show_closed.erb:167
|
||||||
msgid "Ratings"
|
msgid "Ratings"
|
||||||
msgstr "Valoracions"
|
msgstr "Valoracions"
|
||||||
|
|
||||||
#: ../views/admin_users.erb:45 ../views/admin_votes.erb:53
|
#: ../views/admin_users.erb:45 ../views/admin_votes.erb:91
|
||||||
msgid "No rating."
|
msgid "No rating."
|
||||||
msgstr "Cap valoració."
|
msgstr "Cap valoració."
|
||||||
|
|
||||||
|
|
@ -138,29 +146,29 @@ msgstr "ID segura: %{secure_id}"
|
||||||
msgid "Description: %{description}"
|
msgid "Description: %{description}"
|
||||||
msgstr "Descripció: %{description}"
|
msgstr "Descripció: %{description}"
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:15 ../views/votes_open.erb:12
|
#: ../views/admin_votes.erb:18
|
||||||
msgid "Closing date: %{date}"
|
msgid "Closing date: "
|
||||||
msgstr "Data de tancament: %{date}"
|
msgstr "Data de tancament: "
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:15
|
#: ../views/admin_votes.erb:50
|
||||||
msgid "None"
|
msgid "Change"
|
||||||
msgstr "Cap"
|
msgstr "Canviar"
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:17
|
#: ../views/admin_votes.erb:55
|
||||||
msgid "State: %{state}"
|
msgid "State: %{state}"
|
||||||
msgstr "Estat: %{state}"
|
msgstr "Estat: %{state}"
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:19 ../views/votes_edit.erb:90
|
#: ../views/admin_votes.erb:57 ../views/votes_edit.erb:90
|
||||||
#: ../views/votes_show_closed.erb:200 ../views/votes_show_draft.erb:29
|
#: ../views/votes_show_closed.erb:206 ../views/votes_show_draft.erb:29
|
||||||
#: ../views/votes_show_open.erb:88
|
#: ../views/votes_show_open.erb:96
|
||||||
msgid "Organizers"
|
msgid "Organizers"
|
||||||
msgstr "Organitzadores"
|
msgstr "Organitzadores"
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:34
|
#: ../views/admin_votes.erb:72
|
||||||
msgid "No organizer."
|
msgid "No organizer."
|
||||||
msgstr "Cap organitzadora."
|
msgstr "Cap organitzadora."
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:60 ../views/votes_edit.erb:86
|
#: ../views/admin_votes.erb:98 ../views/votes_edit.erb:86
|
||||||
msgid "Delete vote"
|
msgid "Delete vote"
|
||||||
msgstr "Suprimir la votació"
|
msgstr "Suprimir la votació"
|
||||||
|
|
||||||
|
|
@ -204,14 +212,14 @@ msgid "Login"
|
||||||
msgstr "Connexió"
|
msgstr "Connexió"
|
||||||
|
|
||||||
#: ../views/login.erb:6 ../views/reset.erb:1 ../views/reset.erb:16
|
#: ../views/login.erb:6 ../views/reset.erb:1 ../views/reset.erb:16
|
||||||
#: ../views/reset_change.erb:1 ../views/reset_change.erb:20
|
#: ../views/reset_change.erb:1 ../views/reset_change.erb:21
|
||||||
#: ../views/reset_invalid.erb:1 ../views/reset_sent.erb:1
|
#: ../views/reset_invalid.erb:1 ../views/reset_sent.erb:1
|
||||||
msgid "Reset password"
|
msgid "Reset password"
|
||||||
msgstr "Reiniciar contrasenya"
|
msgstr "Reiniciar contrasenya"
|
||||||
|
|
||||||
#: ../views/login.erb:12 ../views/reset.erb:13 ../views/reset_change.erb:13
|
#: ../views/login.erb:12 ../views/reset.erb:13 ../views/reset_change.erb:13
|
||||||
#: ../views/signup.erb:24 ../views/votes_edit.erb:102
|
#: ../views/signup.erb:24 ../views/votes_edit.erb:102
|
||||||
#: ../views/votes_show_closed.erb:214 ../views/votes_show_open.erb:104
|
#: ../views/votes_show_closed.erb:220 ../views/votes_show_open.erb:112
|
||||||
#: ../views/votes_show_unauthenticated.erb:9
|
#: ../views/votes_show_unauthenticated.erb:9
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Correu"
|
msgstr "Correu"
|
||||||
|
|
@ -269,7 +277,8 @@ msgstr "Un compte ja existeix pel correu %{email}."
|
||||||
msgid "Voted"
|
msgid "Voted"
|
||||||
msgstr "Votat"
|
msgstr "Votat"
|
||||||
|
|
||||||
#: ../views/votes.erb:20 ../views/votes_show_open.erb:9
|
#: ../views/votes.erb:20 ../views/votes_show_closed.erb:188
|
||||||
|
#: ../views/votes_show_open.erb:9
|
||||||
msgid "Not voted"
|
msgid "Not voted"
|
||||||
msgstr "Sense votar"
|
msgstr "Sense votar"
|
||||||
|
|
||||||
|
|
@ -320,8 +329,8 @@ msgid "Open vote to participants"
|
||||||
msgstr "Obrir la votació als votants"
|
msgstr "Obrir la votació als votants"
|
||||||
|
|
||||||
#: ../views/votes_edit.erb:98 ../views/votes_edit.erb:105
|
#: ../views/votes_edit.erb:98 ../views/votes_edit.erb:105
|
||||||
#: ../views/votes_show_closed.erb:210 ../views/votes_show_closed.erb:217
|
#: ../views/votes_show_closed.erb:216 ../views/votes_show_closed.erb:223
|
||||||
#: ../views/votes_show_open.erb:100 ../views/votes_show_open.erb:107
|
#: ../views/votes_show_open.erb:108 ../views/votes_show_open.erb:115
|
||||||
msgid "Add organizer"
|
msgid "Add organizer"
|
||||||
msgstr "Afegeix organitzadora"
|
msgstr "Afegeix organitzadora"
|
||||||
|
|
||||||
|
|
@ -341,6 +350,10 @@ msgstr "Títol"
|
||||||
msgid "New vote"
|
msgid "New vote"
|
||||||
msgstr "Nova votació"
|
msgstr "Nova votació"
|
||||||
|
|
||||||
|
#: ../views/votes_open.erb:12
|
||||||
|
msgid "Closing date: %{date}"
|
||||||
|
msgstr "Data de tancament: %{date}"
|
||||||
|
|
||||||
#: ../views/votes_open.erb:14
|
#: ../views/votes_open.erb:14
|
||||||
msgid ""
|
msgid ""
|
||||||
"The vote will automatically close on that date and the results will\n"
|
"The vote will automatically close on that date and the results will\n"
|
||||||
|
|
@ -359,6 +372,14 @@ msgstr "Ja no podràs modificar o suprimir aquesta votació desprès d'obrir-la.
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancel·lar"
|
msgstr "Cancel·lar"
|
||||||
|
|
||||||
|
#: ../views/votes_reminder_email.erb:1
|
||||||
|
msgid "You haven't voted yet!"
|
||||||
|
msgstr "Encara no has votat!"
|
||||||
|
|
||||||
|
#: ../views/votes_reminder_email.erb:3
|
||||||
|
msgid "Visit this link to vote:"
|
||||||
|
msgstr "Visita aquest enllaç per votar:"
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:11
|
#: ../views/votes_show_closed.erb:11
|
||||||
msgid "Closed on %{date}"
|
msgid "Closed on %{date}"
|
||||||
msgstr "Tancada el %{date}"
|
msgstr "Tancada el %{date}"
|
||||||
|
|
@ -393,11 +414,11 @@ msgstr "Veure descripció"
|
||||||
msgid "Analyze tiebreak"
|
msgid "Analyze tiebreak"
|
||||||
msgstr "Analitzar desempat"
|
msgstr "Analitzar desempat"
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:80
|
#: ../views/votes_show_closed.erb:81
|
||||||
msgid "This candidate and the winning candidate have the same majority judgment."
|
msgid "This candidate and the winning candidate have the same majority judgment."
|
||||||
msgstr "Aquesta opció i l'opció guanyadora tenen el mateix judici majoritari."
|
msgstr "Aquesta opció i l'opció guanyadora tenen el mateix judici majoritari."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:82
|
#: ../views/votes_show_closed.erb:83
|
||||||
msgid ""
|
msgid ""
|
||||||
"To break the tie, we remove the vote that corresponds to the majority judgment"
|
"To break the tie, we remove the vote that corresponds to the majority judgment"
|
||||||
" one-by-one until one candidate has a better majority judgment than the other."
|
" one-by-one until one candidate has a better majority judgment than the other."
|
||||||
|
|
@ -405,23 +426,23 @@ msgstr ""
|
||||||
"Pel desempat, traiem el vot que correspon al judici majoritari un per un fins "
|
"Pel desempat, traiem el vot que correspon al judici majoritari un per un fins "
|
||||||
"que alguna opció tingui un millor judici majoritari que l'altre."
|
"que alguna opció tingui un millor judici majoritari que l'altre."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:84
|
#: ../views/votes_show_closed.erb:85
|
||||||
msgid "Votes for this candidate"
|
msgid "Votes for this candidate"
|
||||||
msgstr "Vots per aquesta opció"
|
msgstr "Vots per aquesta opció"
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:85
|
#: ../views/votes_show_closed.erb:86
|
||||||
msgid "Votes for the winning candidate"
|
msgid "Votes for the winning candidate"
|
||||||
msgstr "Vots per l'opció guanyadora"
|
msgstr "Vots per l'opció guanyadora"
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:99
|
#: ../views/votes_show_closed.erb:100
|
||||||
msgid ""
|
msgid ""
|
||||||
"Without removing any vote, both candidates have the same majority judgement of"
|
"Without removing any vote, both candidates have the same majority judgement of"
|
||||||
" %{current}."
|
" %{current}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Sense treure cap vot, les dues opcions tenen el mateix judici majoritari de "
|
"Sense treure cap vot, les dues opcions tenen el mateix judici majoritari de %{"
|
||||||
"%{current}."
|
"current}."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:104
|
#: ../views/votes_show_closed.erb:105
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing a vote of rating %{previous}, both candidates still have the same maj"
|
"Removing a vote of rating %{previous}, both candidates still have the same maj"
|
||||||
"ority judgement of %{current}."
|
"ority judgement of %{current}."
|
||||||
|
|
@ -429,16 +450,16 @@ msgstr ""
|
||||||
"Traient un vot de valoració %{previous}, les dues opcions encara tenen el mate"
|
"Traient un vot de valoració %{previous}, les dues opcions encara tenen el mate"
|
||||||
"ix judici majoritari de %{current}."
|
"ix judici majoritari de %{current}."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:108
|
#: ../views/votes_show_closed.erb:109
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing a vote of rating %{previous}, this candidate has a majority judgement"
|
"Removing a vote of rating %{previous}, this candidate has a majority judgement"
|
||||||
" of %{losing}, but the winning candidate has a majority judgement of %{winning"
|
" of %{losing}, but the winning candidate has a majority judgement of %{winning"
|
||||||
"}."
|
"}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Traient un vot de valoració %{previous}, aquesta opció te un judici majoritar"
|
"Traient un vot de valoració %{previous}, aquesta opció te un judici majoritari"
|
||||||
"i de %{losing} però l'opció guanyadora te un judici majoritari de %{winning}."
|
" de %{losing} però l'opció guanyadora te un judici majoritari de %{winning}."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:114
|
#: ../views/votes_show_closed.erb:115
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing another vote of rating %{previous}, both candidates still have the sa"
|
"Removing another vote of rating %{previous}, both candidates still have the sa"
|
||||||
"me majority judgement of %{current}."
|
"me majority judgement of %{current}."
|
||||||
|
|
@ -446,21 +467,21 @@ msgstr ""
|
||||||
"Traient un altre vot de valoració %{previous}, les dues opcions encara tenen e"
|
"Traient un altre vot de valoració %{previous}, les dues opcions encara tenen e"
|
||||||
"l mateix judici majoritari de %{current}."
|
"l mateix judici majoritari de %{current}."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:118
|
#: ../views/votes_show_closed.erb:119
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing another vote of rating %{previous}, this candidate has a majority jud"
|
"Removing another vote of rating %{previous}, this candidate has a majority jud"
|
||||||
"gement of %{losing}, but the winning candidate has a majority judgement of %{w"
|
"gement of %{losing}, but the winning candidate has a majority judgement of %{w"
|
||||||
"inning}."
|
"inning}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Traient un altre vot de valoració %{previous}, aquesta opció te un judici maj"
|
"Traient un altre vot de valoració %{previous}, aquesta opció te un judici majo"
|
||||||
"oritari de %{losing} però l'opció guanyadora te un judici majoritari de %{winn"
|
"ritari de %{losing} però l'opció guanyadora te un judici majoritari de %{winni"
|
||||||
"ing}."
|
"ng}."
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:170
|
#: ../views/votes_show_closed.erb:172
|
||||||
msgid "Participant"
|
msgid "Participant"
|
||||||
msgstr "Votant"
|
msgstr "Votant"
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:195
|
#: ../views/votes_show_closed.erb:201
|
||||||
msgid "Reopen voting period"
|
msgid "Reopen voting period"
|
||||||
msgstr "Reobrir el període de votació"
|
msgstr "Reobrir el període de votació"
|
||||||
|
|
||||||
|
|
@ -484,11 +505,11 @@ msgstr "Votar"
|
||||||
msgid "Participants"
|
msgid "Participants"
|
||||||
msgstr "Votants"
|
msgstr "Votants"
|
||||||
|
|
||||||
#: ../views/votes_show_open.erb:77
|
#: ../views/votes_show_open.erb:85
|
||||||
msgid "Change back to draft vote"
|
msgid "Change back to draft vote"
|
||||||
msgstr "Tornar a l'esborrany de votació"
|
msgstr "Tornar a l'esborrany de votació"
|
||||||
|
|
||||||
#: ../views/votes_show_open.erb:81
|
#: ../views/votes_show_open.erb:89
|
||||||
msgid "Close votes and show results"
|
msgid "Close votes and show results"
|
||||||
msgstr "Tancar la votació i veure els resultats"
|
msgstr "Tancar la votació i veure els resultats"
|
||||||
|
|
||||||
|
|
|
||||||
97
po/vedia.pot
97
po/vedia.pot
|
|
@ -8,8 +8,8 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2026-01-21 09:33-0600\n"
|
"POT-Creation-Date: 2026-03-23 18:58-0600\n"
|
||||||
"PO-Revision-Date: 2026-01-21 09:33-0600\n"
|
"PO-Revision-Date: 2026-03-23 18:58-0600\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
|
|
@ -42,16 +42,24 @@ msgstr ""
|
||||||
msgid "Very good"
|
msgid "Very good"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../vedia.rb:143
|
#: ../vedia.rb:137
|
||||||
msgid "Incorrect email or password."
|
msgid "Incorrect email or password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../vedia.rb:170
|
#: ../vedia.rb:164
|
||||||
msgid "Reset your password"
|
msgid "Reset your password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../vedia.rb:582
|
#: ../vedia.rb:593
|
||||||
msgid "Results of the vote: %{t}"
|
msgid "Results of the vote '%{t}'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../vedia.rb:613
|
||||||
|
msgid "%{m} minutes left to vote on '%{t}'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../vedia.rb:615
|
||||||
|
msgid "%{h} hours left to vote on '%{t}'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin.erb:1 ../views/admin_users.erb:1 ../views/admin_votes.erb:1
|
#: ../views/admin.erb:1 ../views/admin_users.erb:1 ../views/admin_votes.erb:1
|
||||||
|
|
@ -105,7 +113,7 @@ msgid "Organized votes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_users.erb:19 ../views/admin_users.erb:38
|
#: ../views/admin_users.erb:19 ../views/admin_users.erb:38
|
||||||
#: ../views/admin_votes.erb:27 ../views/admin_votes.erb:46
|
#: ../views/admin_votes.erb:65 ../views/admin_votes.erb:84
|
||||||
#: ../views/votes_edit.erb:32
|
#: ../views/votes_edit.erb:32
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -114,12 +122,12 @@ msgstr ""
|
||||||
msgid "No vote organized."
|
msgid "No vote organized."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_users.erb:30 ../views/admin_votes.erb:38
|
#: ../views/admin_users.erb:30 ../views/admin_votes.erb:76
|
||||||
#: ../views/votes_show_closed.erb:165
|
#: ../views/votes_show_closed.erb:167
|
||||||
msgid "Ratings"
|
msgid "Ratings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_users.erb:45 ../views/admin_votes.erb:53
|
#: ../views/admin_users.erb:45 ../views/admin_votes.erb:91
|
||||||
msgid "No rating."
|
msgid "No rating."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -139,29 +147,29 @@ msgstr ""
|
||||||
msgid "Description: %{description}"
|
msgid "Description: %{description}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:15 ../views/votes_open.erb:12
|
#: ../views/admin_votes.erb:18
|
||||||
msgid "Closing date: %{date}"
|
msgid "Closing date: "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:15
|
#: ../views/admin_votes.erb:50
|
||||||
msgid "None"
|
msgid "Change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:17
|
#: ../views/admin_votes.erb:55
|
||||||
msgid "State: %{state}"
|
msgid "State: %{state}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:19 ../views/votes_edit.erb:90
|
#: ../views/admin_votes.erb:57 ../views/votes_edit.erb:90
|
||||||
#: ../views/votes_show_closed.erb:200 ../views/votes_show_draft.erb:29
|
#: ../views/votes_show_closed.erb:206 ../views/votes_show_draft.erb:29
|
||||||
#: ../views/votes_show_open.erb:88
|
#: ../views/votes_show_open.erb:96
|
||||||
msgid "Organizers"
|
msgid "Organizers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:34
|
#: ../views/admin_votes.erb:72
|
||||||
msgid "No organizer."
|
msgid "No organizer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/admin_votes.erb:60 ../views/votes_edit.erb:86
|
#: ../views/admin_votes.erb:98 ../views/votes_edit.erb:86
|
||||||
msgid "Delete vote"
|
msgid "Delete vote"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -203,14 +211,14 @@ msgid "Login"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/login.erb:6 ../views/reset.erb:1 ../views/reset.erb:16
|
#: ../views/login.erb:6 ../views/reset.erb:1 ../views/reset.erb:16
|
||||||
#: ../views/reset_change.erb:1 ../views/reset_change.erb:20
|
#: ../views/reset_change.erb:1 ../views/reset_change.erb:21
|
||||||
#: ../views/reset_invalid.erb:1 ../views/reset_sent.erb:1
|
#: ../views/reset_invalid.erb:1 ../views/reset_sent.erb:1
|
||||||
msgid "Reset password"
|
msgid "Reset password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/login.erb:12 ../views/reset.erb:13 ../views/reset_change.erb:13
|
#: ../views/login.erb:12 ../views/reset.erb:13 ../views/reset_change.erb:13
|
||||||
#: ../views/signup.erb:24 ../views/votes_edit.erb:102
|
#: ../views/signup.erb:24 ../views/votes_edit.erb:102
|
||||||
#: ../views/votes_show_closed.erb:214 ../views/votes_show_open.erb:104
|
#: ../views/votes_show_closed.erb:220 ../views/votes_show_open.erb:112
|
||||||
#: ../views/votes_show_unauthenticated.erb:9
|
#: ../views/votes_show_unauthenticated.erb:9
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -266,7 +274,8 @@ msgstr ""
|
||||||
msgid "Voted"
|
msgid "Voted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes.erb:20 ../views/votes_show_open.erb:9
|
#: ../views/votes.erb:20 ../views/votes_show_closed.erb:188
|
||||||
|
#: ../views/votes_show_open.erb:9
|
||||||
msgid "Not voted"
|
msgid "Not voted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -317,8 +326,8 @@ msgid "Open vote to participants"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_edit.erb:98 ../views/votes_edit.erb:105
|
#: ../views/votes_edit.erb:98 ../views/votes_edit.erb:105
|
||||||
#: ../views/votes_show_closed.erb:210 ../views/votes_show_closed.erb:217
|
#: ../views/votes_show_closed.erb:216 ../views/votes_show_closed.erb:223
|
||||||
#: ../views/votes_show_open.erb:100 ../views/votes_show_open.erb:107
|
#: ../views/votes_show_open.erb:108 ../views/votes_show_open.erb:115
|
||||||
msgid "Add organizer"
|
msgid "Add organizer"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -338,6 +347,10 @@ msgstr ""
|
||||||
msgid "New vote"
|
msgid "New vote"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../views/votes_open.erb:12
|
||||||
|
msgid "Closing date: %{date}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_open.erb:14
|
#: ../views/votes_open.erb:14
|
||||||
msgid ""
|
msgid ""
|
||||||
"The vote will automatically close on that date and the results will\n"
|
"The vote will automatically close on that date and the results will\n"
|
||||||
|
|
@ -354,6 +367,14 @@ msgstr ""
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../views/votes_reminder_email.erb:1
|
||||||
|
msgid "You haven't voted yet!"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: ../views/votes_reminder_email.erb:3
|
||||||
|
msgid "Visit this link to vote:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:11
|
#: ../views/votes_show_closed.erb:11
|
||||||
msgid "Closed on %{date}"
|
msgid "Closed on %{date}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -385,61 +406,61 @@ msgstr ""
|
||||||
msgid "Analyze tiebreak"
|
msgid "Analyze tiebreak"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:80
|
#: ../views/votes_show_closed.erb:81
|
||||||
msgid "This candidate and the winning candidate have the same majority judgment."
|
msgid "This candidate and the winning candidate have the same majority judgment."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:82
|
#: ../views/votes_show_closed.erb:83
|
||||||
msgid ""
|
msgid ""
|
||||||
"To break the tie, we remove the vote that corresponds to the majority judgment"
|
"To break the tie, we remove the vote that corresponds to the majority judgment"
|
||||||
" one-by-one until one candidate has a better majority judgment than the other."
|
" one-by-one until one candidate has a better majority judgment than the other."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:84
|
#: ../views/votes_show_closed.erb:85
|
||||||
msgid "Votes for this candidate"
|
msgid "Votes for this candidate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:85
|
#: ../views/votes_show_closed.erb:86
|
||||||
msgid "Votes for the winning candidate"
|
msgid "Votes for the winning candidate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:99
|
#: ../views/votes_show_closed.erb:100
|
||||||
msgid ""
|
msgid ""
|
||||||
"Without removing any vote, both candidates have the same majority judgement of"
|
"Without removing any vote, both candidates have the same majority judgement of"
|
||||||
" %{current}."
|
" %{current}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:104
|
#: ../views/votes_show_closed.erb:105
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing a vote of rating %{previous}, both candidates still have the same maj"
|
"Removing a vote of rating %{previous}, both candidates still have the same maj"
|
||||||
"ority judgement of %{current}."
|
"ority judgement of %{current}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:108
|
#: ../views/votes_show_closed.erb:109
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing a vote of rating %{previous}, this candidate has a majority judgement"
|
"Removing a vote of rating %{previous}, this candidate has a majority judgement"
|
||||||
" of %{losing}, but the winning candidate has a majority judgement of %{winning"
|
" of %{losing}, but the winning candidate has a majority judgement of %{winning"
|
||||||
"}."
|
"}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:114
|
#: ../views/votes_show_closed.erb:115
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing another vote of rating %{previous}, both candidates still have the sa"
|
"Removing another vote of rating %{previous}, both candidates still have the sa"
|
||||||
"me majority judgement of %{current}."
|
"me majority judgement of %{current}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:118
|
#: ../views/votes_show_closed.erb:119
|
||||||
msgid ""
|
msgid ""
|
||||||
"Removing another vote of rating %{previous}, this candidate has a majority jud"
|
"Removing another vote of rating %{previous}, this candidate has a majority jud"
|
||||||
"gement of %{losing}, but the winning candidate has a majority judgement of %{w"
|
"gement of %{losing}, but the winning candidate has a majority judgement of %{w"
|
||||||
"inning}."
|
"inning}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:170
|
#: ../views/votes_show_closed.erb:172
|
||||||
msgid "Participant"
|
msgid "Participant"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_closed.erb:195
|
#: ../views/votes_show_closed.erb:201
|
||||||
msgid "Reopen voting period"
|
msgid "Reopen voting period"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -463,11 +484,11 @@ msgstr ""
|
||||||
msgid "Participants"
|
msgid "Participants"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_open.erb:77
|
#: ../views/votes_show_open.erb:85
|
||||||
msgid "Change back to draft vote"
|
msgid "Change back to draft vote"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: ../views/votes_show_open.erb:81
|
#: ../views/votes_show_open.erb:89
|
||||||
msgid "Close votes and show results"
|
msgid "Close votes and show results"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
37
vedia.rb
37
vedia.rb
|
|
@ -268,6 +268,7 @@ post '/admin/votes/:id' do
|
||||||
if (@vote.state == 'open' or @vote.state == 'closed') and new_expiry > Time.now
|
if (@vote.state == 'open' or @vote.state == 'closed') and new_expiry > Time.now
|
||||||
puts "change"
|
puts "change"
|
||||||
@vote.expire_on = new_expiry
|
@vote.expire_on = new_expiry
|
||||||
|
@vote.reminders = 0
|
||||||
@vote.state = 'open'
|
@vote.state = 'open'
|
||||||
@vote.save
|
@vote.save
|
||||||
end
|
end
|
||||||
|
|
@ -584,12 +585,12 @@ def close_expired_votes
|
||||||
puts "#{Time.now.utc} Closing vote \"#{vote.title}\" because it expired on #{vote.expire_on}..."
|
puts "#{Time.now.utc} Closing vote \"#{vote.title}\" because it expired on #{vote.expire_on}..."
|
||||||
vote.state = 'closed'
|
vote.state = 'closed'
|
||||||
vote.save
|
vote.save
|
||||||
User.all.each do |user|
|
all_users_sorted.each do |user|
|
||||||
puts "#{Time.now.utc} Sending results by email to #{user.email}..."
|
puts "#{Time.now.utc} Sending results by email to #{user.email}..."
|
||||||
mail = Mail.new
|
mail = Mail.new
|
||||||
mail.from = settings.admin_email
|
mail.from = settings.admin_email
|
||||||
mail.to = user.email
|
mail.to = user.email
|
||||||
mail.subject = _("Results of the vote: %{t}") % { t: vote.title }
|
mail.subject = _("Results of the vote '%{t}'") % { t: vote.title }
|
||||||
template = ERB.new(File.read("views/votes_close_email.erb"))
|
template = ERB.new(File.read("views/votes_close_email.erb"))
|
||||||
mail.body = template.result(binding)
|
mail.body = template.result(binding)
|
||||||
mail.deliver
|
mail.deliver
|
||||||
|
|
@ -597,6 +598,34 @@ def close_expired_votes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_reminders
|
||||||
|
Vote.where(state: 'open').each do |vote|
|
||||||
|
settings.reminders.slice(vote.reminders..settings.reminders.length-1).each do |reminder|
|
||||||
|
minutes_to_expiry = ( vote.expire_on - Time.now.utc ) / 60
|
||||||
|
if minutes_to_expiry < reminder[:timeout] / 60
|
||||||
|
all_users_sorted.each do |user|
|
||||||
|
if not vote.ratings.collect { |rating| rating.user }.include?(user)
|
||||||
|
puts "#{Time.now.utc} Sending reminder #{reminder[:template]} for '#{vote.title}' to #{user.email}..."
|
||||||
|
mail = Mail.new
|
||||||
|
mail.from = settings.admin_email
|
||||||
|
mail.to = user.email
|
||||||
|
if minutes_to_expiry < 60
|
||||||
|
mail.subject = _("%{m} minutes left to vote on '%{t}'") % { m: minutes_to_expiry.round, t: vote.title }
|
||||||
|
else
|
||||||
|
mail.subject = _("%{h} hours left to vote on '%{t}'") % { h: (minutes_to_expiry / 60).round, t: vote.title }
|
||||||
|
end
|
||||||
|
template = ERB.new(File.read("views/votes_reminder_email.erb"))
|
||||||
|
mail.body = template.result(binding)
|
||||||
|
mail.deliver
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vote.reminders = vote.reminders + 1
|
||||||
|
vote.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
helpers do
|
helpers do
|
||||||
def current_user
|
def current_user
|
||||||
if session[:user_id]
|
if session[:user_id]
|
||||||
|
|
@ -631,6 +660,10 @@ helpers do
|
||||||
@candidate = Candidate.find(params[:cid])
|
@candidate = Candidate.find(params[:cid])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def all_users_sorted
|
||||||
|
User.all.each.sort_by { |user| user.email }
|
||||||
|
end
|
||||||
|
|
||||||
def require_candidate_in_vote
|
def require_candidate_in_vote
|
||||||
redirect '/votes/' + @vote.secure_id unless @candidate.vote == @vote
|
redirect '/votes/' + @vote.secure_id unless @candidate.vote == @vote
|
||||||
end
|
end
|
||||||
|
|
|
||||||
5
views/votes_reminder_email.erb
Normal file
5
views/votes_reminder_email.erb
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<%= _("You haven't voted yet!") %>
|
||||||
|
|
||||||
|
<%= _("Visit this link to vote:") %>
|
||||||
|
|
||||||
|
<%= "#{settings.base_url}votes/#{vote.secure_id}" %>
|
||||||
|
|
@ -175,7 +175,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<% @vote.ratings.collect { |rating| rating.user }.uniq.sort_by { |user| user.email }.each do |user| %>
|
<% all_users_sorted.each do |user| %>
|
||||||
<tr>
|
<tr>
|
||||||
<td><%= user.email %></td>
|
<td><%= user.email %></td>
|
||||||
<% @vote.candidates.each do |candidate| %>
|
<% @vote.candidates.each do |candidate| %>
|
||||||
|
|
@ -183,6 +183,10 @@
|
||||||
<td class="h5">
|
<td class="h5">
|
||||||
<%= erb :rating_badge, :locals => { :value => settings.values.select { |e| e[:id] == rating.value }.first } %>
|
<%= erb :rating_badge, :locals => { :value => settings.values.select { |e| e[:id] == rating.value }.first } %>
|
||||||
</td>
|
</td>
|
||||||
|
<% else %>
|
||||||
|
<td class="h5">
|
||||||
|
<span class="badge bg-secondary"><%= _("Not voted") %></span>
|
||||||
|
</td>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,17 @@
|
||||||
<h2 class="mb-4"><%= _("Participants") + " (#{@vote.ratings.collect { |rating| rating.user }.uniq.count})" %></h2>
|
<h2 class="mb-4"><%= _("Participants") + " (#{@vote.ratings.collect { |rating| rating.user }.uniq.count})" %></h2>
|
||||||
|
|
||||||
<ul class="mb-5">
|
<ul class="mb-5">
|
||||||
<% @vote.ratings.collect { |rating| rating.user }.uniq.sort_by { |user| user.email }.each do |user| %>
|
<% all_users_sorted.each do |user| %>
|
||||||
<li><%= user.email %></li>
|
<li>
|
||||||
<% end %>
|
<% if @vote.ratings.collect { |rating| rating.user }.include?(user) %>
|
||||||
|
<span>
|
||||||
|
<% else %>
|
||||||
|
<span class="text-decoration-line-through">
|
||||||
|
<% end %>
|
||||||
|
<%= user.email %>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<% if @vote.users.exists?(current_user.id) and @vote.expire_on.nil? %>
|
<% if @vote.users.exists?(current_user.id) and @vote.expire_on.nil? %>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue