aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rwxr-xr-x.travis/install6
-rwxr-xr-xbin/update-schema1
m---------commonlib0
-rw-r--r--conf/general.yml-example6
-rw-r--r--cpanfile6
-rw-r--r--cpanfile.snapshot184
-rw-r--r--db/downgrade_0039---0038.sql4
-rw-r--r--db/schema.sql4
-rw-r--r--db/schema_0039-social-login.sql4
-rw-r--r--locale/FixMyStreet.po4
-rw-r--r--locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po4
-rw-r--r--locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po7
-rw-r--r--perllib/FixMyStreet/App/Controller/Around.pm7
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth.pm144
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm3
-rwxr-xr-xperllib/FixMyStreet/App/Controller/FakeMapit.pm3
-rw-r--r--perllib/FixMyStreet/App/Controller/JSON.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Open311.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm149
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/Update.pm166
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm3
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Status.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Tokens.pm2
-rw-r--r--perllib/FixMyStreet/Cobrand/UK.pm1
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm10
-rw-r--r--perllib/FixMyStreet/Geocode.pm1
-rw-r--r--perllib/FixMyStreet/Map/OSM/TonerLite.pm2
-rw-r--r--perllib/FixMyStreet/TestMech.pm2
-rw-r--r--perllib/Open311/Endpoint.pm2
-rw-r--r--t/Facebook.pm52
-rw-r--r--t/app/controller/auth_social.t143
-rw-r--r--t/app/controller/page_not_found.t2
-rw-r--r--t/app/helpers/send_email.t2
-rw-r--r--t/app/load_general_config.t2
-rw-r--r--t/app/model/comment.t2
-rw-r--r--t/app/model/problem.t2
-rw-r--r--t/app/model/questionnaire.t2
-rw-r--r--t/app/model/token.t2
-rw-r--r--t/app/sendreport/email.t2
-rw-r--r--t/map/tilma/original.t2
-rw-r--r--templates/web/base/auth/general.html86
-rw-r--r--templates/web/base/js/validation_rules.html4
-rw-r--r--templates/web/base/questionnaire/index.html2
-rw-r--r--templates/web/base/report/display.html70
-rw-r--r--templates/web/base/report/display_tools.html49
-rw-r--r--templates/web/base/report/new/fill_in_details.html14
-rw-r--r--templates/web/base/report/new/fill_in_details_form.html121
-rw-r--r--templates/web/base/report/new/form_report.html67
-rw-r--r--templates/web/base/report/new/form_user_loggedout.html92
-rw-r--r--templates/web/base/report/new/form_user_loggedout_by_email.html41
-rw-r--r--templates/web/base/report/new/form_user_loggedout_email.html9
-rw-r--r--templates/web/base/report/new/form_user_loggedout_password.html24
-rw-r--r--templates/web/base/report/new/login_success_form.html18
-rw-r--r--templates/web/base/report/new/oauth_email_form.html26
-rw-r--r--templates/web/base/report/update-form.html164
-rw-r--r--templates/web/base/report/update/form_name.html21
-rw-r--r--templates/web/base/report/update/form_update.html60
-rw-r--r--templates/web/base/report/update/form_user_loggedout.html24
-rw-r--r--templates/web/base/report/update/form_user_loggedout_by_email.html17
-rw-r--r--templates/web/base/report/update/form_user_loggedout_email.html9
-rw-r--r--templates/web/base/report/update/form_user_loggedout_password.html23
-rw-r--r--web/cobrands/fixmystreet/fixmystreet.js14
-rw-r--r--web/cobrands/sass/_base.scss30
-rw-r--r--web/cobrands/sass/_h5bp.scss3
-rw-r--r--web/i/facebook-icon-32.pngbin0 -> 211 bytes
-rw-r--r--web/js/fixmystreet.js6
93 files changed, 1472 insertions, 632 deletions
diff --git a/.travis.yml b/.travis.yml
index 1f8e95d58..c0191f177 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -28,5 +28,5 @@ before_script:
- ./bin/emptyhomes/make_welsh_po
- commonlib/bin/gettext-makemo FixMyStreet
script: "bin/run-tests t"
-after_script:
+after_success:
- .travis/after_script
diff --git a/.travis/install b/.travis/install
index a9132ba82..00ef16bc8 100755
--- a/.travis/install
+++ b/.travis/install
@@ -25,4 +25,8 @@ except IOError:
os.remove(wanted_filename)
print "No cached copy found, running carton install..."
-os.system('vendor/bin/carton install --deployment')
+ret = os.system('vendor/bin/carton install --deployment')
+if ret:
+ os.system('cat ~/.cpanm/build.log')
+
+sys.exit(ret)
diff --git a/bin/update-schema b/bin/update-schema
index c6b197deb..1393178f8 100755
--- a/bin/update-schema
+++ b/bin/update-schema
@@ -194,6 +194,7 @@ else {
# By querying the database schema, we can see where we're currently at
# (assuming schema change files are never half-applied, which should be the case)
sub get_db_version {
+ return '0039' if column_exists('users', 'facebook_id');
return '0038' if column_exists('admin_log', 'time_spent');
return '0037' if table_exists('response_templates');
return '0036' if constraint_contains('problem_cobrand_check', 'a-z0-9_');
diff --git a/commonlib b/commonlib
-Subproject f87aecb7510fb6e43156328277ba4aa4b9e17d7
+Subproject b8516ca3642716852e479f9c0889d267e339b26
diff --git a/conf/general.yml-example b/conf/general.yml-example
index f16d63c70..097d81b19 100644
--- a/conf/general.yml-example
+++ b/conf/general.yml-example
@@ -164,6 +164,12 @@ RSS_LIMIT: '20'
# How many reports to show per page on the All Reports pages
ALL_REPORTS_PER_PAGE: 100
+# Social networking
+FACEBOOK_APP_ID: ''
+FACEBOOK_APP_SECRET: ''
+TWITTER_KEY: ''
+TWITTER_SECRET: ''
+
# If you wish to send email through a SMTP server elsewhere, change these
# variables. SMTP_TYPE should be one of '', 'ssl' or 'tls'.
SMTP_SMARTHOST: 'localhost'
diff --git a/cpanfile b/cpanfile
index eae53fcb1..a8592917d 100644
--- a/cpanfile
+++ b/cpanfile
@@ -59,8 +59,7 @@ requires 'HTML::Entities';
requires 'HTTP::Request::Common';
requires 'Image::Size';
requires 'IO::String';
-requires 'JSON';
-requires 'JSON::XS';
+requires 'JSON::MaybeXS';
requires 'Locale::gettext';
requires 'LWP::Simple';
requires 'LWP::UserAgent';
@@ -71,8 +70,11 @@ requires 'MooX::Types::MooseLike';
requires 'namespace::autoclean';
requires 'Net::DNS::Resolver';
requires 'Net::Domain::TLD';
+requires 'Net::Facebook::Oauth2';
+requires 'Net::OAuth';
requires 'Net::SMTP::SSL';
requires 'Net::SMTP::TLS';
+requires 'Net::Twitter::Lite::WithAPIv1_1';
requires 'Path::Class';
requires 'POSIX';
requires 'Readonly';
diff --git a/cpanfile.snapshot b/cpanfile.snapshot
index 7bf4bc0a7..7abc62713 100644
--- a/cpanfile.snapshot
+++ b/cpanfile.snapshot
@@ -857,6 +857,14 @@ DISTRIBUTIONS
Convert::NLS_DATE_FORMAT 0.05
requirements:
ExtUtils::MakeMaker 0
+ Cpanel-JSON-XS-3.0210
+ pathname: R/RU/RURBAN/Cpanel-JSON-XS-3.0210.tar.gz
+ provides:
+ Cpanel::JSON::XS 3.0210
+ requirements:
+ ExtUtils::MakeMaker 0
+ Pod::Text 2.08
+ Pod::Usage 1.33
Crypt-Eksblowfish-0.009
pathname: Z/ZE/ZEFRAM/Crypt-Eksblowfish-0.009.tar.gz
provides:
@@ -2483,6 +2491,14 @@ DISTRIBUTIONS
Digest::SHA 1
ExtUtils::MakeMaker 0
perl 5.004
+ Digest-SHA1-2.13
+ pathname: G/GA/GAAS/Digest-SHA1-2.13.tar.gz
+ provides:
+ Digest::SHA1 2.13
+ requirements:
+ Digest::base 1.00
+ ExtUtils::MakeMaker 0
+ perl 5.004
Dir-Self-0.11
pathname: M/MA/MAUKE/Dir-Self-0.11.tar.gz
provides:
@@ -3300,6 +3316,20 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 0
Test::More 0
+ JSON-MaybeXS-1.003005
+ pathname: E/ET/ETHER/JSON-MaybeXS-1.003005.tar.gz
+ provides:
+ JSON::MaybeXS 1.003005
+ requirements:
+ Carp 0
+ Cpanel::JSON::XS 2.3310
+ ExtUtils::CBuilder 0.27
+ ExtUtils::MakeMaker 0
+ File::Spec 0
+ File::Temp 0
+ JSON::PP 2.27202
+ Scalar::Util 0
+ perl 5.006
JSON-PP-2.27202
pathname: M/MA/MAKAMAKA/JSON-PP-2.27202.tar.gz
provides:
@@ -3309,14 +3339,6 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 0
Test::More 0
- JSON-XS-2.33
- pathname: M/ML/MLEHMANN/JSON-XS-2.33.tar.gz
- provides:
- JSON::XS 2.33
- JSON::XS::Boolean 2.33
- requirements:
- ExtUtils::MakeMaker 0
- common::sense 0
LWP-MediaTypes-6.02
pathname: G/GA/GAAS/LWP-MediaTypes-6.02.tar.gz
provides:
@@ -4298,6 +4320,22 @@ DISTRIBUTIONS
Carp 0
ExtUtils::MakeMaker 0
Storable 0
+ Net-Facebook-Oauth2-0.09
+ pathname: M/MA/MAMOD/Net-Facebook-Oauth2-0.09.tar.gz
+ provides:
+ MyApp::Controller::Facebook undef
+ Net::Facebook::Oauth2 0.09
+ requirements:
+ Carp 0
+ ExtUtils::MakeMaker 0
+ JSON::MaybeXS 0
+ LWP::UserAgent 0
+ Test::Exception 0
+ Test::MockModule 0
+ Test::MockObject 0
+ Test::More 0.88
+ URI 0
+ URI::Escape 0
Net-HTTP-6.06
pathname: G/GA/GAAS/Net-HTTP-6.06.tar.gz
provides:
@@ -4312,6 +4350,45 @@ DISTRIBUTIONS
IO::Select 0
IO::Socket::INET 0
perl 5.006002
+ Net-OAuth-0.28
+ pathname: K/KG/KGRENNAN/Net-OAuth-0.28.tar.gz
+ provides:
+ Net::OAuth 0.28
+ Net::OAuth::AccessToken undef
+ Net::OAuth::AccessTokenRequest undef
+ Net::OAuth::AccessTokenResponse undef
+ Net::OAuth::Client undef
+ Net::OAuth::ConsumerRequest undef
+ Net::OAuth::Message undef
+ Net::OAuth::ProtectedResourceRequest undef
+ Net::OAuth::Request 0.28
+ Net::OAuth::RequestTokenRequest undef
+ Net::OAuth::RequestTokenResponse undef
+ Net::OAuth::Response undef
+ Net::OAuth::SignatureMethod::HMAC_SHA1 undef
+ Net::OAuth::SignatureMethod::HMAC_SHA256 undef
+ Net::OAuth::SignatureMethod::PLAINTEXT undef
+ Net::OAuth::SignatureMethod::RSA_SHA1 undef
+ Net::OAuth::UserAuthRequest undef
+ Net::OAuth::UserAuthResponse undef
+ Net::OAuth::V1_0A::AccessTokenRequest undef
+ Net::OAuth::V1_0A::RequestTokenRequest undef
+ Net::OAuth::V1_0A::RequestTokenResponse undef
+ Net::OAuth::V1_0A::UserAuthResponse undef
+ Net::OAuth::XauthAccessTokenRequest undef
+ Net::OAuth::YahooAccessTokenRefreshRequest undef
+ requirements:
+ Class::Accessor 0.31
+ Class::Data::Inheritable 0.06
+ Digest::HMAC_SHA1 1.01
+ Digest::SHA 5.47
+ Digest::SHA1 2.12
+ Encode 2.35
+ LWP::UserAgent 1
+ Module::Build 0.36
+ Test::More 0.66
+ Test::Warn 0.21
+ URI::Escape 3.28
Net-SMTP-SSL-1.01
pathname: C/CW/CWEST/Net-SMTP-SSL-1.01.tar.gz
provides:
@@ -4375,6 +4452,32 @@ DISTRIBUTIONS
IO::Socket 0
POSIX 0
Socket 0
+ Net-Twitter-Lite-0.12006
+ pathname: M/MM/MMIMS/Net-Twitter-Lite-0.12006.tar.gz
+ provides:
+ Net::Twitter::Lite 0.12006
+ Net::Twitter::Lite::API::V1 0.12006
+ Net::Twitter::Lite::API::V1_1 0.12006
+ Net::Twitter::Lite::Error 0.12006
+ Net::Twitter::Lite::WithAPIv1_1 0.12006
+ Net::Twitter::Lite::WrapResult 0.12006
+ requirements:
+ Carp 0
+ Crypt::SSLeay 0.5
+ Encode 0
+ HTTP::Request::Common 0
+ JSON 2.02
+ LWP::UserAgent 2.032
+ Module::Build 0.3601
+ Net::HTTP >= 0, != 6.04, != 6.05
+ Net::Netrc 0
+ URI 1.40
+ URI::Escape 0
+ overload 0
+ parent 0
+ perl 5.005
+ strict 0
+ warnings 0
Number-Compare-0.03
pathname: R/RC/RCLAMP/Number-Compare-0.03.tar.gz
provides:
@@ -4976,6 +5079,16 @@ DISTRIBUTIONS
Test::More 0.92
Test::Warn 0
perl 5.006002
+ SUPER-1.20141117
+ pathname: C/CH/CHROMATIC/SUPER-1.20141117.tar.gz
+ provides:
+ SUPER 1.20141117
+ requirements:
+ ExtUtils::MakeMaker 0
+ Scalar::Util 1.20
+ Sub::Identify 0.03
+ Test::Simple 0.61
+ perl v5.6.2
Safe-Isa-1.000002
pathname: M/MS/MSTROUT/Safe-Isa-1.000002.tar.gz
provides:
@@ -5456,6 +5569,33 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 6.03
Test::More 0
+ Test-MockModule-0.11
+ pathname: G/GF/GFRANKS/Test-MockModule-0.11.tar.gz
+ provides:
+ Test::MockModule 0.11
+ requirements:
+ Carp 0
+ Module::Build 0.38
+ SUPER 0
+ Scalar::Util 0
+ Test::More 0.45
+ perl 5.006
+ Test-MockObject-1.20150527
+ pathname: C/CH/CHROMATIC/Test-MockObject-1.20150527.tar.gz
+ provides:
+ Test::MockObject 1.20150527
+ Test::MockObject::Extends 1.20150527
+ requirements:
+ Carp 0
+ Devel::Peek 0
+ ExtUtils::MakeMaker 0
+ Scalar::Util 0
+ Test::Builder 0
+ UNIVERSAL::can 1.20110617
+ UNIVERSAL::isa 1.20110614
+ constant 0
+ strict 0
+ warnings 0
Test-MockTime-0.12
pathname: D/DD/DDICK/Test-MockTime-0.12.tar.gz
provides:
@@ -5879,6 +6019,28 @@ DISTRIBUTIONS
Exporter::Tiny 0.026
ExtUtils::MakeMaker 6.17
perl 5.006001
+ UNIVERSAL-can-1.20140328
+ pathname: C/CH/CHROMATIC/UNIVERSAL-can-1.20140328.tar.gz
+ provides:
+ UNIVERSAL::can 1.20140328
+ requirements:
+ ExtUtils::MakeMaker 6.30
+ Scalar::Util 0
+ strict 0
+ vars 0
+ warnings 0
+ warnings::register 0
+ UNIVERSAL-isa-1.20150614
+ pathname: E/ET/ETHER/UNIVERSAL-isa-1.20150614.tar.gz
+ provides:
+ UNIVERSAL::isa 1.20150614
+ requirements:
+ ExtUtils::MakeMaker 0
+ Scalar::Util 0
+ perl 5.006002
+ strict 0
+ warnings 0
+ warnings::register 0
UNIVERSAL-require-0.13
pathname: M/MS/MSCHWERN/UNIVERSAL-require-0.13.tar.gz
provides:
@@ -6255,12 +6417,6 @@ DISTRIBUTIONS
overload 0
strict 0
warnings 0
- common-sense-3.6
- pathname: M/ML/MLEHMANN/common-sense-3.6.tar.gz
- provides:
- common::sense undef
- requirements:
- ExtUtils::MakeMaker 0
gettext-1.05
pathname: P/PV/PVANDRY/gettext-1.05.tar.gz
provides:
diff --git a/db/downgrade_0039---0038.sql b/db/downgrade_0039---0038.sql
new file mode 100644
index 000000000..62bbc42ef
--- /dev/null
+++ b/db/downgrade_0039---0038.sql
@@ -0,0 +1,4 @@
+begin;
+alter table users drop column twitter_id;
+alter table users drop column facebook_id;
+commit;
diff --git a/db/schema.sql b/db/schema.sql
index 72fccd7f3..3761553a5 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -27,7 +27,9 @@ create table users (
password text not null default '',
from_body integer,
flagged boolean not null default 'f',
- title text
+ title text,
+ twitter_id bigint unique,
+ facebook_id bigint unique
);
-- Record details of reporting bodies, including open311 configuration details
diff --git a/db/schema_0039-social-login.sql b/db/schema_0039-social-login.sql
new file mode 100644
index 000000000..ae55d5655
--- /dev/null
+++ b/db/schema_0039-social-login.sql
@@ -0,0 +1,4 @@
+begin;
+alter table users add column twitter_id bigint unique;
+alter table users add column facebook_id bigint unique;
+commit;
diff --git a/locale/FixMyStreet.po b/locale/FixMyStreet.po
index 35964c367..55bd7a978 100644
--- a/locale/FixMyStreet.po
+++ b/locale/FixMyStreet.po
@@ -3095,6 +3095,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po
index a90673b92..7d9283f33 100644
--- a/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/ar.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3873,6 +3873,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po
index e05dd6219..48a478a17 100644
--- a/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/bg_BG.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3910,6 +3910,10 @@ msgstr "Паролата Ви беше променена успешно"
msgid "Your phone number"
msgstr "Телефонен номер"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Вашият сигнал"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Вашите сигнали"
@@ -4275,6 +4279,3 @@ msgstr[1] "Все още <strong>нямаме</strong> информация за
#~ msgid "Your email address:"
#~ msgstr "Имейл адрес:"
-
-#~ msgid "Your report"
-#~ msgstr "Вашият сигнал"
diff --git a/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po
index 1980580af..22096ce9b 100644
--- a/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/cs_CZ.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3955,6 +3955,10 @@ msgstr "Vaše heslo bylo změněno"
msgid "Your phone number"
msgstr "Vaše telefonní číslo:"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Vaše hlášení"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Vaše hlášení"
@@ -4367,6 +4371,3 @@ msgstr[2] "Doposud <strong>nemáme</strong> podrobnosti o dalších úřadech,
#~ msgid "Your email address:"
#~ msgstr "Vaše e-mailová adresa:"
-
-#~ msgid "Your report"
-#~ msgstr "Vaše hlášení"
diff --git a/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po
index 322be446f..1b853b11f 100644
--- a/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/cy.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3873,6 +3873,10 @@ msgstr "Newidiwyd eich cyfrinair"
msgid "Your phone number"
msgstr "Eich rhif ffôn"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Eich adroddiad"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Eich adroddiadau"
@@ -4269,6 +4273,3 @@ msgstr[3] ""
#~ msgid "Your email address:"
#~ msgstr "Eich cyfeiriad e-bost:"
-
-#~ msgid "Your report"
-#~ msgstr "Eich adroddiad"
diff --git a/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po
index 191e7b1fb..1f09b03b9 100644
--- a/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/da_DK.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3966,6 +3966,10 @@ msgstr "Din adgangskode er blevet ændret"
msgid "Your phone number"
msgstr "Dit telefonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Dine rapporter"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Dine opdateringer"
@@ -4370,6 +4374,3 @@ msgstr[1] "Vi har endnu <strong>ikke</strong> detaljerne for de andre myndighede
#~ msgid "Your email address:"
#~ msgstr "Din e-postadresse:"
-
-#~ msgid "Your report"
-#~ msgstr "Dine rapporter"
diff --git a/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po
index 877c45126..a66aed935 100644
--- a/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/de_CH.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3809,6 +3809,10 @@ msgstr "Ihr Passwort wurde ge&auml;ndert"
msgid "Your phone number"
msgstr "Ihre Telefonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Ihre Meldung"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Ihre Meldungen"
@@ -4099,9 +4103,6 @@ msgstr[1] ""
#~ msgid "Your email address:"
#~ msgstr "Ihre E-Mail Adresse"
-#~ msgid "Your report"
-#~ msgstr "Ihre Meldung"
-
#~ msgid "Edit templates"
#~ msgstr "Vorlagen editieren"
diff --git a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po
index 87ec9a231..3bd046cdb 100644
--- a/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/de_DE.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3868,6 +3868,10 @@ msgstr "Ihr Passwort wurde ge&auml;ndert"
msgid "Your phone number"
msgstr "Ihre Telefonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Ihre Meldung"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Ihre Meldungen"
@@ -4179,6 +4183,3 @@ msgstr[1] ""
#~ msgid "Your email address:"
#~ msgstr "Ihre eMail-Adresse:"
-
-#~ msgid "Your report"
-#~ msgstr "Ihre Meldung"
diff --git a/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po
index 11ff75e60..1b28c0ff9 100644
--- a/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/el_GR.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3945,6 +3945,10 @@ msgstr "Ο κωδικός σου έχει αλλάξει"
msgid "Your phone number"
msgstr "Ο αριθμός τηλεφώνου σου"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Η αναφορά σου"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Οι αναφορές σου"
@@ -4349,6 +4353,3 @@ msgstr[1] "<strong>Δεν</strong> έχουμε ακόμη λεπτομέρει
#~ msgid "Your email address:"
#~ msgstr "Η διεύθυνση του e-mail σου:"
-
-#~ msgid "Your report"
-#~ msgstr "Η αναφορά σου"
diff --git a/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po
index f879fde30..481751c47 100644
--- a/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/es.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3980,6 +3980,10 @@ msgstr "Su contraseña ha cambiado"
msgid "Your phone number"
msgstr "Su número de teléfono"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Su notificación"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Sus notificaciones"
@@ -4384,6 +4388,3 @@ msgstr[1] "Todavía <strong>no</strong> tenemos información sobre el ayuntamien
#~ msgid "Your email address:"
#~ msgstr "Su dirección de email:"
-
-#~ msgid "Your report"
-#~ msgstr "Su notificación"
diff --git a/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po
index be127cbfa..aebef33e8 100644
--- a/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/fr_FR.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3972,6 +3972,10 @@ msgstr "Votre mot de passe a été changé"
msgid "Your phone number"
msgstr "Votre numéro de téléphone"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Votre rapport"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Vos rapports"
@@ -4376,6 +4380,3 @@ msgstr[1] "Nous n'avons pas encore de détails pour les autres administrations r
#~ msgid "Your email address:"
#~ msgstr "Votre adresse mail:"
-
-#~ msgid "Your report"
-#~ msgstr "Votre rapport"
diff --git a/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po
index dde0eb03c..6969b6ac1 100644
--- a/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/he_IL.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3845,6 +3845,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po
index 970443299..14f43cfc5 100644
--- a/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/hr.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3892,6 +3892,10 @@ msgstr "Vaša lozinka je promijenjena"
msgid "Your phone number"
msgstr "Vaš broj telefona"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Vaša prijava"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Vaše prijave"
@@ -4277,6 +4281,3 @@ msgstr[2] "Još <strong>nemamo</strong> podatke za ostala odgovorna tijela koja
#~ msgid "Your email address:"
#~ msgstr "Vaša e-mail adresa:"
-
-#~ msgid "Your report"
-#~ msgstr "Vaša prijava"
diff --git a/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po
index a1febb654..1c48611b0 100644
--- a/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/it.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3893,6 +3893,10 @@ msgstr "La tua password è stata cambiata"
msgid "Your phone number"
msgstr "Il tuo numero di telefono"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "La tua segnalazione"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Tue segnalazioni"
@@ -4264,6 +4268,3 @@ msgstr[1] "<strong>Non</strong>abbiamo ancora dettagli sugli altri comuni che co
#~ msgid "Your email address:"
#~ msgstr "Tuo indirizzo email:"
-
-#~ msgid "Your report"
-#~ msgstr "La tua segnalazione"
diff --git a/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po
index 818df538f..356ee1329 100644
--- a/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/lt_LT.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3939,6 +3939,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po
index 42205653d..765a43220 100644
--- a/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/ms.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3879,6 +3879,10 @@ msgstr "Kata laluan anda telah diubahi"
msgid "Your phone number"
msgstr "Nombor telefon anda"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Laporan anda"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Laporan anda"
@@ -4224,6 +4228,3 @@ msgstr[0] "Kita <strong>belum</strong> ada maklumat tentang majlis lain yang men
#~ msgid "Your email address:"
#~ msgstr "Alamat emel anda:"
-
-#~ msgid "Your report"
-#~ msgstr "Laporan anda"
diff --git a/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po
index dfd0c74af..b9480f1c3 100644
--- a/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/my_MM.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3886,6 +3886,10 @@ msgstr "သင္၏ စကားဝွက္ကို ေျပာင္းလ
msgid "Your phone number"
msgstr "သင္၏ ဖုန္းနံပါတ္"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "သင္၏ အစီရင္ခံစာ"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "သင္၏ အစီရင္ခံစာမ်ား"
@@ -4207,6 +4211,3 @@ msgstr[0] "ကၽြႏု္ပ္တို႔တြင္ ဒီတည္ေ
#~ msgid "Your email address:"
#~ msgstr "သင္၏ အီးေမးလ္လိပ္စာ"
-
-#~ msgid "Your report"
-#~ msgstr "သင္၏ အစီရင္ခံစာ"
diff --git a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
index 1eb9ca635..e603727b3 100644
--- a/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/nb_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3966,6 +3966,10 @@ msgstr "Ditt passord har blitt endret"
msgid "Your phone number"
msgstr "Ditt telefonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Dine rapporter"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Dine oppdateringer"
@@ -4370,6 +4374,3 @@ msgstr[1] "Vi har ennå <strong>ikke</strong> detaljene for de andre administras
#~ msgid "Your email address:"
#~ msgstr "Din e-postadresse:"
-
-#~ msgid "Your report"
-#~ msgstr "Dine rapporter"
diff --git a/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po
index 7631b6ef8..80852a82f 100644
--- a/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/nl_NL.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3873,6 +3873,10 @@ msgstr "Je wachtwoord is gewijzigd"
msgid "Your phone number"
msgstr "Je telefoonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Jouw melding"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Jouw meldingen"
@@ -4244,6 +4248,3 @@ msgstr[1] ""
#~ msgid "Your email address:"
#~ msgstr "Jouw e-mailadres:"
-
-#~ msgid "Your report"
-#~ msgstr "Jouw melding"
diff --git a/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
index 468c9afdb..e6e0ccebe 100644
--- a/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/nn_NO.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3888,6 +3888,10 @@ msgstr "Passordet ditt har vorte endra"
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Oppdateringane dine"
diff --git a/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po
index d8a83602b..6e44a8685 100644
--- a/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/pt_CV.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3911,6 +3911,10 @@ msgstr "Sua password foi alterada"
msgid "Your phone number"
msgstr "Telefone "
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Seu relatório"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Seus relatórios"
@@ -4316,6 +4320,3 @@ msgstr[1] "Fazemos <strong> não </strong> ainda tem detalhes para os outros con
#~ msgid "Your email address:"
#~ msgstr "O seu endereço de email:"
-
-#~ msgid "Your report"
-#~ msgstr "Seu relatório"
diff --git a/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po
index 32583bef2..1124609f0 100644
--- a/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/ro_RO.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3847,6 +3847,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po
index 37ff5119c..b484625a0 100644
--- a/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/ru.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3845,6 +3845,10 @@ msgstr ""
msgid "Your phone number"
msgstr ""
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr ""
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr ""
diff --git a/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po
index a4d0ad0ce..603d65cba 100644
--- a/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/sq.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3869,6 +3869,10 @@ msgstr "Fjalekalimi juaj eshte ndryshuar"
msgid "Your phone number"
msgstr "Numri juaj i telefonit"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Raporti juaj"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Raportet tuaja"
@@ -4192,6 +4196,3 @@ msgstr[1] ""
#~ msgid "Your email address:"
#~ msgstr "Email adresa juaj:"
-
-#~ msgid "Your report"
-#~ msgstr "Raporti juaj"
diff --git a/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po
index 0b2631c3f..926beac88 100644
--- a/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/sv_SE.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3897,6 +3897,10 @@ msgstr "Ditt lösenord har ändrats"
msgid "Your phone number"
msgstr "Ditt telefonnummer"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Din rapport"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Dina rapporter"
@@ -4301,6 +4305,3 @@ msgstr[1] "Kommunen på platsen har valt att inte ta emot rapporter från FixaMi
#~ msgid "Your email address:"
#~ msgstr "Din epostadress:"
-
-#~ msgid "Your report"
-#~ msgstr "Din rapport"
diff --git a/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po
index 272f73cda..371d0674a 100644
--- a/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/tr_TR.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3888,6 +3888,10 @@ msgstr "Şifren değiştirildi"
msgid "Your phone number"
msgstr "Telefon numaran"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Bildirimin"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Bildirimlerin"
@@ -4205,6 +4209,3 @@ msgstr[0] "Bahsettiğiniz alanı kapsayan ilgili diğer kurullar hakkında henü
#~ msgid "Your email address:"
#~ msgstr "E-posta adresin:"
-
-#~ msgid "Your report"
-#~ msgstr "Bildirimin"
diff --git a/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po
index 375100924..e30353c7a 100644
--- a/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/uk_UA.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3899,6 +3899,10 @@ msgstr "Ваш пароль було змінено"
msgid "Your phone number"
msgstr "Ваш телефон"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "Ваше сповіщення"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "Ваші сповіщення"
@@ -4281,6 +4285,3 @@ msgstr[2] ""
#~ msgid "Your email address:"
#~ msgstr "Ваша адреса е-пошти:"
-
-#~ msgid "Your report"
-#~ msgstr "Ваше сповіщення"
diff --git a/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po b/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po
index 0bf7f0bbb..70868e989 100644
--- a/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po
+++ b/locale/zh.UTF-8/LC_MESSAGES/FixMyStreet.po
@@ -3981,6 +3981,10 @@ msgstr "密碼已更新"
msgid "Your phone number"
msgstr "電話號碼"
+#: templates/web/base/questionnaire/index.html:14
+msgid "Your report"
+msgstr "申報"
+
#: templates/web/base/footer.html:9 templates/web/fixmystreet/footer.html:29
msgid "Your reports"
msgstr "你作的申報"
@@ -4374,6 +4378,3 @@ msgstr[0] "我們<strong>尚未<strong>有該區域其它單位之細節 "
#~ msgid "Your email address:"
#~ msgstr "您的電子郵件"
-
-#~ msgid "Your report"
-#~ msgstr "申報"
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm
index 4aa695ae5..5ccab4047 100644
--- a/perllib/FixMyStreet/App/Controller/Around.pm
+++ b/perllib/FixMyStreet/App/Controller/Around.pm
@@ -6,6 +6,7 @@ BEGIN { extends 'Catalyst::Controller'; }
use FixMyStreet::Map;
use Encode;
+use JSON::MaybeXS;
use Utils;
=head1 NAME
@@ -306,7 +307,7 @@ sub ajax : Path('/ajax') {
# JSON encode the response
my $json = { pins => $pins };
$json->{current} = $on_map_list_html if $on_map_list_html;
- my $body = JSON->new->utf8(1)->encode($json);
+ my $body = encode_json($json);
$c->res->body($body);
}
@@ -363,9 +364,7 @@ sub _geocode : Private {
$response = \@addresses;
}
- my $body = JSON->new->utf8(1)->encode(
- $response
- );
+ my $body = encode_json($response);
$c->res->body($body);
}
diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm
index 6de416c53..9e8fb29aa 100644
--- a/perllib/FixMyStreet/App/Controller/Auth.pm
+++ b/perllib/FixMyStreet/App/Controller/Auth.pm
@@ -7,7 +7,8 @@ BEGIN { extends 'Catalyst::Controller'; }
use Email::Valid;
use Net::Domain::TLD;
use mySociety::AuthToken;
-use JSON;
+use JSON::MaybeXS;
+use Net::Facebook::Oauth2;
=head1 NAME
@@ -36,6 +37,8 @@ sub general : Path : Args(0) {
return unless $c->req->method eq 'POST';
# decide which action to take
+ $c->detach('facebook_sign_in') if $c->get_param('facebook_sign_in');
+
my $clicked_password = $c->get_param('sign_in');
my $clicked_email = $c->get_param('email_sign_in');
my $data_password = $c->get_param('password_sign_in');
@@ -122,18 +125,19 @@ sub email_sign_in : Private {
if $c->get_param('password_register');
my $user = $c->model('DB::User')->new( $user_params );
- my $token_obj = $c->model('DB::Token') #
- ->create(
- {
- scope => 'email_sign_in',
- data => {
- email => $good_email,
- r => $c->get_param('r'),
- name => $c->get_param('name'),
- password => $user->password,
- }
- }
- );
+ my $token_data = {
+ email => $good_email,
+ r => $c->get_param('r'),
+ name => $c->get_param('name'),
+ password => $user->password,
+ };
+ $token_data->{facebook_id} = $c->session->{oauth}{facebook_id}
+ if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id};
+
+ my $token_obj = $c->model('DB::Token')->create({
+ scope => 'email_sign_in',
+ data => $token_data,
+ });
$c->stash->{token} = $token_obj->token;
$c->send_email( 'login.txt', { to => $good_email } );
@@ -175,6 +179,7 @@ sub token : Path('/M') : Args(1) {
my $user = $c->model('DB::User')->find_or_create( { email => $data->{email} } );
$user->name( $data->{name} ) if $data->{name};
$user->password( $data->{password}, 1 ) if $data->{password};
+ $user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id};
$user->update;
$c->authenticate( { email => $user->email }, 'no_password' );
@@ -182,6 +187,113 @@ sub token : Path('/M') : Args(1) {
$c->detach( 'redirect_on_signin', [ $data->{r} ] );
}
+=head2 facebook_sign_in
+
+Starts the Facebook authentication sequence.
+
+=cut
+
+sub fb : Private {
+ my ($self, $c) = @_;
+ Net::Facebook::Oauth2->new(
+ application_id => $c->config->{FACEBOOK_APP_ID},
+ application_secret => $c->config->{FACEBOOK_APP_SECRET},
+ callback => $c->uri_for('/auth/Facebook'),
+ );
+}
+
+sub facebook_sign_in : Private {
+ my( $self, $c ) = @_;
+
+ my $fb = $c->forward('/auth/fb');
+ my $url = $fb->get_authorization_url(scope => ['email']);
+
+ my %oauth;
+ $oauth{return_url} = $c->get_param('r');
+ $oauth{detach_to} = $c->stash->{detach_to};
+ $oauth{detach_args} = $c->stash->{detach_args};
+ $c->session->{oauth} = \%oauth;
+ $c->res->redirect($url);
+}
+
+=head2 facebook_callback
+
+Handles the Facebook callback request and completes the authentication sequence.
+
+=cut
+
+sub facebook_callback: Path('/auth/Facebook') : Args(0) {
+ my( $self, $c ) = @_;
+
+ if ( $c->get_param('error_code') ) {
+ $c->stash->{oauth_failure} = 1;
+ if ($c->session->{oauth}{detach_to}) {
+ $c->detach($c->session->{oauth}{detach_to}, $c->session->{oauth}{detach_args});
+ } else {
+ $c->stash->{template} = 'auth/general.html';
+ $c->detach;
+ }
+ }
+
+ my $fb = $c->forward('/auth/fb');
+ my $access_token;
+ eval {
+ $access_token = $fb->get_access_token(code => $c->get_param('code'));
+ };
+ if ($@) {
+ ($c->stash->{message} = $@) =~ s/at [^ ]*Auth.pm.*//;
+ $c->stash->{template} = 'errors/generic.html';
+ $c->detach;
+ }
+
+ # save this token in session
+ $c->session->{oauth}{token} = $access_token;
+
+ my $info = $fb->get('https://graph.facebook.com/me?fields=name,email')->as_hash();
+ my $name = $info->{name};
+ my $email = lc ($info->{email} || "");
+ my $uid = $info->{id};
+
+ my $user;
+ if ($email) {
+ # We've got an ID and an email address
+ # Remove any existing mention of this ID
+ my $existing = $c->model('DB::User')->find( { facebook_id => $uid } );
+ $existing->update( { facebook_id => undef } ) if $existing;
+ # Get or create a user, give it this Facebook ID
+ $user = $c->model('DB::User')->find_or_new( { email => $email } );
+ $user->facebook_id($uid);
+ $user->name($name);
+ $user->in_storage() ? $user->update : $user->insert;
+ } else {
+ # We've got an ID, but no email
+ $user = $c->model('DB::User')->find( { facebook_id => $uid } );
+ if ($user) {
+ # Matching Facebook ID in our database
+ $user->name($name);
+ $user->update;
+ } else {
+ # No matching ID, store ID for use later
+ $c->session->{oauth}{facebook_id} = $uid;
+ $c->stash->{oauth_need_email} = 1;
+ }
+ }
+
+ # If we've got here with a full user, log in
+ if ($user) {
+ $c->authenticate( { email => $user->email }, 'no_password' );
+ $c->stash->{login_success} = 1;
+ }
+
+ if ($c->session->{oauth}{detach_to}) {
+ $c->detach($c->session->{oauth}{detach_to}, $c->session->{oauth}{detach_args});
+ } elsif ($c->stash->{oauth_need_email}) {
+ $c->stash->{template} = 'auth/general.html';
+ } else {
+ $c->detach( 'redirect_on_signin', [ $c->session->{oauth}{return_url} ] );
+ }
+}
+
=head2 redirect_on_signin
Used after signing in to take the person back to where they were.
@@ -275,7 +387,7 @@ sub ajax_sign_in : Path('ajax/sign_in') {
$return->{error} = 1;
}
- my $body = JSON->new->utf8(1)->encode( $return );
+ my $body = encode_json($return);
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
@@ -287,7 +399,7 @@ sub ajax_sign_out : Path('ajax/sign_out') {
$c->logout();
- my $body = JSON->new->utf8(1)->encode( { signed_out => 1 } );
+ my $body = encode_json( { signed_out => 1 } );
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
@@ -305,7 +417,7 @@ sub ajax_check_auth : Path('ajax/check_auth') {
$code = 200;
}
- my $body = JSON->new->utf8(1)->encode( $data );
+ my $body = encode_json($data);
$c->res->content_type('application/json; charset=utf-8');
$c->res->code($code);
$c->res->body($body);
diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
index faddaa89e..9189b28e5 100644
--- a/perllib/FixMyStreet/App/Controller/Dashboard.pm
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -4,6 +4,7 @@ use namespace::autoclean;
use DateTime;
use File::Slurp;
+use JSON::MaybeXS;
BEGIN { extends 'Catalyst::Controller'; }
@@ -40,7 +41,7 @@ sub example : Local : Args(0) {
my $data = File::Slurp::read_file(
FixMyStreet->path_to( 'data/dashboard.json' )->stringify
);
- my $j = JSON->new->utf8->decode($data);
+ my $j = decode_json($data);
if ( !$c->stash->{ward} && !$c->stash->{category} ) {
$c->stash->{problems} = $j->{counts_all};
} else {
diff --git a/perllib/FixMyStreet/App/Controller/FakeMapit.pm b/perllib/FixMyStreet/App/Controller/FakeMapit.pm
index 253c75ba4..a4adadd09 100755
--- a/perllib/FixMyStreet/App/Controller/FakeMapit.pm
+++ b/perllib/FixMyStreet/App/Controller/FakeMapit.pm
@@ -1,6 +1,7 @@
package FixMyStreet::App::Controller::FakeMapit;
use Moose;
use namespace::autoclean;
+use JSON::MaybeXS;
BEGIN { extends 'Catalyst::Controller'; }
@@ -22,7 +23,7 @@ my $area = { "name" => "Everywhere", "type" => "ZZZ", "id" => 161 };
sub output : Private {
my ( $self, $c, $data ) = @_;
- my $body = JSON->new->utf8(1)->encode( $data );
+ my $body = encode_json($data);
$c->res->content_type('application/json; charset=utf-8');
$c->res->body( $body );
}
diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm
index be738bb8b..d3cd33546 100644
--- a/perllib/FixMyStreet/App/Controller/JSON.pm
+++ b/perllib/FixMyStreet/App/Controller/JSON.pm
@@ -4,7 +4,7 @@ use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller'; }
-use JSON;
+use JSON::MaybeXS;
use DateTime;
use DateTime::Format::ISO8601;
use List::MoreUtils 'uniq';
diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm
index 96066ca93..f35dc64a5 100644
--- a/perllib/FixMyStreet/App/Controller/Open311.pm
+++ b/perllib/FixMyStreet/App/Controller/Open311.pm
@@ -4,7 +4,7 @@ use utf8;
use Moose;
use namespace::autoclean;
-use JSON;
+use JSON::MaybeXS;
use XML::Simple;
use DateTime::Format::W3CDTF;
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index d7cae05d4..5cc44bb8f 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -2,6 +2,8 @@ package FixMyStreet::App::Controller::Report;
use Moose;
use namespace::autoclean;
+use JSON::MaybeXS;
+
BEGIN { extends 'Catalyst::Controller'; }
=head1 NAME
@@ -184,7 +186,7 @@ sub format_problem_for_display : Private {
if ( $c->stash->{ajax} ) {
$c->res->content_type('application/json; charset=utf-8');
- my $content = JSON->new->utf8(1)->encode(
+ my $content = encode_json(
{
report => $c->cobrand->problem_as_hashref( $problem, $c ),
updates => $c->cobrand->updates_as_hashref( $problem, $c ),
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index db524ada4..bab0f0fd0 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -12,7 +12,7 @@ use mySociety::MaPit;
use Path::Class;
use Utils;
use mySociety::EmailUtil;
-use JSON;
+use JSON::MaybeXS;
=head1 NAME
@@ -164,9 +164,7 @@ sub report_new_ajax : Path('mobile') : Args(0) {
sub send_json_response : Private {
my ( $self, $c ) = @_;
- my $body = JSON->new->utf8(1)->encode(
- $c->stash->{json_response},
- );
+ my $body = encode_json($c->stash->{json_response});
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
}
@@ -178,9 +176,7 @@ sub report_form_ajax : Path('ajax') : Args(0) {
# work out the location for this report and do some checks
if ( ! $c->forward('determine_location') ) {
- my $body = JSON->new->utf8(1)->encode( {
- error => $c->stash->{location_error},
- } );
+ my $body = encode_json({ error => $c->stash->{location_error} });
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
return;
@@ -197,7 +193,7 @@ sub report_form_ajax : Path('ajax') : Args(0) {
my $extra_titles_list = $c->cobrand->title_list($c->stash->{all_areas});
- my $body = JSON->new->utf8(1)->encode(
+ my $body = encode_json(
{
councils_text => $councils_text,
category => $category,
@@ -216,11 +212,7 @@ sub category_extras_ajax : Path('category_extras') : Args(0) {
$c->forward('initialize_report');
if ( ! $c->forward('determine_location') ) {
- my $body = JSON->new->utf8(1)->encode(
- {
- error => _("Sorry, we could not find that location."),
- }
- );
+ my $body = encode_json({ error => _("Sorry, we could not find that location.") });
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
return 1;
@@ -244,11 +236,7 @@ sub category_extras_ajax : Path('category_extras') : Args(0) {
$category_extra = $c->render_fragment( 'report/new/category_extras.html');
}
- my $body = JSON->new->utf8(1)->encode(
- {
- category_extra => $category_extra,
- }
- );
+ my $body = encode_json({ category_extra => $category_extra });
$c->res->content_type('application/json; charset=utf-8');
$c->res->body($body);
@@ -403,6 +391,12 @@ sub report_import : Path('/import') {
return 1;
}
+sub oauth_callback : Private {
+ my ( $self, $c, $token_code ) = @_;
+ $c->stash->{oauth_report} = $token_code;
+ $c->detach('report_new');
+}
+
=head2 initialize_report
Create the report and set up some basics in it. If there is a partial report
@@ -448,9 +442,6 @@ sub initialize_report : Private {
# save the token to delete at the end
$c->stash->{partial_token} = $token if $report;
- # Stash the photo IDs for "already got" display
- $c->stash->{upload_fileid} = $report->get_photoset->data;
-
} else {
# no point keeping it if it is done.
$token->delete;
@@ -458,18 +449,25 @@ sub initialize_report : Private {
}
}
- if ( !$report ) {
+ if (!$report && $c->stash->{oauth_report}) {
+ my $auth_token = $c->forward( '/tokens/load_auth_token',
+ [ $c->stash->{oauth_report}, 'problem/social' ] );
+ $report = $c->model("DB::Problem")->new($auth_token->data);
+ }
- # If we didn't find a partial then create a new one
+ if ($report) {
+ # Stash the photo IDs for "already got" display
+ $c->stash->{upload_fileid} = $report->get_photoset->data;
+ } else {
+ # If we didn't find one otherwise, start with a blank report
$report = $c->model('DB::Problem')->new( {} );
+ }
- # If we have a user logged in let's prefill some values for them.
- if ( $c->user ) {
- my $user = $c->user->obj;
- $report->user($user);
- $report->name( $user->name );
- }
-
+ # If we have a user logged in let's prefill some values for them.
+ if (!$report->user && $c->user) {
+ my $user = $c->user->obj;
+ $report->user($user);
+ $report->name( $user->name );
}
if ( $c->get_param('first_name') && $c->get_param('last_name') ) {
@@ -1001,6 +999,13 @@ sub check_for_errors : Private {
delete $field_errors{name};
}
+ # if using social login then we don't care about name and email errors
+ $c->stash->{is_social_user} = $c->get_param('facebook_sign_in') || $c->get_param('twitter_sign_in');
+ if ( $c->stash->{is_social_user} ) {
+ delete $field_errors{name};
+ delete $field_errors{email};
+ }
+
# add the photo error if there is one.
if ( my $photo_error = delete $c->stash->{photo_error} ) {
$field_errors{photo} = $photo_error;
@@ -1014,6 +1019,19 @@ sub check_for_errors : Private {
return;
}
+# Store changes in token for when token is validated.
+sub tokenize_user : Private {
+ my ($self, $c, $report) = @_;
+ $c->stash->{token_data} = {
+ name => $report->user->name,
+ phone => $report->user->phone,
+ password => $report->user->password,
+ title => $report->user->title,
+ };
+ $c->stash->{token_data}{facebook_id} = $c->session->{oauth}{facebook_id}
+ if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id};
+}
+
=head2 save_user_and_report
Save the user and the report.
@@ -1025,7 +1043,41 @@ before or they are currently logged in. Otherwise discard any changes.
sub save_user_and_report : Private {
my ( $self, $c ) = @_;
- my $report = $c->stash->{report};
+ my $report = $c->stash->{report};
+
+ # If there was a photo add that
+ if ( my $fileid = $c->stash->{upload_fileid} ) {
+ $report->photo($fileid);
+ }
+
+ # Set a default if possible
+ $report->category( _('Other') ) unless $report->category;
+
+ # Set unknown to DB unknown
+ $report->bodies_str( undef ) if $report->bodies_str eq '-1';
+
+ # if there is a Message Manager message ID, pass it back to the client view
+ if ($c->cobrand->moniker eq 'fixmybarangay' && $c->get_param('external_source_id') =~ /^\d+$/) {
+ $c->stash->{external_source_id} = $c->get_param('external_source_id');
+ $report->external_source_id( $c->get_param('external_source_id') );
+ $report->external_source( $c->config->{MESSAGE_MANAGER_URL} ) ;
+ }
+
+ if ( $c->stash->{is_social_user} ) {
+ my $token = $c->model("DB::Token")->create( {
+ scope => 'problem/social',
+ data => { $report->get_inflated_columns },
+ } );
+
+ $c->stash->{detach_to} = '/report/new/oauth_callback';
+ $c->stash->{detach_args} = [$token->token];
+
+ if ( $c->get_param('facebook_sign_in') ) {
+ $c->detach('/auth/facebook_sign_in');
+ } elsif ( $c->get_param('twitter_sign_in') ) {
+ $c->detach('/auth/twitter_sign_in');
+ }
+ }
# Save or update the user if appropriate
if ( $c->cobrand->never_confirm_reports ) {
@@ -1035,15 +1087,10 @@ sub save_user_and_report : Private {
$report->user->insert();
}
$report->confirm();
+
} elsif ( !$report->user->in_storage ) {
# User does not exist.
- # Store changes in token for when token is validated.
- $c->stash->{token_data} = {
- name => $report->user->name,
- phone => $report->user->phone,
- password => $report->user->password,
- title => $report->user->title,
- };
+ $c->forward('tokenize_user', [ $report ]);
$report->user->name( undef );
$report->user->phone( undef );
$report->user->password( '', 1 );
@@ -1060,35 +1107,11 @@ sub save_user_and_report : Private {
}
else {
# User exists and we are not logged in as them.
- # Store changes in token for when token is validated.
- $c->stash->{token_data} = {
- name => $report->user->name,
- phone => $report->user->phone,
- password => $report->user->password,
- title => $report->user->title,
- };
+ $c->forward('tokenize_user', [ $report ]);
$report->user->discard_changes();
$c->log->info($report->user->id . ' exists, but is not logged in for this report');
}
- # If there was a photo add that too
- if ( my $fileid = $c->stash->{upload_fileid} ) {
- $report->photo($fileid);
- }
-
- # Set a default if possible
- $report->category( _('Other') ) unless $report->category;
-
- # Set unknown to DB unknown
- $report->bodies_str( undef ) if $report->bodies_str eq '-1';
-
- # if there is a Message Manager message ID, pass it back to the client view
- if ($c->cobrand->moniker eq 'fixmybarangay' && $c->get_param('external_source_id') =~ /^\d+$/) {
- $c->stash->{external_source_id} = $c->get_param('external_source_id');
- $report->external_source_id( $c->get_param('external_source_id') );
- $report->external_source( $c->config->{MESSAGE_MANAGER_URL} ) ;
- }
-
# save the report;
$report->in_storage ? $report->update : $report->insert();
diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm
index 445723fec..45d924335 100644
--- a/perllib/FixMyStreet/App/Controller/Report/Update.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm
@@ -20,12 +20,16 @@ Creates an update to a report
sub report_update : Path : Args(0) {
my ( $self, $c ) = @_;
- $c->forward( '/report/load_problem_or_display_error', [ $c->get_param('id') ] );
+ $c->forward('initialize_update');
+ $c->forward('load_problem');
+ $c->forward('check_form_submitted')
+ or $c->go( '/report/display', [ $c->stash->{problem}->id ] );
+
$c->forward('process_update');
$c->forward('process_user');
$c->forward('/photo/process_photo');
$c->forward('check_for_errors')
- or $c->go( '/report/display', [ $c->get_param('id') ] );
+ or $c->go( '/report/display', [ $c->stash->{problem}->id ] );
$c->forward('save_update');
$c->forward('redirect_or_confirm_creation');
@@ -151,19 +155,46 @@ sub process_user : Private {
return 1;
}
-=head2 process_update
+=head2 oauth_callback
-Take the submitted params and create a new update item. Does not save
-anything to the database.
+Called when we successfully login via OAuth. Stores the token so we can look up
+what we have so far.
-NB: relies on their being a problem and update_user in the stash. May
-want to move adding these elsewhere
+=cut
+
+sub oauth_callback : Private {
+ my ( $self, $c, $token_code ) = @_;
+ $c->stash->{oauth_update} = $token_code;
+ $c->detach('report_update');
+}
+
+=head2 initialize_update
+
+Create an initial update object, either empty or from stored OAuth data.
=cut
-sub process_update : Private {
+sub initialize_update : Private {
my ( $self, $c ) = @_;
+ my $update;
+ if ($c->stash->{oauth_update}) {
+ my $auth_token = $c->forward( '/tokens/load_auth_token',
+ [ $c->stash->{oauth_update}, 'update/social' ] );
+ $update = $c->model("DB::Comment")->new($auth_token->data);
+ }
+
+ if ($update) {
+ $c->stash->{upload_fileid} = $update->get_photoset->data;
+ } else {
+ $update = $c->model('DB::Comment')->new({
+ state => 'unconfirmed',
+ cobrand => $c->cobrand->moniker,
+ cobrand_data => '',
+ lang => $c->stash->{lang_code},
+ });
+ }
+
if ( $c->get_param('first_name') && $c->get_param('last_name') ) {
my $first_name = $c->get_param('first_name');
my $last_name = $c->get_param('last_name');
@@ -173,6 +204,48 @@ sub process_update : Private {
$c->stash->{last_name} = $last_name;
}
+ $c->stash->{update} = $update;
+}
+
+=head2 load_problem
+
+Our update could be prefilled, or we could be submitting a form containing an
+ID. Look up the relevant report either way.
+
+=cut
+
+sub load_problem : Private {
+ my ( $self, $c ) = @_;
+
+ my $update = $c->stash->{update};
+ # Problem ID could come from existing update in token, or from query parameter
+ my $problem_id = $update->problem_id || $c->get_param('id');
+ $c->forward( '/report/load_problem_or_display_error', [ $problem_id ] );
+ $update->problem($c->stash->{problem});
+}
+
+=head2 check_form_submitted
+
+This makes sure we only proceed to processing if we've had the form submitted
+(we may have come here via an OAuth login, for example).
+
+=cut
+
+sub check_form_submitted : Private {
+ my ( $self, $c ) = @_;
+ return $c->get_param('submit_update') || '';
+}
+
+=head2 process_update
+
+Take the submitted params and updates our update item. Does not save
+anything to the database.
+
+=cut
+
+sub process_update : Private {
+ my ( $self, $c ) = @_;
+
my %params =
map { $_ => $c->get_param($_) } ( 'update', 'name', 'fixed', 'state', 'reopen' );
@@ -184,20 +257,12 @@ sub process_update : Private {
$params{reopen} = 0 unless $c->user && $c->user->id == $c->stash->{problem}->user->id;
- my $update = $c->model('DB::Comment')->new(
- {
- text => $params{update},
- name => $name,
- problem => $c->stash->{problem},
- state => 'unconfirmed',
- mark_fixed => $params{fixed} ? 1 : 0,
- mark_open => $params{reopen} ? 1 : 0,
- cobrand => $c->cobrand->moniker,
- cobrand_data => '',
- lang => $c->stash->{lang_code},
- anonymous => $anonymous,
- }
- );
+ my $update = $c->stash->{update};
+ $update->text($params{update});
+ $update->name($name);
+ $update->mark_fixed($params{fixed} ? 1 : 0);
+ $update->mark_open($params{reopen} ? 1 : 0);
+ $update->anonymous($anonymous);
if ( $params{state} ) {
$params{state} = 'fixed - council'
@@ -241,7 +306,6 @@ sub process_update : Private {
$c->log->debug( 'name is ' . $c->get_param('name') );
- $c->stash->{update} = $update;
$c->stash->{add_alert} = $c->get_param('add_alert');
return 1;
@@ -283,6 +347,13 @@ sub check_for_errors : Private {
%{ $c->stash->{update}->check_for_errors },
);
+ # if using social login then we don't care about name and email errors
+ $c->stash->{is_social_user} = $c->get_param('facebook_sign_in') || $c->get_param('twitter_sign_in');
+ if ( $c->stash->{is_social_user} ) {
+ delete $field_errors{name};
+ delete $field_errors{email};
+ }
+
if ( my $photo_error = delete $c->stash->{photo_error} ) {
$field_errors{photo} = $photo_error;
}
@@ -302,6 +373,17 @@ sub check_for_errors : Private {
return;
}
+# Store changes in token for when token is validated.
+sub tokenize_user : Private {
+ my ($self, $c, $update) = @_;
+ $c->stash->{token_data} = {
+ name => $update->user->name,
+ password => $update->user->password,
+ };
+ $c->stash->{token_data}{facebook_id} = $c->session->{oauth}{facebook_id}
+ if $c->get_param('oauth_need_email') && $c->session->{oauth}{facebook_id};
+}
+
=head2 save_update
Save the update and the user as appropriate.
@@ -313,6 +395,27 @@ sub save_update : Private {
my $update = $c->stash->{update};
+ # If there was a photo add that too
+ if ( my $fileid = $c->stash->{upload_fileid} ) {
+ $update->photo($fileid);
+ }
+
+ if ( $c->stash->{is_social_user} ) {
+ my $token = $c->model("DB::Token")->create( {
+ scope => 'update/social',
+ data => { $update->get_inflated_columns },
+ } );
+
+ $c->stash->{detach_to} = '/report/update/oauth_callback';
+ $c->stash->{detach_args} = [$token->token];
+
+ if ( $c->get_param('facebook_sign_in') ) {
+ $c->detach('/auth/facebook_sign_in');
+ } elsif ( $c->get_param('twitter_sign_in') ) {
+ $c->detach('/auth/twitter_sign_in');
+ }
+ }
+
if ( $c->cobrand->never_confirm_updates ) {
if ( $update->user->in_storage() ) {
$update->user->update();
@@ -322,11 +425,7 @@ sub save_update : Private {
$update->confirm();
} elsif ( !$update->user->in_storage ) {
# User does not exist.
- # Store changes in token for when token is validated.
- $c->stash->{token_data} = {
- name => $update->user->name,
- password => $update->user->password,
- };
+ $c->forward('tokenize_user', [ $update ]);
$update->user->name( undef );
$update->user->password( '', 1 );
$update->user->insert;
@@ -338,19 +437,10 @@ sub save_update : Private {
$update->confirm;
} else {
# User exists and we are not logged in as them.
- # Store changes in token for when token is validated.
- $c->stash->{token_data} = {
- name => $update->user->name,
- password => $update->user->password,
- };
+ $c->forward('tokenize_user', [ $update ]);
$update->user->discard_changes();
}
- # If there was a photo add that too
- if ( my $fileid = $c->stash->{upload_fileid} ) {
- $update->photo($fileid);
- }
-
if ( $update->in_storage ) {
$update->update;
}
diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm
index 407fc625e..027b0d5a4 100644
--- a/perllib/FixMyStreet/App/Controller/Reports.pm
+++ b/perllib/FixMyStreet/App/Controller/Reports.pm
@@ -3,6 +3,7 @@ use Moose;
use namespace::autoclean;
use File::Slurp;
+use JSON::MaybeXS;
use List::MoreUtils qw(any);
use POSIX qw(strcoll);
use RABX;
@@ -68,7 +69,7 @@ sub index : Path : Args(0) {
my $data = File::Slurp::read_file(
FixMyStreet->path_to( '../data/all-reports.json' )->stringify
);
- my $j = JSON->new->utf8->decode($data);
+ my $j = decode_json($data);
$c->stash->{fixed} = $j->{fixed};
$c->stash->{open} = $j->{open};
};
diff --git a/perllib/FixMyStreet/App/Controller/Status.pm b/perllib/FixMyStreet/App/Controller/Status.pm
index 8a84a1666..931c7bd47 100755
--- a/perllib/FixMyStreet/App/Controller/Status.pm
+++ b/perllib/FixMyStreet/App/Controller/Status.pm
@@ -3,7 +3,7 @@ use Moose;
use namespace::autoclean;
use HTTP::Negotiate;
-use JSON;
+use JSON::MaybeXS;
BEGIN { extends 'Catalyst::Controller'; }
diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm
index b1d60fe32..eb35fd152 100644
--- a/perllib/FixMyStreet/App/Controller/Tokens.pm
+++ b/perllib/FixMyStreet/App/Controller/Tokens.pm
@@ -105,6 +105,7 @@ sub confirm_problem : Path('/P') {
$problem->user->phone( $data->{phone} ) if $data->{phone};
$problem->user->password( $data->{password}, 1 ) if $data->{password};
$problem->user->title( $data->{title} ) if $data->{title};
+ $problem->user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id};
$problem->user->update;
}
$c->authenticate( { email => $problem->user->email }, 'no_password' );
@@ -230,6 +231,7 @@ sub confirm_update : Path('/C') {
if ( $data->{name} || $data->{password} ) {
$comment->user->name( $data->{name} ) if $data->{name};
$comment->user->password( $data->{password}, 1 ) if $data->{password};
+ $comment->user->facebook_id( $data->{facebook_id} ) if $data->{facebook_id};
$comment->user->update;
}
diff --git a/perllib/FixMyStreet/Cobrand/UK.pm b/perllib/FixMyStreet/Cobrand/UK.pm
index 2473f386f..824590d38 100644
--- a/perllib/FixMyStreet/Cobrand/UK.pm
+++ b/perllib/FixMyStreet/Cobrand/UK.pm
@@ -1,6 +1,7 @@
package FixMyStreet::Cobrand::UK;
use base 'FixMyStreet::Cobrand::Default';
+use JSON::MaybeXS;
use mySociety::MaPit;
use mySociety::VotingArea;
diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm
index f08b666c8..ddf986c47 100644
--- a/perllib/FixMyStreet/DB/Result/User.pm
+++ b/perllib/FixMyStreet/DB/Result/User.pm
@@ -32,9 +32,15 @@ __PACKAGE__->add_columns(
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
"title",
{ data_type => "text", is_nullable => 1 },
+ "twitter_id",
+ { data_type => "bigint", is_nullable => 1 },
+ "facebook_id",
+ { data_type => "bigint", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("users_email_key", ["email"]);
+__PACKAGE__->add_unique_constraint("users_facebook_id_key", ["facebook_id"]);
+__PACKAGE__->add_unique_constraint("users_twitter_id_key", ["twitter_id"]);
__PACKAGE__->has_many(
"admin_logs",
"FixMyStreet::DB::Result::AdminLog",
@@ -84,8 +90,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2014-07-29 13:54:07
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Y41/jGp93IxSpyJ/o6Q1gQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-12-09 16:02:08
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hCq6ZDZfV/6iiu3HFhPPOg
__PACKAGE__->add_columns(
"password" => {
diff --git a/perllib/FixMyStreet/Geocode.pm b/perllib/FixMyStreet/Geocode.pm
index aac52fbaa..4470ecbca 100644
--- a/perllib/FixMyStreet/Geocode.pm
+++ b/perllib/FixMyStreet/Geocode.pm
@@ -11,6 +11,7 @@ use Digest::MD5 qw(md5_hex);
use Encode;
use File::Slurp;
use File::Path ();
+use JSON::MaybeXS;
use LWP::Simple qw($ua);
use URI::Escape;
use FixMyStreet::Geocode::Bing;
diff --git a/perllib/FixMyStreet/Map/OSM/TonerLite.pm b/perllib/FixMyStreet/Map/OSM/TonerLite.pm
index 543cd6002..b0d12c453 100644
--- a/perllib/FixMyStreet/Map/OSM/TonerLite.pm
+++ b/perllib/FixMyStreet/Map/OSM/TonerLite.pm
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-#
# FixMyStreet:Map::OSM::TonerLite
# OSM TonerLite maps on FixMyStreet.
#
diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm
index d3adce08b..9d836ca4d 100644
--- a/perllib/FixMyStreet/TestMech.pm
+++ b/perllib/FixMyStreet/TestMech.pm
@@ -14,7 +14,7 @@ use Test::More;
use Web::Scraper;
use Carp;
use Email::Send::Test;
-use JSON;
+use JSON::MaybeXS;
=head1 NAME
diff --git a/perllib/Open311/Endpoint.pm b/perllib/Open311/Endpoint.pm
index 7916d090f..2a6ba742a 100644
--- a/perllib/Open311/Endpoint.pm
+++ b/perllib/Open311/Endpoint.pm
@@ -8,7 +8,7 @@ Open311::Endpoint - a generic Open311 endpoint implementation
use Web::Simple;
-use JSON;
+use JSON::MaybeXS;
use XML::Simple;
use Open311::Endpoint::Result;
diff --git a/t/Facebook.pm b/t/Facebook.pm
new file mode 100644
index 000000000..8c258699b
--- /dev/null
+++ b/t/Facebook.pm
@@ -0,0 +1,52 @@
+package t::Facebook;
+
+use JSON;
+use Web::Simple;
+use MooX::Types::MooseLike::Base qw(:all);
+
+has json => (
+ is => 'lazy',
+ default => sub {
+ JSON->new->pretty->allow_blessed->convert_blessed;
+ },
+);
+
+has returns_email => (
+ is => 'rw',
+ isa => Bool,
+ default => 1,
+);
+
+sub dispatch_request {
+ my $self = shift;
+
+ sub (GET + /v2.2/dialog/oauth + ?*) {
+ my ($self) = @_;
+ return [ 200, [ 'Content-Type' => 'text/html' ], [ 'FB login page' ] ];
+ },
+
+ sub (GET + /v2.2/oauth/access_token + ?*) {
+ my ($self) = @_;
+ return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'access_token=access_token&expires=never' ] ];
+ },
+
+ sub (GET + /me + ?fields=) {
+ my ($self, $fields) = @_;
+ my $data = {
+ id => '123456789',
+ name => 'Fiona Tester',
+ };
+ $data->{email} = 'facebook@example.org' if $self->returns_email;
+ my $json = $self->json->encode($data);
+ return [ 200, [ 'Content-Type' => 'text/html' ], [ $json ] ];
+ },
+
+ sub (GET + /search + ?q=) {
+ my ($self, $q) = @_;
+ my $response = $self->query($q);
+ my $json = $self->json->encode($response);
+ return [ 200, [ 'Content-Type' => 'application/json' ], [ $json ] ];
+ },
+}
+
+__PACKAGE__->run_if_script;
diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t
new file mode 100644
index 000000000..173572b02
--- /dev/null
+++ b/t/app/controller/auth_social.t
@@ -0,0 +1,143 @@
+use strict;
+use warnings;
+use Test::More;
+use LWP::Protocol::PSGI;
+use LWP::Simple;
+use JSON::MaybeXS;
+
+use t::Facebook;
+use t::MapIt;
+
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my ($report) = $mech->create_problems_for_body(1, '2345', 'Test');
+
+LWP::Protocol::PSGI->register(t::MapIt->to_psgi_app, host => 'mapit.uk');
+
+FixMyStreet::override_config {
+ FACEBOOK_APP_ID => 'facebook-app-id',
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+my $fb_email = 'facebook@example.org';
+my $fb_uid = 123456789;
+
+for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
+ for my $page ( 'my', 'report', 'update' ) {
+ subtest "test FB '$fb_state' login for page '$page'" => sub {
+ $mech->log_out_ok;
+ if ($fb_state eq 'existing UID') {
+ my $user = $mech->create_user_ok($fb_email);
+ $user->update({ facebook_id => $fb_uid });
+ } else {
+ $mech->delete_user($fb_email);
+ }
+
+ # Set up a mock to catch (most, see below) requests to Facebook
+ my $fb = t::Facebook->new;
+ $fb->returns_email(0) if $fb_state eq 'no email' || $fb_state eq 'existing UID';
+ LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'www.facebook.com');
+ LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'graph.facebook.com');
+
+ # Due to https://metacpan.org/pod/Test::WWW::Mechanize::Catalyst#External-Redirects-and-allow_external
+ # the redirect to Facebook's OAuth page can mess up the session
+ # cookie. So let's pretend we always on www.facebook.com, which
+ # sorts that out.
+ $mech->host('www.facebook.com');
+
+ # Fetch the page with the form via which we wish to log in
+ my $fields;
+ if ($page eq 'my') {
+ $mech->get_ok('/my');
+ } elsif ($page eq 'report') {
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $fields = {
+ title => 'Test title',
+ detail => 'Test detail',
+ };
+ } else {
+ $mech->get_ok('/report/' . $report->id);
+ $fields = {
+ update => 'Test update',
+ };
+ }
+ $mech->submit_form(with_fields => $fields, button => 'facebook_sign_in');
+
+ # As well as the cookie issue above, caused by this external
+ # redirect rewriting the host, the redirect gets handled directly
+ # by Catalyst, not our mocked handler, so will be a 404. Check
+ # the redirect happened instead.
+ is $mech->res->previous->code, 302, 'FB button redirected';
+ like $mech->res->previous->header('Location'), qr{facebook\.com.*dialog/oauth.*facebook-app-id}, 'FB redirect to oauth URL';
+
+ # Okay, now call the callback Facebook would send us to
+ if ($fb_state eq 'refused') {
+ $mech->get_ok('/auth/Facebook?error_code=ERROR');
+ } else {
+ $mech->get_ok('/auth/Facebook?code=response-code');
+ }
+
+ # Check we're showing the right form, regardless of what came back
+ if ($page eq 'report') {
+ $mech->content_contains('/report/new');
+ } elsif ($page eq 'update') {
+ $mech->content_contains('/report/update');
+ }
+
+ if ($fb_state eq 'refused') {
+ $mech->content_contains('Sorry, we could not log you in. Please fill in the form below.');
+ $mech->not_logged_in_ok;
+ } elsif ($fb_state eq 'no email') {
+ $mech->content_contains('We need your email address, please give it below.');
+ # We don't have an email, so check that we can still submit it,
+ # and the ID carries through the confirmation
+ if ($page eq 'update') {
+ $fields->{rznvy} = $fb_email;
+ } else {
+ $fields->{email} = $fb_email;
+ }
+ $fields->{name} = 'Ffion Tester';
+ $mech->submit_form(with_fields => $fields);
+ $mech->content_contains('Nearly done! Now check your email');
+
+ my $email = $mech->get_email;
+ ok $email, "got an email";
+ $mech->clear_emails_ok;
+ my ( $url, $url_token ) = $email->body =~ m{(https?://\S+/[CMP]/)(\S+)};
+ ok $url, "extracted confirm url '$url'";
+
+ my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
+ if ($page eq 'my') {
+ is $user, undef, 'No user yet exists';
+ } else {
+ is $user->facebook_id, undef, 'User has no facebook ID';
+ }
+ $mech->get_ok( $url . $url_token );
+ $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
+ is $user->facebook_id, $fb_uid, 'User now has correct facebook ID';
+
+ } elsif ($page ne 'my') {
+ # /my auth login goes directly there, no message like this
+ $mech->content_contains('You have successfully signed in; please check and confirm your details are accurate');
+ $mech->logged_in_ok;
+ } else {
+ is $mech->uri->path, '/my', 'Successfully on /my page';
+ }
+ }
+ }
+}
+
+};
+
+END {
+ $mech->delete_problems_for_body('2345');
+ done_testing();
+}
diff --git a/t/app/controller/page_not_found.t b/t/app/controller/page_not_found.t
index 05e983109..3c2bc3c3d 100644
--- a/t/app/controller/page_not_found.t
+++ b/t/app/controller/page_not_found.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t
index d1609cb2f..c4781ac8f 100644
--- a/t/app/helpers/send_email.t
+++ b/t/app/helpers/send_email.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
use utf8;
diff --git a/t/app/load_general_config.t b/t/app/load_general_config.t
index 3855c2565..1051aac3f 100644
--- a/t/app/load_general_config.t
+++ b/t/app/load_general_config.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl -w
-
use strict;
use warnings;
diff --git a/t/app/model/comment.t b/t/app/model/comment.t
index ae93824a7..e83d795fc 100644
--- a/t/app/model/comment.t
+++ b/t/app/model/comment.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/model/problem.t b/t/app/model/problem.t
index 6f706a22a..4e4a098d7 100644
--- a/t/app/model/problem.t
+++ b/t/app/model/problem.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t
index f82b071bd..945a64633 100644
--- a/t/app/model/questionnaire.t
+++ b/t/app/model/questionnaire.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/model/token.t b/t/app/model/token.t
index c98cea395..e31901187 100644
--- a/t/app/model/token.t
+++ b/t/app/model/token.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/sendreport/email.t b/t/app/sendreport/email.t
index eacc6dcf6..471145dcb 100644
--- a/t/app/sendreport/email.t
+++ b/t/app/sendreport/email.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/map/tilma/original.t b/t/map/tilma/original.t
index 4ddeed8e0..a1c6d83f4 100644
--- a/t/map/tilma/original.t
+++ b/t/map/tilma/original.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
use Test::More;
diff --git a/templates/web/base/auth/general.html b/templates/web/base/auth/general.html
index 6e1db86fe..d856dc19a 100644
--- a/templates/web/base/auth/general.html
+++ b/templates/web/base/auth/general.html
@@ -2,11 +2,28 @@
<h1>[% loc('Sign in') %]</h1>
+[% IF oauth_need_email %]
+ <p class="form-error">[% loc('We need your email address, please give it below.') %]</p>
+[% END %]
+[% IF oauth_failure %]
+ <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p>
+[% END %]
+
<form action="[% c.uri_for() %]" method="post" name="general_auth" class="validate">
<fieldset>
<input type="hidden" name="r" value="[% c.req.params.r | html %]">
+[% IF NOT oauth_need_email AND c.config.FACEBOOK_APP_ID %]
+ <div class="form-box">
+ <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook">
+ <img alt="" src="/i/facebook-icon-32.png" width="17" height="32">
+ Log in with Facebook
+ </button>
+ </div>
+ <div id="js-social-email-hide">
+[% END %]
+
[% IF email_error;
# other keys include fqdn, mxcheck if you'd like to write a custom error message
@@ -29,43 +46,58 @@
<div id="form_sign_in">
<h3>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h3>
+ [% IF oauth_need_email %]
+ [% INCLUDE form_sign_in_no %]
+ [% INCLUDE form_sign_in_yes %]
+ <input type="hidden" name="oauth_need_email" value="1">
+ [% ELSE %]
+ [% INCLUDE form_sign_in_yes %]
+ [% INCLUDE form_sign_in_no %]
+ [% END %]
+ </div>
- <div id="form_sign_in_yes" class="form-box">
- <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
+[% IF NOT oauth_need_email AND c.config.FACEBOOK_APP_ID %]
+ </div>
+[% END %]
- <label class="hidden-js n" for="password_sign_in">[% loc('Password:') %]</label>
+ </fieldset>
+</form>
- <div class="form-txt-submit-box">
- <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]">
- <input class="green-btn" type="submit" name="sign_in" value="[% loc('Sign in') %]">
- </div>
+[% INCLUDE 'footer.html' %]
- <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
- <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
+[% BLOCK form_sign_in_yes %]
+ <div id="form_sign_in_yes" class="form-box">
+ <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
- </div>
- <div id="form_sign_in_no" class="form-box">
- <h5>[% loc('<strong>No</strong> let me sign in by email') %]</h5>
+ <label class="hidden-js n" for="password_sign_in">[% loc('Password:') %]</label>
- <label for="name">[% loc('Name') %]</label>
- <input type="text" name="name" value="" placeholder="[% loc('Your name') %]">
+ <div class="form-txt-submit-box">
+ <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]">
+ <input class="green-btn" type="submit" name="sign_in" value="[% loc('Sign in') %]">
+ </div>
- <label for="password_register">[% loc('Password (optional)') %]</label>
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
- <div class="general-notes">
- <p>[% loc('Providing a name and password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
- </div>
+ </div>
+[% END %]
- <div class="form-txt-submit-box">
- <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
- <input class="green-btn" type="submit" name="email_sign_in" value="[% loc('Sign in') %]">
- </div>
- </div>
+[% BLOCK form_sign_in_no %]
+ <div id="form_sign_in_no" class="form-box">
+ <h5>[% loc('<strong>No</strong> let me sign in by email') %]</h5>
- </div>
+ <label for="name">[% loc('Name') %]</label>
+ <input type="text" name="name" value="" placeholder="[% loc('Your name') %]">
- </fieldset>
-</form>
+ <label for="password_register">[% loc('Password (optional)') %]</label>
+ <div class="general-notes">
+ <p>[% loc('Providing a name and password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
+ </div>
-[% INCLUDE 'footer.html' %]
+ <div class="form-txt-submit-box">
+ <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
+ <input class="green-btn" type="submit" name="email_sign_in" value="[% loc('Sign in') %]">
+ </div>
+ </div>
+[% END %]
diff --git a/templates/web/base/js/validation_rules.html b/templates/web/base/js/validation_rules.html
index 409d0971f..5295a53ca 100644
--- a/templates/web/base/js/validation_rules.html
+++ b/templates/web/base/js/validation_rules.html
@@ -1,7 +1,5 @@
validation_rules = {
title: { required: true },
detail: { required: true },
- email: { required: true },
- update: { required: true },
- rznvy: { required: true }
+ update: { required: true }
};
diff --git a/templates/web/base/questionnaire/index.html b/templates/web/base/questionnaire/index.html
index 2c7761d5d..c8b6907a1 100644
--- a/templates/web/base/questionnaire/index.html
+++ b/templates/web/base/questionnaire/index.html
@@ -11,7 +11,7 @@
<h1>[% loc('Questionnaire') %]</h1>
-<h2 class="questionnaire-report-header">Your report</h2>
+<h2 class="questionnaire-report-header">[% loc('Your report') %]</h2>
<div class="questionnaire-report-reminder">
[% INCLUDE 'report/photo.html' object=problem %]
<h3 class="questionnaire-report-reminder__report-title">
diff --git a/templates/web/base/report/display.html b/templates/web/base/report/display.html
index 5f499dd6e..05e07d501 100644
--- a/templates/web/base/report/display.html
+++ b/templates/web/base/report/display.html
@@ -15,64 +15,30 @@
[% IF login_success %]
<p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p>
+ [% INCLUDE 'report/update-form.html' %]
+ [% SET shown_form = 1 %]
+[% ELSIF oauth_failure %]
+ <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p>
+ [% INCLUDE 'report/update-form.html' %]
+ [% SET shown_form = 1 %]
+[% ELSIF oauth_need_email %]
+ <p class="form-error">
+ [% loc('Please note your update has <strong>not yet been posted</strong>.') %]
+ [% loc('We need your email address, please give it below.') %]
+ </p>
+ [% INCLUDE 'report/update-form.html' %]
+ [% SET shown_form = 1 %]
[% END %]
[% INCLUDE 'report/banner.html' %]
-
[% INCLUDE 'report/_main.html' %]
[% TRY %][% INCLUDE 'report/_message_manager.html' %][% CATCH file %][% END %]
+[% INCLUDE 'report/display_tools.html' %]
+[% TRY %][% INCLUDE 'report/sharing.html' %][% CATCH file %][% END %]
+[% INCLUDE 'report/updates.html' %]
-<div class="shadow-wrap">
- <ul id="key-tools">
- [% IF c.user_exists AND c.cobrand.users_can_hide AND c.user.belongs_to_body( c.cobrand.council_id ) %]
- <li><form method="post" action="/report/delete/[% problem.id %]" id="remove-from-site-form">
- <input type="submit" id="key-tool-report-abuse" class="abuse" value="Remove from site">
- </form></li>
- [% ELSIF c.cobrand.moniker != 'zurich' %]
- <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li>
- [% END %]
- [% IF c.cobrand.moniker != 'zurich' %]
- <li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li>
- [% END %]
- [% IF c.cobrand.moniker == 'fixmystreet' %]
- <li><a rel="nofollow" id="key-tool-report-share" class="share" href="#report-share">[% loc('Share') %]</a></li>
- [% END %]
- [% IF c.cobrand.moniker == 'zurich' %]
- <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems on the map' ) %]</a></li>
- [% ELSE %]
- <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li>
- [% END %]
- </ul>
-
-[% IF c.cobrand.moniker == 'fixmystreet' %]
- <div id="report-share" class="hidden-js" align="center">
- <a href="https://twitter.com/share" class="twitter-share-button" data-text="I just reported &lsquo;[% problem.title_safe | html %]&rsquo;" data-via="fixmystreet" data-related="mysociety" data-count="none" data-dnt="true">Tweet</a>
-<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
- <iframe src="//www.facebook.com/plugins/like.php?href=[% c.req.uri | uri %]&amp;send=false&amp;layout=button_count&amp;width=90&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:90px; height:21px;" allowTransparency="true"></iframe>
- </div>
+[% IF NOT shown_form %]
+ [% INCLUDE 'report/update-form.html' %]
[% END %]
-<div id="report-updates-data" class="hidden-js">
- <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post">
- <a href="[% c.uri_for( '/rss', problem.id ) %]">
- <img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0">
- </a>
- <p>[% loc('Receive email when updates are left on this problem.' ) %]</p>
- <fieldset>
- <label class="hidden n" for="alert_rznvy">[% loc('Your email') %]</label>
- <div class="form-txt-submit-box">
- <input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30" placeholder="[% loc('Your email') %]">
- <input class="green-btn" type="submit" value="[% loc('Subscribe') %]">
- </div>
- <input type="hidden" name="id" value="[% problem.id %]">
- <input type="hidden" name="type" value="updates">
- </fieldset>
- </form>
-</div>
-
-</div>
-
-[% TRY %][% INCLUDE 'report/sharing.html' %][% CATCH file %][% END %]
-[% INCLUDE 'report/updates.html' %]
-[% INCLUDE 'report/update-form.html' %]
[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/report/display_tools.html b/templates/web/base/report/display_tools.html
new file mode 100644
index 000000000..004ae29e5
--- /dev/null
+++ b/templates/web/base/report/display_tools.html
@@ -0,0 +1,49 @@
+<div class="shadow-wrap">
+ <ul id="key-tools">
+ [% IF c.user_exists AND c.cobrand.users_can_hide AND c.user.belongs_to_body( c.cobrand.council_id ) %]
+ <li><form method="post" action="/report/delete/[% problem.id %]" id="remove-from-site-form">
+ <input type="submit" id="key-tool-report-abuse" class="abuse" value="Remove from site">
+ </form></li>
+ [% ELSIF c.cobrand.moniker != 'zurich' %]
+ <li><a rel="nofollow" id="key-tool-report-abuse" class="abuse" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Report abuse' ) %]</a></li>
+ [% END %]
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <li><a rel="nofollow" id="key-tool-report-updates" class="feed" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Get updates' ) %]</a></li>
+ [% END %]
+ [% IF c.cobrand.moniker == 'fixmystreet' %]
+ <li><a rel="nofollow" id="key-tool-report-share" class="share" href="#report-share">[% loc('Share') %]</a></li>
+ [% END %]
+ [% IF c.cobrand.moniker == 'zurich' %]
+ <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems on the map' ) %]</a></li>
+ [% ELSE %]
+ <li><a class="chevron" id="key-tool-problems-nearby" href="[% c.uri_for( '/around', { lat => latitude, lon => longitude } ) %]">[% loc( 'Problems nearby' ) %]</a></li>
+ [% END %]
+ </ul>
+
+[% IF c.cobrand.moniker == 'fixmystreet' %]
+ <div id="report-share" class="hidden-js" align="center">
+ <a href="https://twitter.com/share" class="twitter-share-button" data-text="I just reported &lsquo;[% problem.title_safe | html %]&rsquo;" data-via="fixmystreet" data-related="mysociety" data-count="none" data-dnt="true">Tweet</a>
+<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
+ <iframe src="//www.facebook.com/plugins/like.php?href=[% c.req.uri | uri %]&amp;send=false&amp;layout=button_count&amp;width=90&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:90px; height:21px;" allowTransparency="true"></iframe>
+ </div>
+[% END %]
+
+<div id="report-updates-data" class="hidden-js">
+ <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post">
+ <a href="[% c.uri_for( '/rss', problem.id ) %]">
+ <img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0">
+ </a>
+ <p>[% loc('Receive email when updates are left on this problem.' ) %]</p>
+ <fieldset>
+ <label class="hidden n" for="alert_rznvy">[% loc('Your email') %]</label>
+ <div class="form-txt-submit-box">
+ <input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30" placeholder="[% loc('Your email') %]">
+ <input class="green-btn" type="submit" value="[% loc('Subscribe') %]">
+ </div>
+ <input type="hidden" name="id" value="[% problem.id %]">
+ <input type="hidden" name="type" value="updates">
+ </fieldset>
+ </form>
+</div>
+
+</div>
diff --git a/templates/web/base/report/new/fill_in_details.html b/templates/web/base/report/new/fill_in_details.html
index 9d3f52041..55b3a5207 100644
--- a/templates/web/base/report/new/fill_in_details.html
+++ b/templates/web/base/report/new/fill_in_details.html
@@ -33,11 +33,15 @@
<div id="skipped-map">
[% END %]
- [% IF login_success %]
- <p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p>
- [% END %]
-
- [% PROCESS 'report/new/fill_in_details_form.html' %]
+ <div id="report-a-problem-main">
+ [% IF login_success %]
+ [% PROCESS 'report/new/login_success_form.html' %]
+ [% ELSIF oauth_need_email %]
+ [% PROCESS 'report/new/oauth_email_form.html' %]
+ [% ELSE %]
+ [% PROCESS 'report/new/fill_in_details_form.html' %]
+ [% END %]
+ </div>
</div>
</form>
diff --git a/templates/web/base/report/new/fill_in_details_form.html b/templates/web/base/report/new/fill_in_details_form.html
index 9c42f4696..f9da3753f 100644
--- a/templates/web/base/report/new/fill_in_details_form.html
+++ b/templates/web/base/report/new/fill_in_details_form.html
@@ -1,11 +1,10 @@
-<div id="report-a-problem-main">
- <h1>[% loc('Report your problem') %]</h1>
+<h1>[% loc('Report your problem') %]</h1>
- [% IF report.used_map %]
+[% IF report.used_map %]
<p class="change_location">[% loc('Wrong location? Just click again on the map.') %]</p>
- [% END %]
+[% END %]
- [% IF js %]
+[% IF js %]
<p id="councils_text">
[% tprintf(
loc('All the information you provide here will be sent to <strong>%s</strong>.'),
@@ -13,94 +12,28 @@
); %]
[% loc('The summary and description will also be made public (see our <a href="/privacy">privacy policy</a>).') %]
</p>
- [% ELSE %]
- [% PROCESS 'report/new/councils_text.html' %]
- [% END %]
+[% ELSE %]
+ [% PROCESS 'report/new/councils_text.html' %]
+[% END %]
- [% IF report.used_map && partial_token %]
+[% IF report.used_map && partial_token %]
<p id="unknown">[% loc('Please note your report has <strong>not yet been sent</strong>. Choose a category and add further information below, then submit.') %]</p>
- [% END %]
-
- [% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %]
-
- [% INCLUDE 'errors.html' %]
-
- <fieldset>
- <div id="problem_form">
-
- [% INCLUDE 'report/new/form_heading.html' %]
-
- [% IF field_errors.bodies %]
- <p class='form-error'>[% field_errors.bodies %]</p>
- [% END %]
-
- [% TRY %]
- [%# Useful for amending form contents based on category selection %]
- [% PROCESS 'report/new/category_at_top.html' %]
- [% need_to_show_category_selector = 0 %]
- [% CATCH file %]
- [% need_to_show_category_selector = 1 %]
- [% END %]
-
- <label for="form_title">[% loc('One-line summary') %] [% INCLUDE 'report/public_label.html' %]</label>
- [% IF field_errors.title %]
- <p class='form-error'>[% field_errors.title %]</p>
- [% END %]
- <input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('What’s the issue, and where is it?') %]" required>
-
- [% IF c.cobrand.allow_photo_upload %]
- <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
- <label for="form_photo">[% loc('Photo') %]
- [% INCLUDE 'report/public_label.html' %]</label>
-
- [% IF field_errors.photo %]
- <p class='form-error'>[% field_errors.photo %]</p>
- [% END %]
-
- <div id="form_photos">
- [% IF upload_fileid %]
- <script>
- var fixmystreet = fixmystreet || {};
- fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
- </script>
- <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
- [% FOREACH id IN upload_fileid.split(',') %]
- <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
- [% END %]
- [% END %]
- <input type="file" name="photo1" id="form_photo">
- <input type="file" name="photo2" id="form_photo2">
- <input type="file" name="photo3" id="form_photo3">
- </div>
- [% END %]
-
- [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
-
- <label for="form_detail">[% loc('Description') %] [% INCLUDE 'report/public_label.html' %]</label>
- [% IF field_errors.detail %]
- <p class='form-error'>[% field_errors.detail %]</p>
- [% END %]
- <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Explain what’s wrong, exactly where it is, and how long it’s been there…') %]" required>[% report.detail | html %]</textarea>
-
- [% TRY %][% PROCESS 'report/new/inline-tips.html' %][% CATCH file %][% END %]
-
- [% IF need_to_show_category_selector %]
- [% PROCESS "report/new/category_wrapper.html" %]
- [% END %]
-
- [% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %]
-
- [% IF c.user_exists %]
- [% PROCESS "report/new/form_user_loggedin.html" %]
- [% ELSE %]
- [% PROCESS "report/new/form_user_loggedout.html" %]
- [% END %]
- </div>
- </fieldset>
-
- [% IF partial_token %]
- <input type="hidden" name="partial" value="[% partial_token.token %]">
- [% END %]
-
- <input type="hidden" name="submit_problem" value="1">
-</div>
+[% END %]
+[% IF oauth_failure %]
+ <p class="form-error">[% loc('Sorry, we could not log you in. Please fill in the form below.') %]</p>
+[% END %]
+
+[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %]
+
+[% INCLUDE 'errors.html' %]
+
+<fieldset>
+ <div id="problem_form">
+ [% PROCESS 'report/new/form_report.html' %]
+ [% IF c.user_exists %]
+ [% PROCESS "report/new/form_user_loggedin.html" %]
+ [% ELSE %]
+ [% PROCESS "report/new/form_user_loggedout.html" %]
+ [% END %]
+ </div>
+</fieldset>
diff --git a/templates/web/base/report/new/form_report.html b/templates/web/base/report/new/form_report.html
new file mode 100644
index 000000000..a236b6a1f
--- /dev/null
+++ b/templates/web/base/report/new/form_report.html
@@ -0,0 +1,67 @@
+[% INCLUDE 'report/new/form_heading.html' %]
+
+[% IF field_errors.bodies %]
+ <p class='form-error'>[% field_errors.bodies %]</p>
+[% END %]
+
+[% TRY %]
+ [%# Useful for amending form contents based on category selection %]
+ [% PROCESS 'report/new/category_at_top.html' %]
+ [% need_to_show_category_selector = 0 %]
+[% CATCH file %]
+ [% need_to_show_category_selector = 1 %]
+[% END %]
+
+ <label for="form_title">[% loc('One-line summary') %] [% INCLUDE 'report/public_label.html' %]</label>
+[% IF field_errors.title %]
+ <p class='form-error'>[% field_errors.title %]</p>
+[% END %]
+ <input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('What’s the issue, and where is it?') %]" required>
+
+[% IF c.cobrand.allow_photo_upload %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ <label for="form_photo">[% loc('Photo') %]
+ [% INCLUDE 'report/public_label.html' %]</label>
+
+ [% IF field_errors.photo %]
+ <p class='form-error'>[% field_errors.photo %]</p>
+ [% END %]
+
+ <div id="form_photos">
+ [% IF upload_fileid %]
+ <script>
+ var fixmystreet = fixmystreet || {};
+ fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
+ </script>
+ <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
+ [% FOREACH id IN upload_fileid.split(',') %]
+ <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
+ [% END %]
+ [% END %]
+ <input type="file" name="photo1" id="form_photo">
+ <input type="file" name="photo2" id="form_photo2">
+ <input type="file" name="photo3" id="form_photo3">
+ </div>
+[% END %]
+
+[% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
+
+ <label for="form_detail">[% loc('Description') %] [% INCLUDE 'report/public_label.html' %]</label>
+[% IF field_errors.detail %]
+ <p class='form-error'>[% field_errors.detail %]</p>
+[% END %]
+ <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Explain what’s wrong, exactly where it is, and how long it’s been there…') %]" required>[% report.detail | html %]</textarea>
+
+[% TRY %][% PROCESS 'report/new/inline-tips.html' %][% CATCH file %][% END %]
+
+[% IF need_to_show_category_selector %]
+ [% PROCESS "report/new/category_wrapper.html" %]
+[% END %]
+
+[% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %]
+
+[% IF partial_token %]
+ <input type="hidden" name="partial" value="[% partial_token.token %]">
+[% END %]
+
+ <input type="hidden" name="submit_problem" value="1">
diff --git a/templates/web/base/report/new/form_user_loggedout.html b/templates/web/base/report/new/form_user_loggedout.html
index c5a58e8a9..6657c87a1 100644
--- a/templates/web/base/report/new/form_user_loggedout.html
+++ b/templates/web/base/report/new/form_user_loggedout.html
@@ -1,79 +1,25 @@
-<label for="form_email">[% loc('Your email') %]
- <span class="muted">([% loc('We never show your email') %])</span>
-</label>
-[% IF field_errors.email %]
- <p class='form-error'>[% field_errors.email %]</p>
-[% END %]
-<input type="email" value="[% report.user.email | html %]" name="email" id="form_email" placeholder="[% loc('Please enter your email address') %]" required>
-
-<div id="form_sign_in">
+[% IF c.config.FACEBOOK_APP_ID %]
<h3>[% loc("Now to submit your report&hellip;") %]</h3>
- <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2>
-
- <div id="form_sign_in_yes" class="form-box">
-
- <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
-
- <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label>
- [% IF field_errors.password %]
- <p class='form-error'>[% field_errors.password %]</p>
- [% END %]
- <div class="form-txt-submit-box">
- <input type="password" name="password_sign_in" id="password_sign_in" placeholder="[% loc('Your password') %]" value="">
- <input class="green-btn" type="submit" id="submit_sign_in" name="submit_sign_in" value="[% loc('Submit') %]">
- </div>
-
- <div class="checkbox-group">
- <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
- <label class="n inline" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
- </div>
-
- <div class="general-notes">
- <p><strong>[% loc('Forgotten your password?') %]</strong>
- [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p>
- </div>
+ <div class="form-box">
+ <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook">
+ <img alt="" src="/i/facebook-icon-32.png" width="17" height="32">
+ Log in with Facebook
+ </button>
</div>
+ <div id="js-social-email-hide">
+ [% PROCESS 'report/new/form_user_loggedout_email.html' required = 0 %]
+[% ELSE %]
+ [% PROCESS 'report/new/form_user_loggedout_email.html' required = 1 %]
+ <h3>[% loc("Now to submit your report&hellip;") %]</h3>
+[% END %]
- <div id="form_sign_in_no" class="form-box">
- <h5>[% loc('<strong>No</strong> Let me confirm my report by email') %]</h5>
-
- [% INCLUDE 'report/new/extra_name.html' %]
-
- [% name_public = report.anonymous==0 OR (c.cobrand.default_show_name AND report.anonymous=='') %]
- <label for="form_name">[% loc('Name') %]
- [% TRY %]
- [% INCLUDE 'report/new/after_name.html' %]
- [% CATCH file %]
- [% END %]
- </label>
- [% IF field_errors.name %]
- <p class='form-error'>[% field_errors.name %]</p>
- [% END %]
-
- <input type="text" class="form-focus-trigger validName" value="[% report.name | html %]" name="name" id="form_name" placeholder="[% loc('Your name') %]">
-
- [%# if there is nothing in the name field then set check box as default on form %]
- <div class="checkbox-group">
- <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]>
- <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label>
- </div>
-
- <label class="form-focus-hidden" for="form_phone">[% loc('Phone number (optional)') %]</label>
- <input class="form-focus-hidden" type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" placeholder="[% loc('Your phone number') %]">
- <div class="general-notes form-focus-hidden">
- <p>[% loc('We never show your email address or phone number.') %]</p>
- </div>
-
- <label class="form-focus-hidden" for="password_register">[% loc('Password (optional)') %]</label>
-
- <div class="general-notes form-focus-hidden">
- <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
- </div>
+<div id="form_sign_in">
+ <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2>
+ [% PROCESS 'report/new/form_user_loggedout_password.html' %]
+ [% PROCESS 'report/new/form_user_loggedout_by_email.html' %]
+</div>
- <div class="form-txt-submit-box form-focus-hidden">
- <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
- <input class="green-btn" type="submit" id="submit_register" name="submit_register" value="[% loc('Submit') %]">
- </div>
+[% IF c.config.FACEBOOK_APP_ID %]
</div>
-</div>
+[% END %]
diff --git a/templates/web/base/report/new/form_user_loggedout_by_email.html b/templates/web/base/report/new/form_user_loggedout_by_email.html
new file mode 100644
index 000000000..a3e36dfa3
--- /dev/null
+++ b/templates/web/base/report/new/form_user_loggedout_by_email.html
@@ -0,0 +1,41 @@
+<div id="form_sign_in_no" class="form-box">
+ <h5>[% loc('<strong>No</strong> Let me confirm my report by email') %]</h5>
+
+ [% INCLUDE 'report/new/extra_name.html' %]
+
+ [% name_public = report.anonymous==0 OR (c.cobrand.default_show_name AND report.anonymous=='') %]
+ <label for="form_name">[% loc('Name') %]
+ [% TRY %]
+ [% INCLUDE 'report/new/after_name.html' %]
+ [% CATCH file %]
+ [% END %]
+ </label>
+ [% IF field_errors.name %]
+ <p class='form-error'>[% field_errors.name %]</p>
+ [% END %]
+
+ <input type="text" class="form-focus-trigger validName" value="[% report.name | html %]" name="name" id="form_name" placeholder="[% loc('Your name') %]">
+
+ [%# if there is nothing in the name field then set check box as default on form %]
+ <div class="checkbox-group">
+ <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]>
+ <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label>
+ </div>
+
+ <label class="form-focus-hidden" for="form_phone">[% loc('Phone number (optional)') %]</label>
+ <input class="form-focus-hidden" type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" placeholder="[% loc('Your phone number') %]">
+ <div class="general-notes form-focus-hidden">
+ <p>[% loc('We never show your email address or phone number.') %]</p>
+ </div>
+
+ <label class="form-focus-hidden" for="password_register">[% loc('Password (optional)') %]</label>
+
+ <div class="general-notes form-focus-hidden">
+ <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
+ </div>
+
+ <div class="form-txt-submit-box form-focus-hidden">
+ <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
+ <input class="green-btn" type="submit" id="submit_register" name="submit_register" value="[% loc('Submit') %]">
+ </div>
+</div>
diff --git a/templates/web/base/report/new/form_user_loggedout_email.html b/templates/web/base/report/new/form_user_loggedout_email.html
new file mode 100644
index 000000000..4f816f8cc
--- /dev/null
+++ b/templates/web/base/report/new/form_user_loggedout_email.html
@@ -0,0 +1,9 @@
+<label for="form_email">[% loc('Your email') %]
+ <span class="muted">([% loc('We never show your email') %])</span>
+</label>
+[% IF field_errors.email %]
+ <p class='form-error'>[% field_errors.email %]</p>
+[% END %]
+<input type="email" value="[% report.user.email | html %]" name="email" id="form_email" placeholder="[% loc('Please enter your email address') %]"
+ [% IF required %]required[% END %]
+ class="required">
diff --git a/templates/web/base/report/new/form_user_loggedout_password.html b/templates/web/base/report/new/form_user_loggedout_password.html
new file mode 100644
index 000000000..c9d65e43e
--- /dev/null
+++ b/templates/web/base/report/new/form_user_loggedout_password.html
@@ -0,0 +1,24 @@
+<div id="form_sign_in_yes" class="form-box">
+
+ <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
+
+ <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label>
+ [% IF field_errors.password %]
+ <p class='form-error'>[% field_errors.password %]</p>
+ [% END %]
+ <div class="form-txt-submit-box">
+ <input type="password" name="password_sign_in" id="password_sign_in" placeholder="[% loc('Your password') %]" value="">
+ <input class="green-btn" type="submit" id="submit_sign_in" name="submit_sign_in" value="[% loc('Submit') %]">
+ </div>
+
+ <div class="checkbox-group">
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="n inline" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
+ </div>
+
+ <div class="general-notes">
+ <p><strong>[% loc('Forgotten your password?') %]</strong>
+ [% loc('Confirm by email instead, providing a new password at that point. When you confirm, your password will be updated.') %]</p>
+ </div>
+
+</div>
diff --git a/templates/web/base/report/new/login_success_form.html b/templates/web/base/report/new/login_success_form.html
new file mode 100644
index 000000000..45d0221a7
--- /dev/null
+++ b/templates/web/base/report/new/login_success_form.html
@@ -0,0 +1,18 @@
+<h1>[% loc('Report your problem') %]</h1>
+
+<p class='form-success'>[% loc('You have successfully signed in; please check and confirm your details are accurate:') %]</p>
+
+[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %]
+
+[% INCLUDE 'errors.html' %]
+
+<fieldset>
+ <div id="problem_form">
+ [% IF c.user_exists %]
+ [% PROCESS "report/new/form_user_loggedin.html" %]
+ [% ELSE %]
+ [% PROCESS "report/new/form_user_loggedout.html" %]
+ [% END %]
+ [% PROCESS 'report/new/form_report.html' %]
+ </div>
+</fieldset>
diff --git a/templates/web/base/report/new/oauth_email_form.html b/templates/web/base/report/new/oauth_email_form.html
new file mode 100644
index 000000000..c897aaeea
--- /dev/null
+++ b/templates/web/base/report/new/oauth_email_form.html
@@ -0,0 +1,26 @@
+<h1>[% loc('Report your problem') %]</h1>
+
+<p class="form-error">
+ [% loc('Please note your report has <strong>not yet been sent</strong>.') %]
+ [% loc('We need your email address, please give it below.') %]
+</p>
+
+[% TRY %][% PROCESS 'report/new/sidebar.html' %][% CATCH file %][% END %]
+
+[% INCLUDE 'errors.html' %]
+
+<fieldset>
+ <div id="problem_form">
+ [% PROCESS 'report/new/form_user_loggedout_email.html' required=1 %]
+
+ <div id="form_sign_in">
+ <h3>[% loc("Now to submit your report&hellip;") %]</h3>
+ <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2>
+ [% PROCESS 'report/new/form_user_loggedout_by_email.html' %]
+ [% PROCESS 'report/new/form_user_loggedout_password.html' %]
+ </div>
+
+ <input type="hidden" name="oauth_need_email" value="1">
+ [% PROCESS 'report/new/form_report.html' %]
+ </div>
+</fieldset>
diff --git a/templates/web/base/report/update-form.html b/templates/web/base/report/update-form.html
index adf1130bf..3e0ac890b 100644
--- a/templates/web/base/report/update-form.html
+++ b/templates/web/base/report/update-form.html
@@ -1,6 +1,8 @@
[% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_body) %]
-[% IF allow_creation %]
+[% RETURN IF NOT allow_creation %]
+
<div id="update_form">
+ [% IF NOT login_success AND NOT oauth_need_email %]
<h2>[% loc( 'Provide an update') %]</h2>
[% IF c.cobrand.moniker != 'emptyhomes' AND c.cobrand.moniker != 'stevenage' %]
@@ -8,157 +10,33 @@
[% INCLUDE 'report/updates-sidebar-notes.html' %]
</div>
[% END %]
+ [% END %]
[% INCLUDE 'errors.html' %]
<form method="post" action="[% c.uri_for( '/report/update' ) %]" id="form_update_form" name="updateForm" class="validate"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %]>
<fieldset>
- <input type="hidden" name="submit_update" value="1">
- <input type="hidden" name="id" value="[% problem.id | html %]">
-
- [% IF c.cobrand.allow_photo_upload %]
- <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
- <label for="form_photo">[% loc('Photo') %]</label>
-
- [% IF field_errors.photo %]
- <p class='form-error'>[% field_errors.photo %]</p>
- [% END %]
-
- <div id="form_photos">
- [% IF upload_fileid %]
- <script>
- var fixmystreet = fixmystreet || {};
- fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
- </script>
- <p>[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]</p>
- [% FOREACH id IN upload_fileid.split(',') %]
- <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
- [% END %]
- [% END %]
- <input type="file" name="photo1" id="form_photo">
- <input type="file" name="photo2" id="form_photo2">
- <input type="file" name="photo3" id="form_photo3">
- </div>
- [% END %]
-
- <label for="form_update">[% loc( 'Update' ) %]</label>
- [% IF field_errors.update %]
- <div class='form-error'>[% field_errors.update %]</div>
- [% END %]
- <textarea rows="7" cols="30" name="update" id="form_update" placeholder="[% loc('Please write your update here') %]" required>[% update.text | html %]</textarea>
-
- [% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %]
- <label for="form_state">[% loc( 'State' ) %]</label>
- <select name="state" id="form_state">
- [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
- loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
- ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
- ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
- ['fixed', loc('Fixed')] ] %]
- <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
- [% END %]
- </select>
- [% ELSE %]
- [% IF problem.is_fixed AND ((c.user_exists AND c.user.id == problem.user_id) OR alert_to_reporter) %]
-
- <input type="checkbox" name="reopen" id="form_reopen" value="1"[% ' checked' IF update.mark_open %]>
- <label class="inline" for="form_reopen">[% loc('This problem has not been fixed') %]</label>
-
- [% ELSIF !problem.is_fixed %]
-
- <div class="checkbox-group">
- <input type="checkbox" name="fixed" id="form_fixed" value="1"[% ' checked' IF update.mark_fixed %]>
- <label class="inline" for="form_fixed">[% loc('This problem has been fixed') %]</label>
- </div>
-
- [% END %]
- [% END %]
-
- [% IF c.user_exists %]
-
- [% INCLUDE name %]
-
- <input class="final-submit green-btn" type="submit" id="update_post" value="[% loc('Post') %]">
-
-
- [% ELSE %]
-
- <label for="form_rznvy">[% loc('Your email' ) %]
- <span class="muted">([% loc('We never show your email') %])</span>
- </label>
- [% IF field_errors.email %]
- <p class='form-error'>[% field_errors.email %]</p>
- [% END %]
- <input type="email" name="rznvy" id="form_rznvy" value="[% update.user.email | html %]" placeholder="[% loc('Your email address' ) %]" required>
-
+ [% IF NOT login_success AND NOT oauth_need_email %]
+ [% INCLUDE 'report/update/form_update.html' %]
+ [% END %]
+ [% IF c.user_exists %]
+ [% INCLUDE 'report/update/form_name.html' %]
+ <div class="cf"><input class="final-submit green-btn" type="submit" id="update_post" value="[% loc('Post') %]"></div>
+ [% ELSIF oauth_need_email %]
+ [% INCLUDE 'report/update/form_user_loggedout_email.html' required = 1 %]
<div id="form_sign_in">
<h3>[% loc("Now to submit your update&hellip;") %]</h3>
<h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2>
-
- <div id="form_sign_in_yes" class="form-box">
- <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
-
- <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label>
- [% IF field_errors.password %]
- <p class='form-error'>[% field_errors.password %]</p>
- [% END %]
- <div class="form-txt-submit-box">
- <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]">
- <input class="green-btn" type="submit" name="submit_sign_in" id="submit_sign_in" value="[% loc('Post') %]">
- </div>
-
- <div class="checkbox-group">
- <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
- <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
- </div>
-
- <div class="general-notes">
- <p><strong>[% loc('Forgotten your password?') %]</strong>
- [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p>
- </div>
-
- </div>
- <div id="form_sign_in_no" class="form-box">
- <h5>[% loc('<strong>No</strong> Let me confirm my update by email') %]</h5>
-
- [% INCLUDE name %]
-
- <label for="password_register">[% loc('Password (optional)') %]</label>
-
- <div class="general-notes">
- <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
- </div>
-
- <div class="form-txt-submit-box">
- <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
- <input class="green-btn" type="submit" name="submit_register" id="submit_register" value="[% loc('Post') %]">
- </div>
-
- </div>
+ [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %]
+ [% INCLUDE 'report/update/form_user_loggedout_password.html' %]
+ <input type="hidden" name="oauth_need_email" value="1">
</div>
-
- [% END %]
+ [% ELSE %]
+ [% INCLUDE 'report/update/form_user_loggedout.html' %]
+ [% END %]
+ [% IF login_success OR oauth_need_email %]
+ [% INCLUDE 'report/update/form_update.html' %]
+ [% END %]
</fieldset>
</form>
</div>
-[% END %]
-
-[% BLOCK name %]
- [% INCLUDE 'report/new/extra_name.html' %]
- <label for="form_name">[% loc('Name') %]</label>
- [% IF field_errors.name %]
- <p class='form-error'>[% field_errors.name %]</p>
- [% END %]
- <input type="text"
- [%- IF c.cobrand.moniker.match('fixmystreet|bromley') AND problem.bodies_str == '2482' %]class="validName" [% END -%]
- name="name" id="form_name" value="[% update.name || c.user.name | html %]" placeholder="[% loc('Your name') %]">
-
- <div class="checkbox-group">
- <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF update.anonymous==0 OR (c.cobrand.default_show_name AND update.anonymous=='') %]>
- <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label>
- </div>
- <div class="checkbox-group">
- <input type="checkbox" name="add_alert" id="form_add_alert" value="1"[% ' checked' IF add_alert %]>
- <label class="inline" for="form_add_alert">[% loc( 'Alert me to future updates' ) %]</label>
- </div>
-[% END %]
diff --git a/templates/web/base/report/update/form_name.html b/templates/web/base/report/update/form_name.html
new file mode 100644
index 000000000..8311922e3
--- /dev/null
+++ b/templates/web/base/report/update/form_name.html
@@ -0,0 +1,21 @@
+[% INCLUDE 'report/new/extra_name.html' %]
+
+[% name_public = update.anonymous==0 OR (c.cobrand.default_show_name AND update.anonymous=='') %]
+<label for="form_name">[% loc('Name') %]</label>
+[% IF field_errors.name %]
+ <p class='form-error'>[% field_errors.name %]</p>
+[% END %]
+
+<input type="text"
+ [%- IF c.cobrand.moniker.match('fixmystreet|bromley') AND problem.bodies_str == '2482' %]class="validName" [% END -%]
+ name="name" id="form_name" value="[% update.name || c.user.name | html %]" placeholder="[% loc('Your name') %]">
+
+<div class="checkbox-group">
+ <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF name_public %]>
+ <label class="inline" for="form_may_show_name">[% loc('Show my name publicly') %]</label>
+</div>
+
+<div class="checkbox-group">
+ <input type="checkbox" name="add_alert" id="form_add_alert" value="1"[% ' checked' IF add_alert %]>
+ <label class="inline" for="form_add_alert">[% loc( 'Alert me to future updates' ) %]</label>
+</div>
diff --git a/templates/web/base/report/update/form_update.html b/templates/web/base/report/update/form_update.html
new file mode 100644
index 000000000..3a46694cf
--- /dev/null
+++ b/templates/web/base/report/update/form_update.html
@@ -0,0 +1,60 @@
+<input type="hidden" name="submit_update" value="1">
+<input type="hidden" name="id" value="[% problem.id | html %]">
+
+[% IF c.cobrand.allow_photo_upload %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ <label for="form_photo">[% loc('Photo') %]</label>
+
+ [% IF field_errors.photo %]
+ <p class='form-error'>[% field_errors.photo %]</p>
+ [% END %]
+
+ <div id="form_photos">
+ [% IF upload_fileid %]
+ <script>
+ var fixmystreet = fixmystreet || {};
+ fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
+ </script>
+ <p>[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]</p>
+ [% FOREACH id IN upload_fileid.split(',') %]
+ <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
+ [% END %]
+ [% END %]
+ <input type="file" name="photo1" id="form_photo">
+ <input type="file" name="photo2" id="form_photo2">
+ <input type="file" name="photo3" id="form_photo3">
+ </div>
+[% END %]
+
+<label for="form_update">[% loc( 'Update' ) %]</label>
+[% IF field_errors.update %]
+ <div class='form-error'>[% field_errors.update %]</div>
+[% END %]
+<textarea rows="7" cols="30" name="update" id="form_update" placeholder="[% loc('Please write your update here') %]" required>[% update.text | html %]</textarea>
+
+[% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %]
+ <label for="form_state">[% loc( 'State' ) %]</label>
+ <select name="state" id="form_state">
+ [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
+ loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
+ ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
+ ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
+ ['fixed', loc('Fixed')] ] %]
+ <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
+ [% END %]
+ </select>
+[% ELSE %]
+ [% IF problem.is_fixed AND ((c.user_exists AND c.user.id == problem.user_id) OR alert_to_reporter) %]
+
+ <input type="checkbox" name="reopen" id="form_reopen" value="1"[% ' checked' IF update.mark_open %]>
+ <label class="inline" for="form_reopen">[% loc('This problem has not been fixed') %]</label>
+
+ [% ELSIF !problem.is_fixed %]
+
+ <div class="checkbox-group">
+ <input type="checkbox" name="fixed" id="form_fixed" value="1"[% ' checked' IF update.mark_fixed %]>
+ <label class="inline" for="form_fixed">[% loc('This problem has been fixed') %]</label>
+ </div>
+
+ [% END %]
+[% END %]
diff --git a/templates/web/base/report/update/form_user_loggedout.html b/templates/web/base/report/update/form_user_loggedout.html
new file mode 100644
index 000000000..4176633f1
--- /dev/null
+++ b/templates/web/base/report/update/form_user_loggedout.html
@@ -0,0 +1,24 @@
+[% IF c.config.FACEBOOK_APP_ID %]
+ <h3>[% loc("Now to submit your update&hellip;") %]</h3>
+ <div class="form-box">
+ <button name="facebook_sign_in" id="facebook_sign_in" value="facebook_sign_in" class="btn btn--block btn--social btn--facebook">
+ <img alt="" src="/i/facebook-icon-32.png" width="17" height="32">
+ Log in with Facebook
+ </button>
+ </div>
+ <div id="js-social-email-hide">
+ [% INCLUDE 'report/update/form_user_loggedout_email.html' required=0 %]
+[% ELSE %]
+ [% INCLUDE 'report/update/form_user_loggedout_email.html' required=1 %]
+ <h3>[% loc("Now to submit your update&hellip;") %]</h3>
+[% END %]
+
+<div id="form_sign_in">
+ <h2>[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]</h2>
+ [% INCLUDE 'report/update/form_user_loggedout_password.html' %]
+ [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %]
+</div>
+
+[% IF c.config.FACEBOOK_APP_ID %]
+ </div>
+[% END %]
diff --git a/templates/web/base/report/update/form_user_loggedout_by_email.html b/templates/web/base/report/update/form_user_loggedout_by_email.html
new file mode 100644
index 000000000..672f76ed9
--- /dev/null
+++ b/templates/web/base/report/update/form_user_loggedout_by_email.html
@@ -0,0 +1,17 @@
+<div id="form_sign_in_no" class="form-box">
+ <h5>[% loc('<strong>No</strong> Let me confirm my update by email') %]</h5>
+
+ [% INCLUDE 'report/update/form_name.html' %]
+
+ <label for="password_register">[% loc('Password (optional)') %]</label>
+
+ <div class="general-notes">
+ <p>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</p>
+ </div>
+
+ <div class="form-txt-submit-box">
+ <input type="password" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
+ <input class="green-btn" type="submit" name="submit_register" id="submit_register" value="[% loc('Post') %]">
+ </div>
+
+</div>
diff --git a/templates/web/base/report/update/form_user_loggedout_email.html b/templates/web/base/report/update/form_user_loggedout_email.html
new file mode 100644
index 000000000..95a3b5578
--- /dev/null
+++ b/templates/web/base/report/update/form_user_loggedout_email.html
@@ -0,0 +1,9 @@
+<label for="form_rznvy">[% loc('Your email' ) %]
+<span class="muted">([% loc('We never show your email') %])</span>
+</label>
+[% IF field_errors.email %]
+ <p class='form-error'>[% field_errors.email %]</p>
+[% END %]
+<input type="email" name="rznvy" id="form_rznvy" value="[% update.user.email | html %]" placeholder="[% loc('Your email address' ) %]"
+ [% IF required %]required[% END %]
+ class="required">
diff --git a/templates/web/base/report/update/form_user_loggedout_password.html b/templates/web/base/report/update/form_user_loggedout_password.html
new file mode 100644
index 000000000..cd4433c47
--- /dev/null
+++ b/templates/web/base/report/update/form_user_loggedout_password.html
@@ -0,0 +1,23 @@
+<div id="form_sign_in_yes" class="form-box">
+ <h5>[% loc('<strong>Yes</strong> I have a password') %]</h5>
+
+ <label class="hidden-js n" for="password_sign_in">[% loc('Yes I have a password') %]</label>
+ [% IF field_errors.password %]
+ <p class='form-error'>[% field_errors.password %]</p>
+ [% END %]
+ <div class="form-txt-submit-box">
+ <input type="password" name="password_sign_in" id="password_sign_in" value="" placeholder="[% loc('Your password') %]">
+ <input class="green-btn" type="submit" name="submit_sign_in" id="submit_sign_in" value="[% loc('Post') %]">
+ </div>
+
+ <div class="checkbox-group">
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="inline n" for="remember_me">[% loc('Keep me signed in on this computer') %]</label>
+ </div>
+
+ <div class="general-notes">
+ <p><strong>[% loc('Forgotten your password?') %]</strong>
+ [% loc('Confirm by email below, providing a new password at that point. When you confirm, your password will be updated.') %]</p>
+ </div>
+
+</div>
diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js
index 975a8e227..7c0a752d2 100644
--- a/web/cobrands/fixmystreet/fixmystreet.js
+++ b/web/cobrands/fixmystreet/fixmystreet.js
@@ -301,6 +301,20 @@ $(function(){
});
}
+ /* Log in with email button */
+ var email_form = $('#js-social-email-hide'),
+ button = $('<button class="btn btn--social btn--social-email">Log in with email</button>'),
+ form_box = $('<div class="form-box"></div>');
+ button.click(function(e){
+ e.preventDefault();
+ email_form.fadeIn(500);
+ form_box.hide();
+ });
+ form_box.append(button).insertBefore(email_form);
+ if ($('.form-error').length) {
+ button.click();
+ }
+
/*
* Show on click - pretty generic
*/
diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss
index 79ed91d97..8992893bb 100644
--- a/web/cobrands/sass/_base.scss
+++ b/web/cobrands/sass/_base.scss
@@ -316,6 +316,9 @@ label{
font-size:1.25em;
margin:0.5em 0;
}
+ h2 {
+ margin: 0 0 0.5em;
+ }
h5 {
margin:0 0 1em;
font: {
@@ -738,6 +741,33 @@ input.final-submit {
float: $right;
}
+.btn--facebook {
+ @include button-reset(#3b5998, darken(#3b5998, 10%), #3b5998, #fff, darken(#3b5998, 5%), darken(#3b5998, 10%), #3b5998, #fff);
+
+ &:visited {
+ color: #fff;
+ }
+
+ img {
+ margin-right: 0.5em;
+ vertical-align: -0.2em;
+ height: 1.3em;
+ width: auto;
+ }
+}
+
+// Under the button to override its text transform and width
+.btn--social {
+ display: block;
+ width: 100%;
+ text-transform: none;
+ text-align: center;
+}
+
+.js #js-social-email-hide {
+ display: none;
+}
+
.button-fwd {
padding: flip(1em 3em 1em 1em, 1em 1em 1em 3em);
background: inline-image("../fixmystreet/images/chevron-grey-#{$right}.svg") $right 50% no-repeat;
diff --git a/web/cobrands/sass/_h5bp.scss b/web/cobrands/sass/_h5bp.scss
index f4078cca6..f2074532c 100644
--- a/web/cobrands/sass/_h5bp.scss
+++ b/web/cobrands/sass/_h5bp.scss
@@ -42,6 +42,9 @@ body, button, input, select, textarea {
color: #222;
background-color: #fff
}
+input[disabled] {
+ color: #888;
+}
/*
* Remove text-shadow in selection highlight: h5bp.com/i
diff --git a/web/i/facebook-icon-32.png b/web/i/facebook-icon-32.png
new file mode 100644
index 000000000..460ddc8a6
--- /dev/null
+++ b/web/i/facebook-icon-32.png
Binary files differ
diff --git a/web/js/fixmystreet.js b/web/js/fixmystreet.js
index 51fa01559..312a3e294 100644
--- a/web/js/fixmystreet.js
+++ b/web/js/fixmystreet.js
@@ -128,6 +128,12 @@ $(function(){
$('#form_name').addClass('required').removeClass('valid');
} );
+ $('#facebook_sign_in').click(function(e){
+ $('#form_email').removeClass();
+ $('#form_rznvy').removeClass();
+ $('#email').removeClass();
+ });
+
// Geolocation
if (geo_position_js.init()) {
var link = '<a href="#LINK" id="geolocate_link">&hellip; ' + translation_strings.geolocate + '</a>';