aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/zurich-overdue-alert1
m---------commonlib0
-rw-r--r--db/schema_0035-update_alert_types_for_bodies.sql19
-rw-r--r--perllib/FixMyStreet/App.pm22
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm112
-rw-r--r--perllib/FixMyStreet/App/Controller/Around.pm7
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth.pm6
-rw-r--r--perllib/FixMyStreet/App/Controller/Location.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/Open311.pm6
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm7
-rw-r--r--perllib/FixMyStreet/Cobrand/Default.pm41
-rw-r--r--perllib/FixMyStreet/Cobrand/Zurich.pm221
-rw-r--r--perllib/FixMyStreet/DB/Result/Alert.pm31
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm32
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm53
-rw-r--r--perllib/FixMyStreet/DB/Result/Questionnaire.pm28
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/AlertType.pm1
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Problem.pm2
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm1
-rw-r--r--perllib/FixMyStreet/Map/Zurich.pm44
-rw-r--r--perllib/FixMyStreet/SendReport/Email.pm1
-rw-r--r--perllib/FixMyStreet/SendReport/Open311.pm2
-rw-r--r--perllib/FixMyStreet/SendReport/Zurich.pm10
-rw-r--r--perllib/Open311.pm2
-rw-r--r--perllib/Open311/GetServiceRequestUpdates.pm2
-rw-r--r--perllib/Utils.pm7
-rw-r--r--t/app/controller/around.t2
-rw-r--r--t/app/controller/report_new.t2
-rw-r--r--t/app/model/comment.t4
-rw-r--r--t/app/model/problem.t8
-rw-r--r--t/cobrand/zurich.t56
-rw-r--r--templates/email/zurich/alert-moderation-overdue.txt4
-rw-r--r--templates/email/zurich/alert-overdue.txt2
-rw-r--r--templates/email/zurich/problem-closed.txt2
-rwxr-xr-xtemplates/email/zurich/problem-confirm.txt2
-rw-r--r--templates/email/zurich/problem-external.txt2
-rw-r--r--templates/email/zurich/problem-rejected.txt2
-rwxr-xr-xtemplates/email/zurich/reply-autoresponse.txt2
-rw-r--r--templates/email/zurich/submit-external-personal.txt8
-rw-r--r--templates/email/zurich/submit-external.txt2
-rwxr-xr-xtemplates/email/zurich/submit-feedback-pending.txt4
-rw-r--r--templates/email/zurich/submit-in-progress.txt2
-rw-r--r--templates/email/zurich/submit.txt2
-rw-r--r--templates/web/default/admin/list_updates.html2
-rw-r--r--templates/web/default/admin/report_blocks.html18
-rw-r--r--templates/web/default/admin/report_edit.html1
-rw-r--r--templates/web/default/admin/reports.html9
-rw-r--r--templates/web/default/admin/timeline.html2
-rw-r--r--templates/web/default/admin/users.html7
-rw-r--r--templates/web/default/alert/index.html6
-rw-r--r--templates/web/default/alert/list.html6
-rw-r--r--templates/web/default/around/around_map_list_items.html2
-rw-r--r--templates/web/default/around/on_map_list_items.html2
-rw-r--r--templates/web/default/contact/index.html8
-rw-r--r--templates/web/default/index.html8
-rw-r--r--templates/web/default/my/my.html6
-rw-r--r--templates/web/default/pagination.html22
-rw-r--r--templates/web/default/report/banner.html2
-rw-r--r--templates/web/default/report/updates.html8
-rw-r--r--templates/web/fixmybarangay/alert/index.html6
-rw-r--r--templates/web/fixmystreet/contact/index.html8
-rw-r--r--templates/web/fixmystreet/index.html3
-rw-r--r--templates/web/fixmystreet/my/my.html2
-rw-r--r--templates/web/fixmystreet/pagination.html15
-rw-r--r--templates/web/fixmystreet/report/_item.html10
-rw-r--r--templates/web/fixmystreet/report/banner.html2
-rw-r--r--templates/web/zurich/admin/header.html13
-rw-r--r--templates/web/zurich/admin/index-dm.html22
-rw-r--r--templates/web/zurich/admin/index-sdm.html22
-rw-r--r--templates/web/zurich/admin/index.html6
-rw-r--r--templates/web/zurich/admin/list_updates.html2
-rw-r--r--templates/web/zurich/admin/problem_row.html23
-rw-r--r--templates/web/zurich/admin/report_edit-sdm.html32
-rw-r--r--templates/web/zurich/admin/report_edit.html28
-rw-r--r--templates/web/zurich/admin/reports.html18
-rw-r--r--templates/web/zurich/admin/stats.html54
-rw-r--r--templates/web/zurich/auth/general.html71
-rwxr-xr-xtemplates/web/zurich/faq/faq-de-ch.html260
-rw-r--r--templates/web/zurich/footer.html15
-rw-r--r--templates/web/zurich/header.html8
-rw-r--r--templates/web/zurich/report/_item.html10
-rw-r--r--templates/web/zurich/report/_main.html2
-rw-r--r--templates/web/zurich/report/updates.html2
-rw-r--r--templates/web/zurich/tracking_code.html18
-rw-r--r--web/cobrands/fixmystreet/_base.scss12
-rw-r--r--web/cobrands/fixmystreet/images/spinner-white.gifbin0 -> 2646 bytes
-rw-r--r--web/cobrands/zurich/_zurich.scss9
-rw-r--r--web/cobrands/zurich/base.scss25
-rw-r--r--web/cobrands/zurich/layout.scss91
-rw-r--r--web/cobrands/zurich/mapbg-1024.jpgbin0 -> 134052 bytes
-rw-r--r--web/cobrands/zurich/mapbg-1600.jpgbin0 -> 244838 bytes
-rw-r--r--web/i/pin-green-big.pngbin0 -> 3270 bytes
-rw-r--r--web/i/pin-red-big.pngbin0 -> 3401 bytes
-rw-r--r--web/js/fixmystreet.js7
-rw-r--r--web/js/map-OpenLayers.js14
-rw-r--r--web/js/map-wmts-zurich.js42
96 files changed, 1151 insertions, 578 deletions
diff --git a/bin/zurich-overdue-alert b/bin/zurich-overdue-alert
index aa9f6fe60..3ba8b9163 100755
--- a/bin/zurich-overdue-alert
+++ b/bin/zurich-overdue-alert
@@ -72,6 +72,7 @@ sub send_alert {
{
_template_ => $template,
_parameters_ => $h,
+ _line_indent => $cobrand->email_indent,
To => $to,
From => [ FixMyStreet->config('CONTACT_EMAIL'), FixMyStreet->config('CONTACT_NAME') ],
},
diff --git a/commonlib b/commonlib
-Subproject 98ea3736edb949184eef7d575c9caa12748b35b
+Subproject d34573a26f0894c28ac118fa27c6945223fcf85
diff --git a/db/schema_0035-update_alert_types_for_bodies.sql b/db/schema_0035-update_alert_types_for_bodies.sql
new file mode 100644
index 000000000..d7f1be475
--- /dev/null
+++ b/db/schema_0035-update_alert_types_for_bodies.sql
@@ -0,0 +1,19 @@
+BEGIN;
+
+ UPDATE alert_type set item_where = 'problem.non_public = ''f'' and problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'',
+ ''internal referral'' ) AND
+ (bodies_str like ''%''||?||''%'' or bodies_str is null) and
+ areas like ''%,''||?||'',%''' WHERE ref = 'council_problems';
+
+ UPDATE alert_type set item_where = 'problem.non_public = ''f'' and problem.state in
+ (''confirmed'', ''investigating'', ''planned'', ''in progress'',
+ ''fixed'', ''fixed - council'', ''fixed - user'', ''closed'',
+ ''action scheduled'', ''not responsible'', ''duplicate'', ''unable to fix'',
+ ''internal referral'' ) AND
+ (bodies_str like ''%''||?||''%'' or bodies_str is null) and
+ areas like ''%,''||?||'',%''' WHERE ref = 'ward_problems';
+
+COMMIT;
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm
index b76f4d3ba..4469ad1c9 100644
--- a/perllib/FixMyStreet/App.pm
+++ b/perllib/FixMyStreet/App.pm
@@ -315,6 +315,7 @@ sub send_email {
{
_template_ => $email->body, # will get line wrapped
_parameters_ => {},
+ _line_indent => $c->cobrand->email_indent,
$email->header_pairs
}
) };
@@ -443,18 +444,29 @@ Hashref contains height, width and url keys.
sub get_photo_params {
my ($self, $key) = @_;
- $key = ($key eq 'id') ? '' : "/$key";
return {} unless $self->photo;
+ $key = ($key eq 'id') ? '' : "/$key";
+
+ my $pre = "/photo$key/" . $self->id;
+ my $post = '.jpeg';
my $photo = {};
+
if (length($self->photo) == 40) {
- $photo->{url_full} = '/photo' . $key . '/' . $self->id . '.full.jpeg';
+ $post .= '?' . $self->photo;
+ $photo->{url_full} = "$pre.full$post";
+ # XXX Can't use size here because {url} (currently 250px height) may be
+ # being used, but at this point it doesn't yet exist to find the width
+ # $str = FixMyStreet->config('UPLOAD_DIR') . $self->photo . '.jpeg';
} else {
- ( $photo->{width}, $photo->{height} ) =
- Image::Size::imgsize( \$self->photo );
+ my $str = \$self->photo;
+ ( $photo->{width}, $photo->{height} ) = Image::Size::imgsize( $str );
}
- $photo->{url} = '/photo' . $key . '/' . $self->id . '.jpeg';
+
+ $photo->{url} = "$pre$post";
+ $photo->{url_tn} = "$pre.tn$post";
+ $photo->{url_fp} = "$pre.fp$post";
return $photo;
}
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index a3a241590..bb7ec2381 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -145,34 +145,34 @@ sub timeline : Path( 'timeline' ) : Args(0) {
my $probs = $c->cobrand->problems->timeline;
foreach ($probs->all) {
- push @{$time{$_->created->epoch}}, { type => 'problemCreated', date => $_->created_local, obj => $_ };
- push @{$time{$_->confirmed->epoch}}, { type => 'problemConfirmed', date => $_->confirmed_local, obj => $_ } if $_->confirmed;
- push @{$time{$_->whensent->epoch}}, { type => 'problemSent', date => $_->whensent_local, obj => $_ } if $_->whensent;
+ push @{$time{$_->created->epoch}}, { type => 'problemCreated', date => $_->created, obj => $_ };
+ push @{$time{$_->confirmed->epoch}}, { type => 'problemConfirmed', date => $_->confirmed, obj => $_ } if $_->confirmed;
+ push @{$time{$_->whensent->epoch}}, { type => 'problemSent', date => $_->whensent, obj => $_ } if $_->whensent;
}
my $questionnaires = $c->model('DB::Questionnaire')->timeline( $c->cobrand->restriction );
foreach ($questionnaires->all) {
- push @{$time{$_->whensent->epoch}}, { type => 'quesSent', date => $_->whensent_local, obj => $_ };
- push @{$time{$_->whenanswered->epoch}}, { type => 'quesAnswered', date => $_->whenanswered_local, obj => $_ } if $_->whenanswered;
+ push @{$time{$_->whensent->epoch}}, { type => 'quesSent', date => $_->whensent, obj => $_ };
+ push @{$time{$_->whenanswered->epoch}}, { type => 'quesAnswered', date => $_->whenanswered, obj => $_ } if $_->whenanswered;
}
my $updates = $c->model('DB::Comment')->timeline( $site_restriction );
foreach ($updates->all) {
- push @{$time{$_->created->epoch}}, { type => 'update', date => $_->created_local, obj => $_} ;
+ push @{$time{$_->created->epoch}}, { type => 'update', date => $_->created, obj => $_} ;
}
my $alerts = $c->model('DB::Alert')->timeline_created( $c->cobrand->restriction );
foreach ($alerts->all) {
- push @{$time{$_->whensubscribed->epoch}}, { type => 'alertSub', date => $_->whensubscribed_local, obj => $_ };
+ push @{$time{$_->whensubscribed->epoch}}, { type => 'alertSub', date => $_->whensubscribed, obj => $_ };
}
$alerts = $c->model('DB::Alert')->timeline_disabled( $c->cobrand->restriction );
foreach ($alerts->all) {
- push @{$time{$_->whendisabled->epoch}}, { type => 'alertDel', date => $_->whendisabled_local, obj => $_ };
+ push @{$time{$_->whendisabled->epoch}}, { type => 'alertDel', date => $_->whendisabled, obj => $_ };
}
$c->model('DB')->schema->storage->sql_maker->quote_char( '' );
@@ -485,6 +485,25 @@ sub body_edit : Path('body_edit') : Args(2) {
sub reports : Path('reports') {
my ( $self, $c ) = @_;
+ my $query = {};
+ if ( $c->cobrand->moniker eq 'zurich' ) {
+ my $type = $c->stash->{admin_type};
+ my $body = $c->stash->{body};
+ if ( $type eq 'dm' ) {
+ my @children = map { $_->id } $body->bodies->all;
+ my @all = (@children, $body->id);
+ $query = { bodies_str => \@all };
+ } elsif ( $type eq 'sdm' ) {
+ $query = { bodies_str => $body->id };
+ }
+ }
+
+ my $order = $c->req->params->{o} || 'created';
+ my $dir = defined $c->req->params->{d} ? $c->req->params->{d} : 1;
+ $c->stash->{order} = $order;
+ $c->stash->{dir} = $dir;
+ $order .= ' desc' if $dir;
+
if (my $search = $c->req->param('search')) {
$c->stash->{searched} = $search;
@@ -503,21 +522,20 @@ sub reports : Path('reports') {
$c->model('DB')->schema->storage->sql_maker->quote_char( '"' );
$c->model('DB')->schema->storage->sql_maker->name_sep( '.' );
- my $query;
if (is_valid_email($search)) {
- $query = [
+ $query->{'-or'} = [
'user.email' => { ilike => $like_search },
];
} elsif ($search =~ /^id:(\d+)$/) {
- $query = [
+ $query->{'-or'} = [
'me.id' => int($1),
];
} elsif ($search =~ /^area:(\d+)$/) {
- $query = [
+ $query->{'-or'} = [
'me.areas' => { like => "%,$1,%" }
];
} else {
- $query = [
+ $query->{'-or'} = [
'me.id' => $search_n,
'user.email' => { ilike => $like_search },
'me.name' => { ilike => $like_search },
@@ -527,13 +545,12 @@ sub reports : Path('reports') {
cobrand_data => { like => $like_search },
];
}
+
my $problems = $c->cobrand->problems->search(
- {
- -or => $query,
- },
+ $query,
{
prefetch => 'user',
- order_by => [\"(state='hidden')",'created']
+ order_by => [ \"(state='hidden')", \$order ]
}
);
@@ -576,7 +593,7 @@ sub reports : Path('reports') {
{
-select => [ 'me.*', qw/problem.bodies_str problem.state/ ],
prefetch => [qw/user problem/],
- order_by => [\"(me.state='hidden')",\"(problem.state='hidden')",'me.created']
+ order_by => [ \"(me.state='hidden')", \"(problem.state='hidden')", 'me.created' ]
}
);
$c->stash->{updates} = [ $updates->all ];
@@ -584,6 +601,15 @@ sub reports : Path('reports') {
# Switch quoting back off. See above for explanation of this.
$c->model('DB')->schema->storage->sql_maker->quote_char( '' );
+ } else {
+
+ my $page = $c->req->params->{p} || 1;
+ my $problems = $c->cobrand->problems->search(
+ $query,
+ { order_by => $order }
+ )->page( $page );
+ $c->stash->{problems} = [ $problems->all ];
+ $c->stash->{pager} = $problems->pager;
}
}
@@ -601,13 +627,8 @@ sub report_edit : Path('report_edit') : Args(1) {
$c->forward('get_token');
- if ( $c->req->param('rotate_photo') ) {
- $c->forward('rotate_photo');
- return 1;
- }
-
if ( $c->cobrand->moniker eq 'zurich' ) {
-
+ $c->stash->{page} = 'admin';
FixMyStreet::Map::display_map(
$c,
latitude => $problem->latitude,
@@ -616,12 +637,19 @@ sub report_edit : Path('report_edit') : Args(1) {
? [ {
latitude => $problem->latitude,
longitude => $problem->longitude,
- colour => 'yellow',
+ colour => $c->cobrand->pin_colour($problem),
type => 'big',
} ]
: [],
);
+ }
+
+ if ( $c->req->param('rotate_photo') ) {
+ $c->forward('rotate_photo');
+ return 1;
+ }
+ if ( $c->cobrand->moniker eq 'zurich' ) {
my $done = $c->cobrand->admin_report_edit();
return if $done;
}
@@ -782,6 +810,16 @@ sub users: Path('users') : Args(0) {
} else {
$c->forward('get_token');
$c->forward('fetch_all_bodies');
+
+ # Admin users by default
+ my $users = $c->model('DB::User')->search(
+ { from_body => { '!=', undef } },
+ { order_by => 'name' }
+ );
+ my @users = $users->all;
+ my %email2user = map { $_->email => $_ } @users;
+ $c->stash->{users} = \@users;
+
}
return 1;
@@ -903,6 +941,8 @@ sub user_add : Path('user_edit') : Args(0) {
$c->forward('check_token');
+ return unless $c->req->param('name') && $c->req->param('email');
+
my $user = $c->model('DB::User')->find_or_create( {
name => $c->req->param('name'),
email => $c->req->param('email'),
@@ -982,7 +1022,7 @@ sub stats : Path('stats') : Args(0) {
$c->forward('fetch_all_bodies');
- if ( $c->cobrand->moniker eq 'seesomething' ) {
+ if ( $c->cobrand->moniker eq 'seesomething' || $c->cobrand->moniker eq 'zurich' ) {
return $c->cobrand->admin_stats();
}
@@ -1288,7 +1328,7 @@ sub rotate_photo : Private {
my ( $self, $c ) =@_;
my $direction = $c->req->param('rotate_photo');
- return unless $direction =~ /Left/ or $direction =~ /Right/;
+ return unless $direction eq _('Rotate Left') or $direction eq _('Rotate Right');
my $photo = $c->stash->{problem}->photo;
my $file;
@@ -1299,16 +1339,12 @@ sub rotate_photo : Private {
$photo = $file->slurp;
}
- $photo = _rotate_image( $photo, $direction =~ /Left/ ? -90 : 90 );
+ $photo = _rotate_image( $photo, $direction eq _('Rotate Left') ? -90 : 90 );
return unless $photo;
- my $fileid;
- if ( !$file ) {
- $fileid = sha1_hex($photo);
- $file = file( $c->config->{UPLOAD_DIR}, "$fileid.jpeg" );
- }
-
- $c->stash->{rotated} = 1;
+ # Write out to new location
+ my $fileid = sha1_hex($photo);
+ $file = file( $c->config->{UPLOAD_DIR}, "$fileid.jpeg" );
my $fh = $file->open('w');
print $fh $photo;
@@ -1316,10 +1352,8 @@ sub rotate_photo : Private {
unlink glob FixMyStreet->path_to( 'web', 'photo', $c->stash->{problem}->id . '.*' );
- if ( $fileid ) {
- $c->stash->{problem}->photo( $fileid );
- $c->stash->{problem}->update();
- }
+ $c->stash->{problem}->photo( $fileid );
+ $c->stash->{problem}->update();
return 1;
}
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm
index 9a754f063..bad269a83 100644
--- a/perllib/FixMyStreet/App/Controller/Around.pm
+++ b/perllib/FixMyStreet/App/Controller/Around.pm
@@ -40,9 +40,10 @@ sub around_index : Path : Args(0) {
my $partial_report = $c->forward('load_partial');
# Try to create a location for whatever we have
- return
- unless $c->forward('/location/determine_location_from_coords')
- || $c->forward('/location/determine_location_from_pc');
+ my $ret = $c->forward('/location/determine_location_from_coords')
+ || $c->forward('/location/determine_location_from_pc');
+ return unless $ret;
+ return $c->res->redirect('/') if $ret == -1 && !$partial_report;
# Check to see if the spot is covered by a area - if not show an error.
return unless $c->cobrand->moniker eq 'fixmybarangay' || $c->forward('check_location_is_acceptable');
diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm
index f4d6d86e4..57b53a155 100644
--- a/perllib/FixMyStreet/App/Controller/Auth.pm
+++ b/perllib/FixMyStreet/App/Controller/Auth.pm
@@ -31,7 +31,7 @@ sub general : Path : Args(0) {
my $req = $c->req;
$c->detach( 'redirect_on_signin', [ $req->param('r') ] )
- if $c->user && $req->param('r') && $req->param('r') !~ /admin/;
+ if $c->user && $req->param('r');
# all done unless we have a form posted to us
return unless $req->method eq 'POST';
@@ -182,6 +182,10 @@ Used after signing in to take the person back to where they were.
sub redirect_on_signin : Private {
my ( $self, $c, $redirect ) = @_;
$redirect = 'my' unless $redirect;
+ if ( $c->cobrand->moniker eq 'zurich' ) {
+ $redirect = 'my' if $redirect eq 'admin';
+ $redirect = 'admin' if $c->user->from_body;
+ }
$c->res->redirect( $c->uri_for( "/$redirect" ) );
}
diff --git a/perllib/FixMyStreet/App/Controller/Location.pm b/perllib/FixMyStreet/App/Controller/Location.pm
index fd3fadd9f..f103ff7f9 100644
--- a/perllib/FixMyStreet/App/Controller/Location.pm
+++ b/perllib/FixMyStreet/App/Controller/Location.pm
@@ -50,6 +50,8 @@ sub determine_location_from_coords : Private {
User has searched for a location - try to find it for them.
+Return -1 if nothing provided.
+
If one match is found returns true and lat/lng is set.
If several possible matches are found puts an array onto stash so that user can be prompted to pick one and returns false.
@@ -62,7 +64,7 @@ sub determine_location_from_pc : Private {
my ( $self, $c, $pc ) = @_;
# check for something to search
- $pc ||= $c->req->param('pc') || return;
+ $pc ||= $c->req->param('pc') || return -1;
$c->stash->{pc} = $pc; # for template
if ( $pc =~ /^(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)$/ ) {
diff --git a/perllib/FixMyStreet/App/Controller/Open311.pm b/perllib/FixMyStreet/App/Controller/Open311.pm
index 7b8cb649f..a4e72e9bd 100644
--- a/perllib/FixMyStreet/App/Controller/Open311.pm
+++ b/perllib/FixMyStreet/App/Controller/Open311.pm
@@ -240,8 +240,8 @@ sub output_requests : Private {
'long' => [ $problem->longitude ],
'status' => [ $problem->state ],
# 'status_notes' => [ {} ],
- 'requested_datetime' => [ w3date($problem->confirmed_local) ],
- 'updated_datetime' => [ w3date($problem->lastupdate_local) ],
+ 'requested_datetime' => [ w3date($problem->confirmed) ],
+ 'updated_datetime' => [ w3date($problem->lastupdate) ],
# 'expected_datetime' => [ {} ],
# 'address' => [ {} ],
# 'address_id' => [ {} ],
@@ -260,7 +260,7 @@ sub output_requests : Private {
if ( $problem->whensent ) {
# Not in Open311 v2
$request->{'agency_sent_datetime'} =
- [ w3date($problem->whensent_local) ];
+ [ w3date($problem->whensent) ];
}
# Extract number of updates
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index 460ccaec5..57b2d781e 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -173,7 +173,10 @@ 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(
- $problem->as_hashref( $c )
+ {
+ report => $c->cobrand->problem_as_hashref( $problem, $c ),
+ updates => $c->cobrand->updates_as_hashref( $problem, $c ),
+ }
);
$c->res->body( $content );
return 1;
@@ -196,7 +199,7 @@ sub generate_map_tags : Private {
? [ {
latitude => $problem->latitude,
longitude => $problem->longitude,
- colour => 'yellow',
+ colour => $c->cobrand->moniker eq 'zurich'? $c->cobrand->pin_colour($problem) : 'yellow',
type => 'big',
} ]
: [],
diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm
index 0c8d567c4..257d9ec24 100644
--- a/perllib/FixMyStreet/Cobrand/Default.pm
+++ b/perllib/FixMyStreet/Cobrand/Default.pm
@@ -708,7 +708,7 @@ Returns the colour of pin to be used for a particular report
=cut
sub pin_colour {
my ( $self, $p, $context ) = @_;
- #return 'green' if time() - $p->confirmed_local->epoch < 7 * 24 * 60 * 60;
+ #return 'green' if time() - $p->confirmed->epoch < 7 * 24 * 60 * 60;
return 'yellow' if $context eq 'around' || $context eq 'reports';
return $p->is_fixed ? 'green' : 'red';
}
@@ -795,5 +795,44 @@ sub show_unconfirmed_reports {
0;
}
+=head2 prettify_dt
+
+ my $date = $c->prettify_dt( $datetime );
+
+Takes a datetime object and returns a string representation.
+
+=cut
+
+sub prettify_dt {
+ my $self = shift;
+ my $dt = shift;
+
+ return Utils::prettify_dt( $dt, 1 );
+}
+
+=head2 email_indent
+
+Set to an indent string if you wish to override the default email handling.
+
+=cut
+
+sub email_indent { undef; }
+
+sub problem_as_hashref {
+ my $self = shift;
+ my $problem = shift;
+ my $ctx = shift;
+
+ return $problem->as_hashref( $ctx );
+}
+
+sub updates_as_hashref {
+ my $self = shift;
+ my $problem = shift;
+ my $ctx = shift;
+
+ return {};
+}
+
1;
diff --git a/perllib/FixMyStreet/Cobrand/Zurich.pm b/perllib/FixMyStreet/Cobrand/Zurich.pm
index ec65ec8f0..7ac776df2 100644
--- a/perllib/FixMyStreet/Cobrand/Zurich.pm
+++ b/perllib/FixMyStreet/Cobrand/Zurich.pm
@@ -39,11 +39,68 @@ sub languages { [ 'de-ch,Deutsch,de_CH', 'en-gb,English,en_GB' ] };
sub uri {
my ( $self, $uri ) = @_;
- $uri->query_param( zoom => 7 )
+ $uri->query_param( zoom => 6 )
if $uri->query_param('lat') && !$uri->query_param('zoom');
return $uri;
}
+sub prettify_dt {
+ my $self = shift;
+ my $dt = shift;
+
+ return Utils::prettify_dt( $dt, 'zurich' );
+}
+
+sub problem_as_hashref {
+ my $self = shift;
+ my $problem = shift;
+ my $ctx = shift;
+
+ my $hashref = $problem->as_hashref( $ctx );
+
+ if ( $problem->state eq 'unconfirmed' ) {
+ for my $var ( qw( photo detail state state_t is_fixed meta ) ) {
+ delete $hashref->{ $var };
+ }
+ $hashref->{detail} = _('This report is awaiting moderation.');
+ $hashref->{state} = 'submitted';
+ $hashref->{state_t} = _('Submitted');
+ } else {
+ if ( $problem->state eq 'confirmed' ) {
+ $hashref->{state} = 'open';
+ $hashref->{state_t} = _('Open');
+ } elsif ( $problem->is_fixed ) {
+ $hashref->{state} = 'closed';
+ $hashref->{state_t} = _('Closed');
+ } elsif ( $problem->state eq 'in progress' || $problem->state eq 'planned' ) {
+ $hashref->{state} = 'in progress';
+ $hashref->{state_t} = _('In progress');
+ }
+ }
+
+ return $hashref;
+}
+
+sub updates_as_hashref {
+ my $self = shift;
+ my $problem = shift;
+ my $ctx = shift;
+
+ my $hashref = {};
+
+ if ( $problem->state eq 'fixed - council' || $problem->state eq 'closed' ) {
+ $hashref->{update_pp} = $self->prettify_dt( $problem->lastupdate );
+
+ if ( $problem->state eq 'fixed - council' ) {
+ $hashref->{details} = FixMyStreet::App::View::Web->add_links( $ctx, $problem->extra->{public_response} );
+ } elsif ( $problem->state eq 'closed' ) {
+ $hashref->{details} = sprintf( _('Assigned to %s'), $problem->body($ctx)->name );
+ }
+ }
+
+ return $hashref;
+}
+
sub remove_redundant_areas {
my $self = shift;
my $all_areas = shift;
@@ -115,16 +172,18 @@ sub overdue {
if ( $problem->state eq 'unconfirmed' || $problem->state eq 'confirmed' ) {
# One working day
$w = add_days( $w, 1 );
- return $w < DateTime->now();
+ return $w < DateTime->now() ? 1 : 0;
} elsif ( $problem->state eq 'in progress' ) {
# Five working days
$w = add_days( $w, 5 );
- return $w < DateTime->now();
+ return $w < DateTime->now() ? 1 : 0;
} else {
return 0;
}
}
+sub email_indent { ''; }
+
# Specific administrative displays
sub admin_pages {
@@ -149,6 +208,7 @@ sub admin_pages {
$pages = { %$pages,
'users' => [_('Users'), 3],
+ 'stats' => [_('Stats'), 4],
'user_edit' => [undef, undef],
};
return $pages if $type eq 'super';
@@ -188,37 +248,68 @@ sub admin {
my @children = map { $_->id } $body->bodies->all;
my @all = (@children, $body->id);
+ my $order = $c->req->params->{o} || 'created';
+ my $dir = defined $c->req->params->{d} ? $c->req->params->{d} : 1;
+ $c->stash->{order} = $order;
+ $c->stash->{dir} = $dir;
+ $order .= ' desc' if $dir;
+
# XXX No multiples or missing bodies
$c->stash->{unconfirmed} = $c->cobrand->problems->search({
state => [ 'unconfirmed', 'confirmed' ],
bodies_str => $c->stash->{body}->id,
+ }, {
+ order_by => $order,
});
$c->stash->{approval} = $c->cobrand->problems->search({
state => 'planned',
bodies_str => $c->stash->{body}->id,
+ }, {
+ order_by => $order,
});
+
+ my $page = $c->req->params->{p} || 1;
$c->stash->{other} = $c->cobrand->problems->search({
state => { -not_in => [ 'unconfirmed', 'confirmed', 'planned' ] },
bodies_str => \@all,
- });
+ }, {
+ order_by => $order,
+ })->page( $page );
+ $c->stash->{pager} = $c->stash->{other}->pager;
+
} elsif ($type eq 'sdm') {
$c->stash->{template} = 'admin/index-sdm.html';
my $body = $c->stash->{body};
+ my $order = $c->req->params->{o} || 'created';
+ my $dir = defined $c->req->params->{d} ? $c->req->params->{d} : 1;
+ $c->stash->{order} = $order;
+ $c->stash->{dir} = $dir;
+ $order .= ' desc' if $dir;
+
# XXX No multiples or missing bodies
$c->stash->{reports_new} = $c->cobrand->problems->search( {
state => 'in progress',
bodies_str => $body->id,
+ }, {
+ order_by => $order
} );
$c->stash->{reports_unpublished} = $c->cobrand->problems->search( {
state => 'planned',
bodies_str => $body->parent->id,
+ }, {
+ order_by => $order
} );
+
+ my $page = $c->req->params->{p} || 1;
$c->stash->{reports_published} = $c->cobrand->problems->search( {
state => 'fixed - council',
bodies_str => $body->parent->id,
- } );
+ }, {
+ order_by => $order
+ } )->page( $page );
+ $c->stash->{pager} = $c->stash->{reports_published}->pager;
}
}
@@ -274,8 +365,7 @@ sub admin_report_edit {
$extra->{publish_photo} = $c->req->params->{publish_photo} || 0;
$extra->{third_personal} = $c->req->params->{third_personal} || 0;
# Make sure we have a copy of the original detail field
- $extra->{original_detail} = $problem->detail unless $extra->{original_detail};
- $problem->extra( { %$extra } );
+ $extra->{original_detail} = $problem->detail if !$extra->{original_detail} && $c->req->params->{detail} && $problem->detail ne $c->req->params->{detail};
# Workflow things
my $redirect = 0;
@@ -286,14 +376,17 @@ sub admin_report_edit {
$problem->external_body( undef );
$problem->bodies_str( $cat->body_id );
$problem->whensent( undef );
+ $extra->{changed_category} = 1;
$redirect = 1 if $cat->body_id ne $body->id;
} elsif ( my $subdiv = $c->req->params->{body_subdivision} ) {
+ $extra->{moderated_overdue} = $self->overdue( $problem );
$problem->state( 'in progress' );
$problem->external_body( undef );
$problem->bodies_str( $subdiv );
$problem->whensent( undef );
$redirect = 1;
} elsif ( my $external = $c->req->params->{body_external} ) {
+ $extra->{moderated_overdue} = $self->overdue( $problem );
$problem->state( 'closed' );
$problem->external_body( $external );
$problem->whensent( undef );
@@ -306,8 +399,11 @@ sub admin_report_edit {
}
}
+ $problem->extra( { %$extra } );
$problem->title( $c->req->param('title') );
$problem->detail( $c->req->param('detail') );
+ $problem->latitude( $c->req->param('latitude') );
+ $problem->longitude( $c->req->param('longitude') );
# Final, public, Update from DM
if (my $update = $c->req->param('status_update')) {
@@ -357,14 +453,23 @@ sub admin_report_edit {
} elsif ($c->req->param('submit')) {
$c->forward('check_token');
+ my $db_update = 0;
+ if ( $c->req->param('latitude') != $problem->latitude || $c->req->param('longitude') != $problem->longitude ) {
+ $problem->latitude( $c->req->param('latitude') );
+ $problem->longitude( $c->req->param('longitude') );
+ $db_update = 1;
+ }
+
my $extra = $problem->extra || {};
$extra->{internal_notes} ||= '';
if ($c->req->param('internal_notes') && $c->req->param('internal_notes') ne $extra->{internal_notes}) {
$extra->{internal_notes} = $c->req->param('internal_notes');
$problem->extra( { %$extra } );
- $problem->update;
+ $db_update = 1;
}
+ $problem->update if $db_update;
+
# Add new update from status_update
if (my $update = $c->req->param('status_update')) {
FixMyStreet::App->model('DB::Comment')->create( {
@@ -384,9 +489,11 @@ sub admin_report_edit {
if ($c->req->param('no_more_updates')) {
$problem->bodies_str( $body->parent->id );
$problem->whensent( undef );
+ my $extra = $problem->extra || {};
+ $extra->{subdiv_overdue} = $self->overdue( $problem );
+ $problem->extra( { %$extra } );
$problem->state( 'planned' );
$problem->update;
- # log here
$c->res->redirect( '/admin/summary' );
}
}
@@ -412,9 +519,15 @@ sub _admin_send_email {
? [ $problem->user->email, $problem->name ]
: $problem->user->email;
+ # Similar to what SendReport::Zurich does to find address to send to
+ my $body = ( values %{$problem->bodies} )[0];
+ my $sender = $body->endpoint || $c->cobrand->contact_email;
+ my $sender_name = $c->cobrand->contact_name; # $body->name?
+
$c->send_email( $template, {
to => [ $to ],
url => $c->uri_for_email( $problem->url ),
+ from => [ $sender, $sender_name ],
} );
}
@@ -457,4 +570,94 @@ sub admin_fetch_all_bodies {
return @out;
}
+sub admin_stats {
+ my $self = shift;
+ my $c = $self->{c};
+
+ my %date_params;
+ my $ym = $c->req->params->{ym};
+ my ($m, $y) = $ym =~ /^(\d+)\.(\d+)$/;
+ $c->stash->{ym} = $ym;
+ if ($y && $m) {
+ $c->stash->{start_date} = DateTime->new( year => $y, month => $m, day => 1 );
+ $c->stash->{end_date} = $c->stash->{start_date} + DateTime::Duration->new( months => 1 );
+ $date_params{created} = { '>=', $c->stash->{start_date}, '<', $c->stash->{end_date} };
+ }
+
+ my %params = (
+ %date_params,
+ state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
+ );
+
+ if ( $c->req->params->{export} ) {
+ my $problems = $c->model('DB::Problem')->search( { %params }, { columns => [ 'id', 'created', 'latitude', 'longitude', 'cobrand', 'category' ] } );
+ my $body = "ID,Created,E,N,Category\n";
+ while (my $report = $problems->next) {
+ $body .= join( ',', $report->id, $report->created, $report->local_coords, $report->category ) . "\n";
+ }
+ $c->res->content_type('text/csv; charset=utf-8');
+ $c->res->body($body);
+ }
+
+ # Total reports (non-hidden)
+ my $total = $c->model('DB::Problem')->search( \%params )->count;
+ # Device for apps (iOS/Android)
+ my $per_service = $c->model('DB::Problem')->search( \%params, {
+ select => [ 'service', { count => 'id' } ],
+ as => [ 'service', 'c' ],
+ group_by => [ 'service' ],
+ });
+ # Reports solved
+ my $solved = $c->model('DB::Problem')->search( { state => 'fixed - council', %date_params } )->count;
+ # Reports marked as spam
+ my $hidden = $c->model('DB::Problem')->search( { state => 'hidden', %date_params } )->count;
+ # Reports assigned to third party
+ my $closed = $c->model('DB::Problem')->search( { state => 'closed', %date_params } )->count;
+ # Reports moderated within 1 day
+ my $moderated = $c->model('DB::Problem')->search( { extra => { like => '%moderated_overdue,I1:0%' }, %params } )->count;
+ # Reports solved within 5 days
+ my $subdiv_dealtwith = $c->model('DB::Problem')->search( { extra => { like => '%subdiv_overdue,I1:0%' }, %params } )->count;
+ # Reports per category
+ my $per_category = $c->model('DB::Problem')->search( \%params, {
+ select => [ 'category', { count => 'id' } ],
+ as => [ 'category', 'c' ],
+ group_by => [ 'category' ],
+ });
+ # How many reports have had their category changed by a DM (wrong category chosen by user)
+ my $changed = $c->model('DB::Problem')->search( { extra => { like => '%changed_category,I1:1%' }, %params } )->count;
+ # pictures taken
+ my $pictures_taken = $c->model('DB::Problem')->search( { photo => { '!=', undef }, %params } )->count;
+ # pictures published
+ my $pictures_published = $c->model('DB::Problem')->search( { extra => { like => '%publish_photo,I1:1%' }, %params } )->count;
+ # how many times was a telephone number provided
+ # XXX => How many users have a telephone number stored
+ # my $phone = $c->model('DB::User')->search( { phone => { '!=', undef } } )->count;
+ # how many times was the email address confirmed
+ my $email_confirmed = $c->model('DB::Problem')->search( { extra => { like => '%email_confirmed%' }, %params } )->count;
+ # how many times was the name provided
+ my $name = $c->model('DB::Problem')->search( { name => { '!=', '' }, %params } )->count;
+ # how many times was the geolocation used vs. addresssearch
+ # ?
+
+ $c->stash(
+ per_service => $per_service,
+ per_category => $per_category,
+ reports_total => $total,
+ reports_solved => $solved,
+ reports_spam => $hidden,
+ reports_assigned => $closed,
+ reports_moderated => $moderated,
+ reports_dealtwith => $subdiv_dealtwith,
+ reports_category_changed => $changed,
+ pictures_taken => $pictures_taken,
+ pictures_published => $pictures_published,
+ #users_phone => $phone,
+ email_confirmed => $email_confirmed,
+ name_provided => $name,
+ # GEO
+ );
+
+ return 1;
+}
+
1;
diff --git a/perllib/FixMyStreet/DB/Result/Alert.pm b/perllib/FixMyStreet/DB/Result/Alert.pm
index ca9ad45c2..fc84c8fd5 100644
--- a/perllib/FixMyStreet/DB/Result/Alert.pm
+++ b/perllib/FixMyStreet/DB/Result/Alert.pm
@@ -77,22 +77,21 @@ with 'FixMyStreet::Roles::Abuser';
my $tz = DateTime::TimeZone->new( name => "local" );
-
-sub whensubscribed_local {
- my $self = shift;
-
- return $self->whensubscribed
- ? $self->whensubscribed->set_time_zone($tz)
- : $self->whensubscribed;
-}
-
-sub whendisabled_local {
- my $self = shift;
-
- return $self->whendisabled
- ? $self->whendisabled->set_time_zone($tz)
- : $self->whendisabled;
-}
+my $tz_f;
+$tz_f = DateTime::TimeZone->new( name => FixMyStreet->config('TIME_ZONE') )
+ if FixMyStreet->config('TIME_ZONE');
+
+my $stz = sub {
+ my ( $orig, $self ) = ( shift, shift );
+ my $s = $self->$orig(@_);
+ return $s unless $s && UNIVERSAL::isa($s, "DateTime");
+ $s->set_time_zone($tz);
+ $s->set_time_zone($tz_f) if $tz_f;
+ return $s;
+};
+
+around whensubscribed => $stz;
+around whendisabled => $stz;
=head2 confirm
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 33fbb9356..eb9e52a65 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -116,23 +116,21 @@ with 'FixMyStreet::Roles::Abuser';
my $tz = DateTime::TimeZone->new( name => "local" );
-sub created_local {
- my $self = shift;
-
- return $self->created
- ? $self->created->set_time_zone($tz)
- : $self->created;
-}
-
-sub confirmed_local {
- my $self = shift;
-
- # if confirmed is null then it doesn't get inflated so don't
- # try and set the timezone
- return $self->confirmed
- ? $self->confirmed->set_time_zone($tz)
- : $self->confirmed;
-}
+my $tz_f;
+$tz_f = DateTime::TimeZone->new( name => FixMyStreet->config('TIME_ZONE') )
+ if FixMyStreet->config('TIME_ZONE');
+
+my $stz = sub {
+ my ( $orig, $self ) = ( shift, shift );
+ my $s = $self->$orig(@_);
+ return $s unless $s && UNIVERSAL::isa($s, "DateTime");
+ $s->set_time_zone($tz);
+ $s->set_time_zone($tz_f) if $tz_f;
+ return $s;
+};
+
+around created => $stz;
+around confirmed => $stz;
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 24aa12944..ec15600b6 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -301,6 +301,7 @@ sub all_states {
'confirmed' => 1,
'investigating' => 1,
'in progress' => 1,
+ 'planned' => 1,
'action scheduled' => 1,
'fixed' => 1,
'fixed - council' => 1,
@@ -342,37 +343,23 @@ sub council_states {
my $tz = DateTime::TimeZone->new( name => "local" );
-sub confirmed_local {
- my $self = shift;
-
- return $self->confirmed
- ? $self->confirmed->set_time_zone($tz)
- : $self->confirmed;
-}
-
-sub created_local {
- my $self = shift;
-
- return $self->created
- ? $self->created->set_time_zone($tz)
- : $self->created;
-}
-
-sub whensent_local {
- my $self = shift;
+my $tz_f;
+$tz_f = DateTime::TimeZone->new( name => FixMyStreet->config('TIME_ZONE') )
+ if FixMyStreet->config('TIME_ZONE');
- return $self->whensent
- ? $self->whensent->set_time_zone($tz)
- : $self->whensent;
-}
-
-sub lastupdate_local {
- my $self = shift;
+my $stz = sub {
+ my ( $orig, $self ) = ( shift, shift );
+ my $s = $self->$orig(@_);
+ return $s unless $s && UNIVERSAL::isa($s, "DateTime");
+ $s->set_time_zone($tz);
+ $s->set_time_zone($tz_f) if $tz_f;
+ return $s;
+};
- return $self->lastupdate
- ? $self->lastupdate->set_time_zone($tz)
- : $self->lastupdate;
-}
+around created => $stz;
+around confirmed => $stz;
+around whensent => $stz;
+around lastupdate => $stz;
around service => sub {
my ( $orig, $self ) = ( shift, shift );
@@ -574,7 +561,7 @@ meta data about the report.
sub meta_line {
my ( $problem, $c ) = @_;
- my $date_time = Utils::prettify_dt( $problem->confirmed_local );
+ my $date_time = Utils::prettify_dt( $problem->confirmed );
my $meta = '';
# FIXME Should be in cobrand
@@ -709,7 +696,7 @@ sub duration_string {
my ( $problem, $c ) = @_;
my $body = $problem->body( $c );
return sprintf(_('Sent to %s %s later'), $body,
- Utils::prettify_duration($problem->whensent_local->epoch - $problem->confirmed_local->epoch, 'minute')
+ Utils::prettify_duration($problem->whensent->epoch - $problem->confirmed->epoch, 'minute')
);
}
@@ -832,8 +819,8 @@ sub as_hashref {
is_fixed => $self->fixed_states->{ $self->state } ? 1 : 0,
photo => $self->get_photo_params,
meta => $self->confirmed ? $self->meta_line( $c ) : '',
- confirmed_pp => $self->confirmed ? Utils::prettify_dt( $self->confirmed_local, 1 ): '',
- created_pp => Utils::prettify_dt( $self->created_local, 1 ),
+ confirmed_pp => $self->confirmed ? $c->cobrand->prettify_dt( $self->confirmed ): '',
+ created_pp => $c->cobrand->prettify_dt( $self->created ),
};
}
diff --git a/perllib/FixMyStreet/DB/Result/Questionnaire.pm b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
index b6791603a..fcaa17d99 100644
--- a/perllib/FixMyStreet/DB/Result/Questionnaire.pm
+++ b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
@@ -44,23 +44,25 @@ __PACKAGE__->belongs_to(
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:NGlSRjoBpDoIvK3EueqN6Q
use DateTime::TimeZone;
+use Moose;
+use namespace::clean -except => [ 'meta' ];
my $tz = DateTime::TimeZone->new( name => "local" );
-sub whensent_local {
- my $self = shift;
+my $tz_f;
+$tz_f = DateTime::TimeZone->new( name => FixMyStreet->config('TIME_ZONE') )
+ if FixMyStreet->config('TIME_ZONE');
- return $self->whensent
- ? $self->whensent->set_time_zone($tz)
- : $self->whensent;
-}
+my $stz = sub {
+ my ( $orig, $self ) = ( shift, shift );
+ my $s = $self->$orig(@_);
+ return $s unless $s && UNIVERSAL::isa($s, "DateTime");
+ $s->set_time_zone($tz);
+ $s->set_time_zone($tz_f) if $tz_f;
+ return $s;
+};
-sub whenanswered_local {
- my $self = shift;
-
- return $self->whenanswered
- ? $self->whenanswered->set_time_zone($tz)
- : $self->whenanswered;
-}
+around whensent => $stz;
+around whenanswered => $stz;
1;
diff --git a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
index 8e9b3d17e..f2b86725d 100644
--- a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
@@ -236,6 +236,7 @@ sub _send_aggregated_alert_email(%) {
{
_template_ => $template,
_parameters_ => \%data,
+ _line_indent => $cobrand->email_indent,
From => [ $sender, _($cobrand->contact_name) ],
To => $data{alert_email},
},
diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
index 116151753..dc1c5c248 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
@@ -269,7 +269,7 @@ sub send_reports {
# Template variables for the email
my $email_base_url = $cobrand->base_url_for_report($row);
my %h = map { $_ => $row->$_ } qw/id title detail name category latitude longitude used_map/;
- map { $h{$_} = $row->user->$_ } qw/email phone/;
+ map { $h{$_} = $row->user->$_ || '' } qw/email phone/;
$h{confirmed} = DateTime::Format::Pg->format_datetime( $row->confirmed->truncate (to => 'second' ) )
if $row->confirmed;
diff --git a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
index 1b9521a9f..8d811180e 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
@@ -101,6 +101,7 @@ sub send_questionnaires_period {
{
_template_ => $template,
_parameters_ => \%h,
+ _line_indent => $cobrand->email_indent,
To => [ [ $row->user->email, $row->name ] ],
From => [ $sender, $sender_name ],
},
diff --git a/perllib/FixMyStreet/Map/Zurich.pm b/perllib/FixMyStreet/Map/Zurich.pm
index 262b6e229..73ebc5608 100644
--- a/perllib/FixMyStreet/Map/Zurich.pm
+++ b/perllib/FixMyStreet/Map/Zurich.pm
@@ -13,9 +13,10 @@ use Geo::Coordinates::CH1903;
use Math::Trig;
use Utils;
-use constant ZOOM_LEVELS => 7;
+use constant ZOOM_LEVELS => 8;
use constant DEFAULT_ZOOM => 5;
use constant MIN_ZOOM_LEVEL => 0;
+use constant ID_OFFSET => 2;
sub map_tiles {
my ( $self, %params ) = @_;
@@ -45,31 +46,24 @@ sub copyright {
sub display_map {
my ($self, $c, %params) = @_;
- my $numZoomLevels = ZOOM_LEVELS;
- my $zoomOffset = MIN_ZOOM_LEVEL;
-# if ($params{any_zoom}) {
-# $numZoomLevels = 10;
-# $zoomOffset = 0;
-# }
-
- # TODO Adjust zoom level dependent upon population density
- my $default_zoom = DEFAULT_ZOOM;
-
# Map centre may be overridden in the query string
$params{latitude} = Utils::truncate_coordinate($c->req->params->{lat} + 0)
if defined $c->req->params->{lat};
$params{longitude} = Utils::truncate_coordinate($c->req->params->{lon} + 0)
if defined $c->req->params->{lon};
- my $zoom = defined $c->req->params->{zoom} ? $c->req->params->{zoom} + 0 : $default_zoom;
- $zoom = $numZoomLevels - 1 if $zoom >= $numZoomLevels;
+ my $zoom = defined $c->req->params->{zoom}
+ ? $c->req->params->{zoom} + 0
+ : $c->stash->{page} eq 'report'
+ ? DEFAULT_ZOOM+1
+ : DEFAULT_ZOOM;
+ $zoom = ZOOM_LEVELS - 1 if $zoom >= ZOOM_LEVELS;
$zoom = 0 if $zoom < 0;
- $params{zoom_act} = $zoomOffset + $zoom;
- ($params{x_tile}, $params{y_tile}, $params{matrix_id}) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $params{zoom_act});
+ ($params{x_tile}, $params{y_tile}, $params{matrix_id}) = latlon_to_tile_with_adjust($params{latitude}, $params{longitude}, $zoom);
foreach my $pin (@{$params{pins}}) {
- ($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act});
+ ($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $zoom);
}
$c->stash->{map} = {
@@ -79,8 +73,8 @@ sub display_map {
tiles => $self->map_tiles( %params ),
copyright => $self->copyright(),
zoom => $zoom,
- zoomOffset => $zoomOffset,
- numZoomLevels => $numZoomLevels,
+ zoomOffset => MIN_ZOOM_LEVEL,
+ numZoomLevels => ZOOM_LEVELS,
};
}
@@ -90,13 +84,11 @@ sub latlon_to_tile($$$) {
my ($x, $y) = Geo::Coordinates::CH1903::from_latlon($lat, $lon);
- my $matrix_id = $zoom;
- $matrix_id = 0 if $matrix_id < 0;
-
- my @scales = ( '250000', '125000', '64000', '32000', '16000', '8000', '4000', '2000', '1000' );
+ my $matrix_id = $zoom + ID_OFFSET;
+ my @scales = ( '250000', '125000', '64000', '32000', '16000', '8000', '4000', '2000', '1000', '500' );
my $tileOrigin = { lat => 30814423, lon => -29386322 };
my $tileSize = 256;
- my $res = $scales[$zoom] / (39.3701 * 96); # OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH
+ my $res = $scales[$matrix_id] / (39.3701 * 96); # OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH
my $fx = ( $x - $tileOrigin->{lon} ) / ($res * $tileSize);
my $fy = ( $tileOrigin->{lat} - $y ) / ($res * $tileSize);
@@ -124,10 +116,11 @@ sub latlon_to_tile_with_adjust($$$) {
sub tile_to_latlon {
my ($fx, $fy, $zoom) = @_;
+ my $matrix_id = $zoom + ID_OFFSET;
my @scales = ( '250000', '125000', '64000', '32000', '16000', '8000', '4000', '2000', '1000', '500' );
my $tileOrigin = { lat => 30814423, lon => -29386322 };
my $tileSize = 256;
- my $res = $scales[$zoom] / (39.3701 * 96); # OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH
+ my $res = $scales[$matrix_id] / (39.3701 * 96); # OpenLayers.INCHES_PER_UNIT[units] * OpenLayers.DOTS_PER_INCH
my $x = $fx * $res * $tileSize + $tileOrigin->{lon};
my $y = $tileOrigin->{lat} - $fy * $res * $tileSize;
@@ -164,12 +157,11 @@ sub click_to_tile {
# Given some click co-ords (the tile they were on, and where in the
# tile they were), convert to WGS84 and return.
-# XXX Note use of MIN_ZOOM_LEVEL here. (Copied from OSM, needed here?)
sub click_to_wgs84 {
my ($self, $c, $pin_tile_x, $pin_x, $pin_tile_y, $pin_y) = @_;
my $tile_x = click_to_tile($pin_tile_x, $pin_x);
my $tile_y = click_to_tile($pin_tile_y, $pin_y);
- my $zoom = MIN_ZOOM_LEVEL + (defined $c->req->params->{zoom} ? $c->req->params->{zoom} : DEFAULT_ZOOM);
+ my $zoom = (defined $c->req->params->{zoom} ? $c->req->params->{zoom} : DEFAULT_ZOOM);
my ($lat, $lon) = tile_to_latlon($tile_x, $tile_y, $zoom);
return ( $lat, $lon );
}
diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm
index 1ff476da3..9006e2f11 100644
--- a/perllib/FixMyStreet/SendReport/Email.pm
+++ b/perllib/FixMyStreet/SendReport/Email.pm
@@ -87,6 +87,7 @@ sub send {
{
_template_ => $self->get_template( $row ),
_parameters_ => $h,
+ _line_indent => $row->cobrand eq 'zurich' ? '' : undef, # XXX Access to Cobrand module here?
To => $self->to,
From => $self->send_from( $row ),
},
diff --git a/perllib/FixMyStreet/SendReport/Open311.pm b/perllib/FixMyStreet/SendReport/Open311.pm
index 61f59f725..b92aa8cfd 100644
--- a/perllib/FixMyStreet/SendReport/Open311.pm
+++ b/perllib/FixMyStreet/SendReport/Open311.pm
@@ -57,7 +57,7 @@ sub send {
push @$extra, { name => 'report_title', value => $row->title };
push @$extra, { name => 'public_anonymity_required', value => $row->anonymous ? 'TRUE' : 'FALSE' };
push @$extra, { name => 'email_alerts_requested', value => 'FALSE' }; # always false as can never request them
- push @$extra, { name => 'requested_datetime', value => DateTime::Format::W3CDTF->format_datetime($row->confirmed_local->set_nanosecond(0)) };
+ push @$extra, { name => 'requested_datetime', value => DateTime::Format::W3CDTF->format_datetime($row->confirmed->set_nanosecond(0)) };
push @$extra, { name => 'email', value => $row->user->email };
$row->extra( $extra );
diff --git a/perllib/FixMyStreet/SendReport/Zurich.pm b/perllib/FixMyStreet/SendReport/Zurich.pm
index e0c95283e..4930ff61e 100644
--- a/perllib/FixMyStreet/SendReport/Zurich.pm
+++ b/perllib/FixMyStreet/SendReport/Zurich.pm
@@ -9,12 +9,14 @@ sub build_recipient_list {
# Only one body ever, most of the time with an email endpoint
my $body = @{ $self->bodies }[0];
- $body = FixMyStreet::App->model("DB::Body")->find( { id => $row->external_body } )
- if $row->external_body;
+ if ( $row->external_body ) {
+ $body = FixMyStreet::App->model("DB::Body")->find( { id => $row->external_body } );
+ $h->{bodies_name} = $body->name;
+ }
my $body_email = $body->endpoint;
- my @bodies = $body->bodies;
- if ($body->parent && @bodies) {
+ my $parent = $body->parent;
+ if ($parent && !$parent->parent) {
# Division, might have an individual contact email address
my $contact = FixMyStreet::App->model("DB::Contact")->find( {
body_id => $body->id,
diff --git a/perllib/Open311.pm b/perllib/Open311.pm
index efa0ac64f..3be5ac365 100644
--- a/perllib/Open311.pm
+++ b/perllib/Open311.pm
@@ -322,7 +322,7 @@ sub _populate_service_request_update_params {
}
my $params = {
- updated_datetime => DateTime::Format::W3CDTF->format_datetime($comment->confirmed_local->set_nanosecond(0)),
+ updated_datetime => DateTime::Format::W3CDTF->format_datetime($comment->confirmed->set_nanosecond(0)),
service_request_id => $comment->problem->external_id,
status => $status,
email => $comment->user->email,
diff --git a/perllib/Open311/GetServiceRequestUpdates.pm b/perllib/Open311/GetServiceRequestUpdates.pm
index aae0940c7..ae1f06a50 100644
--- a/perllib/Open311/GetServiceRequestUpdates.pm
+++ b/perllib/Open311/GetServiceRequestUpdates.pm
@@ -120,7 +120,7 @@ sub update_comments {
# if the comment is older than the last update
# do not change the status of the problem as it's
# tricky to determine the right thing to do.
- if ( $comment->created_local > $p->lastupdate_local ) {
+ if ( $comment->created > $p->lastupdate ) {
my $state = $self->map_state( $request->{status} );
# don't update state unless it's an allowed state and it's
diff --git a/perllib/Utils.pm b/perllib/Utils.pm
index 04d973067..27d604a59 100644
--- a/perllib/Utils.pm
+++ b/perllib/Utils.pm
@@ -226,12 +226,7 @@ sub prettify_dt {
$type ||= '';
$type = 'short' if $type eq '1';
- $dt->set_time_zone( FixMyStreet->config('TIME_ZONE') )
- if FixMyStreet->config('TIME_ZONE');
-
- my $now = DateTime->now( time_zone => 'local' );
- $now->set_time_zone( FixMyStreet->config('TIME_ZONE') )
- if FixMyStreet->config('TIME_ZONE');
+ my $now = DateTime->now( time_zone => FixMyStreet->config('TIME_ZONE') || 'local' );
my $tt = '';
$tt = $dt->strftime('%H:%M') unless $type eq 'date';
diff --git a/t/app/controller/around.t b/t/app/controller/around.t
index 0f01a9ea9..fa2d94aed 100644
--- a/t/app/controller/around.t
+++ b/t/app/controller/around.t
@@ -7,7 +7,7 @@ my $mech = FixMyStreet::TestMech->new;
subtest "check that if no query we get sent back to the homepage" => sub {
$mech->get_ok('/around');
- is $mech->uri->path, '/around', "still at '/around'";
+ is $mech->uri->path, '/', "redirected to '/'";
};
# x,y requests were generated by the old map code. We keep the behavior for
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 868977953..722c3c39c 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -17,7 +17,7 @@ ok -e $sample_file, "sample file $sample_file exists";
subtest "test that bare requests to /report/new get redirected" => sub {
$mech->get_ok('/report/new');
- is $mech->uri->path, '/around', "went to /around";
+ is $mech->uri->path, '/', "went to /";
is_deeply { $mech->uri->query_form }, {}, "query empty";
$mech->get_ok('/report/new?pc=SW1A%201AA');
diff --git a/t/app/model/comment.t b/t/app/model/comment.t
index 93104c2e5..3141af828 100644
--- a/t/app/model/comment.t
+++ b/t/app/model/comment.t
@@ -23,5 +23,5 @@ my $comment = $comment_rs->new(
}
);
-is $comment->confirmed_local, undef, 'inflating null confirmed ok';
-is $comment->created_local, undef, 'inflating null confirmed ok';
+is $comment->confirmed, undef, 'inflating null confirmed ok';
+is $comment->created, undef, 'inflating null confirmed ok';
diff --git a/t/app/model/problem.t b/t/app/model/problem.t
index a92e3b079..6ba2bbde4 100644
--- a/t/app/model/problem.t
+++ b/t/app/model/problem.t
@@ -32,10 +32,10 @@ my $problem = $problem_rs->new(
}
);
-is $problem->confirmed_local, undef, 'inflating null confirmed ok';
-is $problem->whensent_local, undef, 'inflating null confirmed ok';
-is $problem->lastupdate_local, undef, 'inflating null confirmed ok';
-is $problem->created_local, undef, 'inflating null confirmed ok';
+is $problem->confirmed, undef, 'inflating null confirmed ok';
+is $problem->whensent, undef, 'inflating null confirmed ok';
+is $problem->lastupdate, undef, 'inflating null confirmed ok';
+is $problem->created, undef, 'inflating null confirmed ok';
for my $test (
{
diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t
index f354f0da4..71c904ed9 100644
--- a/t/cobrand/zurich.t
+++ b/t/cobrand/zurich.t
@@ -1,5 +1,4 @@
# TODO
-# Report to third party (with third_personal)
# Overdue alerts
use strict;
@@ -30,6 +29,10 @@ $subdivision->parent( $division->id );
$subdivision->send_method( 'Zurich' );
$subdivision->endpoint( 'subdivision@example.org' );
$subdivision->update;
+my $external_body = $mech->create_body_ok( 4, 'External Body' );
+$external_body->send_method( 'Zurich' );
+$external_body->endpoint( 'external_body@example.org' );
+$external_body->update;
my @reports = $mech->create_problems_for_body( 1, 2, 'Test', {
state => 'unconfirmed',
@@ -49,7 +52,7 @@ my $user = $mech->log_in_ok( 'dm1@example.org') ;
$user->from_body( undef );
$user->update;
$mech->get_ok( '/admin' );
-is $mech->uri->path, '/auth', "got sent to the sign in page";
+is $mech->uri->path, '/my', "got sent to /my";
$user->from_body( 2 );
$user->update;
@@ -61,6 +64,7 @@ $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") );
$mech->content_contains( 'Erfasst' );
$mech->get_ok( '/admin/report_edit/' . $report->id );
+$mech->content_contains( 'Unbest&auml;tigt' ); # Unconfirmed email
$mech->submit_form_ok( { with_fields => { state => 'confirmed' } } );
$mech->get_ok( '/report/' . $report->id );
$mech->content_contains('Aufgenommen');
@@ -82,7 +86,7 @@ $mech->content_contains( 'Some internal notes' );
# Original description
$mech->submit_form_ok( { with_fields => { detail => 'Edited details text.' } } );
$mech->content_contains( 'Edited details text.' );
-$mech->content_contains( 'originally entered: &ldquo;Test Test 1 for 2 Detail&rdquo;' );
+$mech->content_contains( 'Originaltext: &ldquo;Test Test 1 for 2 Detail&rdquo;' );
$mech->get_ok( '/admin/report_edit/' . $report->id );
$mech->submit_form_ok( { with_fields => { body_subdivision => 3 } } );
@@ -101,7 +105,7 @@ $mech->log_out_ok;
$user = $mech->log_in_ok( 'sdm1@example.org') ;
$mech->get_ok( '/admin' );
-is $mech->uri->path, '/auth', "got sent to the sign in page";
+is $mech->uri->path, '/my', "got sent to /my";
$user->from_body( 3 );
$user->update;
@@ -149,6 +153,7 @@ $report->extra ( { %$extra } );
$report->update;
$mech->get_ok( '/admin/report_edit/' . $report->id );
+$mech->content_lacks( 'Unbest&auml;tigt' ); # Confirmed email
$mech->submit_form_ok( { with_fields => { status_update => 'FINAL UPDATE' } } );
$mech->form_with_fields( 'status_update' );
$mech->submit_form_ok( { button => 'publish_response' } );
@@ -160,9 +165,52 @@ $mech->content_contains('FINAL UPDATE');
$email = $mech->get_email;
like $email->header('To'), qr/test\@example.com/, 'to line looks correct';
+like $email->header('From'), qr/division\@example.org/, 'from line looks correct';
like $email->body, qr/FINAL UPDATE/, 'body looks correct';
$mech->clear_emails_ok;
+# Report assigned to third party
+
+@reports = $mech->create_problems_for_body( 1, 2, 'Third', {
+ state => 'unconfirmed',
+ confirmed => undef,
+ cobrand => 'zurich',
+});
+$report = $reports[0];
+
+$mech->get_ok( '/admin/report_edit/' . $report->id );
+$mech->submit_form_ok( { with_fields => { body_external => 4 } } );
+$mech->get_ok( '/report/' . $report->id );
+$mech->content_contains('Erledigt');
+$mech->content_contains('Third Test');
+$mech->content_contains('An Fachbereich zuweisen: External Body');
+FixMyStreet::App->model('DB::Problem')->send_reports('zurich');
+$email = $mech->get_email;
+like $email->header('Subject'), qr/Neue Meldung/, 'subject looks okay';
+like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct';
+like $email->body, qr/External Body/, 'body has right name';
+unlike $email->body, qr/test\@example.com/, 'body does not contain email address';
+$mech->clear_emails_ok;
+
+# Test calling back, and third_personal boolean setting
+$mech->get_ok( '/admin' );
+is $mech->uri->path, '/admin', "am logged in";
+$mech->content_contains( 'report_edit/' . $report->id );
+$mech->get_ok( '/admin/report_edit/' . $report->id );
+$mech->submit_form_ok( { with_fields => { state => 'unconfirmed' } } );
+$mech->submit_form_ok( { with_fields => { body_external => 4, third_personal => 1 } } );
+$mech->get_ok( '/report/' . $report->id );
+$mech->content_contains('Erledigt');
+$mech->content_contains('Third Test');
+$mech->content_contains('An Fachbereich zuweisen: External Body');
+FixMyStreet::App->model('DB::Problem')->send_reports('zurich');
+$email = $mech->get_email;
+like $email->header('Subject'), qr/Neue Meldung/, 'subject looks okay';
+like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct';
+like $email->body, qr/External Body/, 'body has right name';
+like $email->body, qr/test\@example.com/, 'body does contain email address';
+$mech->clear_emails_ok;
+
$mech->delete_problems_for_body( 2 );
$mech->delete_user( 'dm1@example.org' );
$mech->delete_user( 'sdm1@example.org' );
diff --git a/templates/email/zurich/alert-moderation-overdue.txt b/templates/email/zurich/alert-moderation-overdue.txt
index c3aab66d2..f410956c0 100644
--- a/templates/email/zurich/alert-moderation-overdue.txt
+++ b/templates/email/zurich/alert-moderation-overdue.txt
@@ -1,6 +1,6 @@
-Subject: eskalierte Meldungen auf Fix my Zurich
+Subject: eskalierte Meldungen auf Züri wie neu
-Die folgenden Meldungen auf Fix my Zurich sind älter als einen Tag und müssen dringend bearbeitet werden:
+Die folgenden Meldungen auf Züri wie neu sind älter als einen Tag und müssen dringend bearbeitet werden:
<?=$values['data']?>
diff --git a/templates/email/zurich/alert-overdue.txt b/templates/email/zurich/alert-overdue.txt
index 3301feee5..92bb58f26 100644
--- a/templates/email/zurich/alert-overdue.txt
+++ b/templates/email/zurich/alert-overdue.txt
@@ -1,4 +1,4 @@
-Subject: Rückmeldung erforderlich auf Fix my Zurich
+Subject: Rückmeldung erforderlich auf Züri wie neu
Die folgenden Meldungen wurden eskaliert, da sie nicht innerhalb von fünf Tagen beantwortet worden sind:
diff --git a/templates/email/zurich/problem-closed.txt b/templates/email/zurich/problem-closed.txt
index d7482d8eb..f16c3534d 100644
--- a/templates/email/zurich/problem-closed.txt
+++ b/templates/email/zurich/problem-closed.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Meldung #[% problem.id %]
+Subject: Züri wie neu: Meldung #[% problem.id %]
Guten Tag [% problem.name %]
diff --git a/templates/email/zurich/problem-confirm.txt b/templates/email/zurich/problem-confirm.txt
index 401591681..f1f1af7e9 100755
--- a/templates/email/zurich/problem-confirm.txt
+++ b/templates/email/zurich/problem-confirm.txt
@@ -1,4 +1,4 @@
-Subject: Fix my Zurich: Meldung #[% report.id %]
+Subject: Züri wie neu: Meldung #[% report.id %]
Guten Tag [% report.name %]
diff --git a/templates/email/zurich/problem-external.txt b/templates/email/zurich/problem-external.txt
index bcc1468d4..55263f4a8 100644
--- a/templates/email/zurich/problem-external.txt
+++ b/templates/email/zurich/problem-external.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Meldung #[% problem.id %]
+Subject: Züri wie neu: Meldung #[% problem.id %]
Guten Tag [% problem.name %]
diff --git a/templates/email/zurich/problem-rejected.txt b/templates/email/zurich/problem-rejected.txt
index 447aeaefb..410a77a04 100644
--- a/templates/email/zurich/problem-rejected.txt
+++ b/templates/email/zurich/problem-rejected.txt
@@ -1,4 +1,4 @@
-Subject: Fix my Zurich: Meldung #[% problem.id %]
+Subject: Züri wie neu: Meldung #[% problem.id %]
Guten Tag [% problem.name %]
diff --git a/templates/email/zurich/reply-autoresponse.txt b/templates/email/zurich/reply-autoresponse.txt
index be927f72b..c47a6186f 100755
--- a/templates/email/zurich/reply-autoresponse.txt
+++ b/templates/email/zurich/reply-autoresponse.txt
@@ -7,4 +7,4 @@ Dies ist eine automatische Antwort auf Ihr E-Mail. Ihr E-Mail wurde nicht überm
Falls Sie eine Meldung erfassen möchten, tun Sie das bitte über die Hauptseite:
[%# link to FMZ %]
-Falls Sie Fragen zu Fix my Zurich haben, senden Sie ein E-Mail an gis-zentrum@zuerich.ch
+Falls Sie Fragen zu Züri wie neu haben, senden Sie ein E-Mail an gis-zentrum@zuerich.ch
diff --git a/templates/email/zurich/submit-external-personal.txt b/templates/email/zurich/submit-external-personal.txt
index 36768d3bb..698c5297a 100644
--- a/templates/email/zurich/submit-external-personal.txt
+++ b/templates/email/zurich/submit-external-personal.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Neue Meldung #<?=$values['id']?>
+Subject: Züri wie neu: Neue Meldung #<?=$values['id']?>
Guten Tag <?=$values['bodies_name']?>,
@@ -6,8 +6,8 @@ Diese Meldung wurde Ihnen von der Stadt Zürich gesendet, da es Ihr Zuständigke
Öffentliche URL: <?=$values['url']?>
-Reporter name: <?=$values['name']?>
+Name des Meldenden: <?=$values['name']?>
-Reporter email: <?=$values['email']?>
+Email des Meldenden: <?=$values['email']?>
-Reporter phone: <?=$values['phone']?>
+Telefonnummer des Meldenden: <?=$values['phone']?>
diff --git a/templates/email/zurich/submit-external.txt b/templates/email/zurich/submit-external.txt
index 3e07b0664..56b5e4196 100644
--- a/templates/email/zurich/submit-external.txt
+++ b/templates/email/zurich/submit-external.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Neue Meldung #<?=$values['id']?>
+Subject: Züri wie neu: Neue Meldung #<?=$values['id']?>
Guten Tag <?=$values['bodies_name']?>,
diff --git a/templates/email/zurich/submit-feedback-pending.txt b/templates/email/zurich/submit-feedback-pending.txt
index fbf9cafb9..dbdd9eedb 100755
--- a/templates/email/zurich/submit-feedback-pending.txt
+++ b/templates/email/zurich/submit-feedback-pending.txt
@@ -1,8 +1,8 @@
-Subject: FixMyZurich: Meldung #<?=$values['id']?> bereit für Feedback
+Subject: Züri wie neu: Meldung #<?=$values['id']?> bereit für Feedback
Guten Tag <?=$values['bodies_name']?>,
-Diese Meldung wurde vom Fachbereich abschliessend beantwortet und kann nun auf Fix My Zurich beantwortet und abgeschlossen werden.
+Diese Meldung wurde vom Fachbereich abschliessend beantwortet und kann nun auf Züri wie neu beantwortet und abgeschlossen werden.
Öffentliche URL: <?=$values['url']?>
diff --git a/templates/email/zurich/submit-in-progress.txt b/templates/email/zurich/submit-in-progress.txt
index 809ba4653..3e2254296 100644
--- a/templates/email/zurich/submit-in-progress.txt
+++ b/templates/email/zurich/submit-in-progress.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Neue Meldung #<?=$values['id']?>
+Subject: Züri wie neu: Neue Meldung #<?=$values['id']?>
Guten Tag <?=$values['bodies_name']?>,
diff --git a/templates/email/zurich/submit.txt b/templates/email/zurich/submit.txt
index f55b66e18..15aea7504 100644
--- a/templates/email/zurich/submit.txt
+++ b/templates/email/zurich/submit.txt
@@ -1,4 +1,4 @@
-Subject: FixMyZurich: Neue Meldung #<?=$values['id']?>
+Subject: Züri wie neu: Neue Meldung #<?=$values['id']?>
Guten Tag <?=$values['bodies_name']?>,
diff --git a/templates/web/default/admin/list_updates.html b/templates/web/default/admin/list_updates.html
index ff0ec2f31..681337844 100644
--- a/templates/web/default/admin/list_updates.html
+++ b/templates/web/default/admin/list_updates.html
@@ -1,3 +1,4 @@
+[% IF updates.size %]
<h2>[% loc('Updates') %]</h2>
<table cellspacing="0" cellpadding="2" border="1">
@@ -36,3 +37,4 @@
</tr>
[% END -%]
</table>
+[% END %]
diff --git a/templates/web/default/admin/report_blocks.html b/templates/web/default/admin/report_blocks.html
index bb9f34cb9..c2cffc352 100644
--- a/templates/web/default/admin/report_blocks.html
+++ b/templates/web/default/admin/report_blocks.html
@@ -22,3 +22,21 @@
[% this_date.strftime('%d.%m.%Y') %]
[% ELSE %][% no_time || '&nbsp;' %][% END %][% no_time = '' %]
[%- END %]
+
+[% BLOCK sort_link %][% IF order == choice %][% c.uri_with( d => 1 - dir ) %][% ELSE %][% c.uri_with( { o => choice, d => 0 } ) %][% END %][% END %]
+
+[% BLOCK sort_arrow %]
+ [% IF order == choice %]
+ <span style="font-size:50%">
+ [% IF dir %]
+ &#9660;
+ [% ELSE %]
+ &#9650;
+ [% END %]
+ </span>
+ [% ELSE %]
+ <span style="font-size:50%; color: #999;">
+ &#9650;
+ </span>
+ [% END %]
+[% END %]
diff --git a/templates/web/default/admin/report_edit.html b/templates/web/default/admin/report_edit.html
index 8d0b8df88..91af70d14 100644
--- a/templates/web/default/admin/report_edit.html
+++ b/templates/web/default/admin/report_edit.html
@@ -57,7 +57,6 @@
[% photo = problem.get_photo_params %]
<li><img alt="" height="[% photo.height %]" width="[% photo.width %]" src="[% c.cobrand.base_url %][% photo.url %]">
<br>
-[% IF rotated %]Photo may be cached for a while.<br>[% END %]
<input type="submit" name="rotate_photo" value="[% loc('Rotate Left') %]">
<input type="submit" name="rotate_photo" value="[% loc('Rotate Right') %]">
<br>
diff --git a/templates/web/default/admin/reports.html b/templates/web/default/admin/reports.html
index 600f2b436..fab12cfce 100644
--- a/templates/web/default/admin/reports.html
+++ b/templates/web/default/admin/reports.html
@@ -2,11 +2,10 @@
[% PROCESS 'admin/report_blocks.html' %]
<form method="get" action="[% c.uri_for('reports') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
- <p><label for="search">[% loc('Search:') %]</label> <input type="text" name="search" size="30" id="search">
+ <p><label for="search">[% loc('Search:') %]</label> <input type="text" name="search" size="30" id="search" value="[% searched | html %]">
</form>
-
-[% IF searched %]
+[% IF problems.size %]
<table cellspacing="0" cellpadding="2" border="1">
<tr>
<th>[% loc('ID') %]</th>
@@ -25,8 +24,10 @@
[% INCLUDE 'admin/problem_row.html' %]
</table>
-[% INCLUDE 'admin/list_updates.html' %]
+[% INCLUDE 'pagination.html', admin = 1, param = 'p' IF pager %]
[% END %]
+[% INCLUDE 'admin/list_updates.html' %]
+
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/default/admin/timeline.html b/templates/web/default/admin/timeline.html
index 4058f7f06..2c77e3fbd 100644
--- a/templates/web/default/admin/timeline.html
+++ b/templates/web/default/admin/timeline.html
@@ -34,7 +34,7 @@
[% CASE 'alertSub' %]
[% tprintf(loc("Alert %d created for %s, type %s, parameters %s / %s"), item.obj.id, item.obj.user.email, item.obj.alert_type.ref, item.obj.parameter, item.obj.parameter2) | html %]
[% CASE 'alertDel' %]
- [% tprintf(loc("Alert %d disabled (created %s)"), item.obj.id, item.obj.whensubscribed_local.strftime('%H:%M:%S %e %B %Y') ) %]
+ [% tprintf(loc("Alert %d disabled (created %s)"), item.obj.id, item.obj.whensubscribed.strftime('%H:%M:%S %e %B %Y') ) %]
[%- END %]
<br />
[%- END %]
diff --git a/templates/web/default/admin/users.html b/templates/web/default/admin/users.html
index de0b74746..70833ff85 100644
--- a/templates/web/default/admin/users.html
+++ b/templates/web/default/admin/users.html
@@ -5,7 +5,7 @@
<p><label for="search">[% loc('Search:') %]</label> <input type="text" name="search" size="30" id="search" value="[% searched | html %]">
</form>
-[% IF searched %]
+[% IF users.size %]
<table cellspacing="0" cellpadding="2" border="1">
<tr>
@@ -30,10 +30,11 @@
[%- END -%]
</table>
-[% ELSE %]
+[% END %]
+[% IF NOT searched %]
<h2>[% loc('Add user') %]</h2>
-[% INCLUDE 'admin/user-form.html' %]
+[% INCLUDE 'admin/user-form.html', user = '' %]
[% END %]
diff --git a/templates/web/default/alert/index.html b/templates/web/default/alert/index.html
index 1f0635ae4..36c0daf91 100644
--- a/templates/web/default/alert/index.html
+++ b/templates/web/default/alert/index.html
@@ -40,9 +40,11 @@ To find out what local alerts we have for you, please enter your [% c.cobrand.co
<div class="sticky-sidebar" id="alert_recent">
<aside>
<h2>[% loc('Some photos of recent reports') %]</h2>
- [% FOREACH p IN photos %]
+ [% FOREACH p IN photos;
+ photo = p.get_photo_params;
+ %]
<a href="/report/[% p.id %]"><img border="0" height="100"
- src="/photo/[% p.id %].tn.jpeg" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
[% END %]
</aside>
</div>
diff --git a/templates/web/default/alert/list.html b/templates/web/default/alert/list.html
index 20ebbf455..447bfcd76 100644
--- a/templates/web/default/alert/list.html
+++ b/templates/web/default/alert/list.html
@@ -24,9 +24,11 @@
<div id="alert_photos" class="sticky-sidebar">
<aside>
<h2>[% loc('Photos of recent nearby reports') %]</h2>
- [% FOREACH p IN photos %]
+ [% FOREACH p IN photos;
+ photo = p.get_photo_params;
+ %]
<a href="/report/[% p.id %]"><img border="0" height="100"
- src="/photo/[% p.id %].tn.jpeg" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
[% END %]
</aside>
</div>
diff --git a/templates/web/default/around/around_map_list_items.html b/templates/web/default/around/around_map_list_items.html
index 655d8bd25..da75561b5 100644
--- a/templates/web/default/around/around_map_list_items.html
+++ b/templates/web/default/around/around_map_list_items.html
@@ -5,7 +5,7 @@
<li>
<a href="[% c.uri_for('/report', p.problem.id ) %]">[% p.problem.title | html %]</a>
- <small>[% prettify_dt( p.problem.confirmed_local, 1 ) %], [% dist %]km</small>
+ <small>[% prettify_dt( p.problem.confirmed, 1 ) %], [% dist %]km</small>
[% IF p.problem.is_fixed %]
<small>[% loc('(fixed)') %]</small>
[% ELSIF p.problem.is_closed %]
diff --git a/templates/web/default/around/on_map_list_items.html b/templates/web/default/around/on_map_list_items.html
index 1022c88a0..70a071406 100644
--- a/templates/web/default/around/on_map_list_items.html
+++ b/templates/web/default/around/on_map_list_items.html
@@ -2,7 +2,7 @@
[% FOREACH p IN on_map %]
<li>
<a href="[% c.uri_for('/report', p.id ) %]">[% p.title | html %]</a>
- <small>[% prettify_dt( p.confirmed_local, 1 ) %]</small>
+ <small>[% prettify_dt( p.confirmed, 1 ) %]</small>
[% IF p.is_fixed %]
<small>[% loc('(fixed)') %]</small>
[% ELSIF p.is_closed %]
diff --git a/templates/web/default/contact/index.html b/templates/web/default/contact/index.html
index cb87362ba..3997198bb 100644
--- a/templates/web/default/contact/index.html
+++ b/templates/web/default/contact/index.html
@@ -18,9 +18,9 @@
<blockquote>
<p>
[% IF update.anonymous %]
- [% tprintf( loc('Update below added anonymously at %s'), prettify_dt( update.confirmed_local ) ) %]
+ [% tprintf( loc('Update below added anonymously at %s'), prettify_dt( update.confirmed ) ) %]
[% ELSE %]
- [% tprintf( loc('Update below added by %s at %s'), update.name, prettify_dt( update.confirmed_local ) ) | html %]
+ [% tprintf( loc('Update below added by %s at %s'), update.name, prettify_dt( update.confirmed ) ) | html %]
[% END %]
</p>
@@ -42,9 +42,9 @@
<p>
[% IF problem.anonymous %]
- [% tprintf( loc('Reported anonymously at %s'), prettify_dt( problem.confirmed_local ) ) %]
+ [% tprintf( loc('Reported anonymously at %s'), prettify_dt( problem.confirmed ) ) %]
[% ELSE %]
- [% tprintf( loc('Reported by %s at %s'), problem.user.name, prettify_dt( problem.confirmed_local ) ) | html %]
+ [% tprintf( loc('Reported by %s at %s'), problem.user.name, prettify_dt( problem.confirmed ) ) | html %]
[% END %]
</p>
diff --git a/templates/web/default/index.html b/templates/web/default/index.html
index beaeefb20..6ae9db3e8 100644
--- a/templates/web/default/index.html
+++ b/templates/web/default/index.html
@@ -41,9 +41,11 @@
<h2>[% loc('Recently reported problems') %]</h2>
[% IF recent_photos.size %]
<p id="front_photos">
- [% FOREACH p IN recent_photos %]
+ [% FOREACH p IN recent_photos;
+ photo = p.get_photo_params;
+ %]
<a href="/report/[% p.id %]"><img border="0" height="100"
- src="/photo/[% p.id %].tn.jpeg" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
[% END %]
</p>
[% END %]
@@ -53,7 +55,7 @@
[% FOREACH p IN probs %]
<li>
<a href="/report/[% p.id %]">[% p.title | html %]</a>
- <small>[% prettify_dt( p.confirmed_local, 1 ) %]</small>
+ <small>[% prettify_dt( p.confirmed, 1 ) %]</small>
</li>
[% END %]
</ul>
diff --git a/templates/web/default/my/my.html b/templates/web/default/my/my.html
index cb9b0dd99..a6e4000df 100644
--- a/templates/web/default/my/my.html
+++ b/templates/web/default/my/my.html
@@ -53,7 +53,7 @@ END %]
<li>&ldquo;[% u.text | html %]&rdquo;
&ndash; <a href="[% c.uri_for( '/report', u.problem_id ) %]#update_[% u.id %]">[% u.problem.title | html %]</a>.
<em class="council_sent_info">
- [% tprintf( loc("Added %s"), prettify_dt( u.confirmed_local, 'date' ) ) %]
+ [% tprintf( loc("Added %s"), prettify_dt( u.confirmed, 'date' ) ) %]
</em>
</li>
[% "</ul>" IF loop.last %]
@@ -69,9 +69,9 @@ END %]
<li><a href="[% c.uri_for( '/report', p.id ) %]">[% p.title | html %]</a>
<em class="council_sent_info"> &ndash;
[% IF p.whensent %]
- [% tprintf( loc("Reported %s, to %s"), prettify_dt( p.confirmed_local, 'date' ), p.body(c) ) %]
+ [% tprintf( loc("Reported %s, to %s"), prettify_dt( p.confirmed, 'date' ), p.body(c) ) %]
[% ELSE %]
- [% tprintf( loc("Reported %s"), prettify_dt( p.confirmed_local, 'date' ) ) %]
+ [% tprintf( loc("Reported %s"), prettify_dt( p.confirmed, 'date' ) ) %]
[% END %]
</em>
</li>
diff --git a/templates/web/default/pagination.html b/templates/web/default/pagination.html
index f5a1192d1..63180b600 100644
--- a/templates/web/default/pagination.html
+++ b/templates/web/default/pagination.html
@@ -1,17 +1,19 @@
[% IF pager.last_page > 1 %]
- <p>
+[% IF NOT admin %]
+<section class="full-width">
+[% END %]
+ <p class="pagination">
[% IF pager.previous_page %]
- <a href="[% c.req.uri_with({ $param => pager.previous_page }) %]">&larr; Previous</a>
- [% ELSE %]
- &larr; Previous
+ <a class="prev" href="[% c.req.uri_with({ $param => pager.previous_page }) %][% '#' _ hash IF hash %]">[% loc('Previous') %]</a>
[% END %]
- |
- [% pager.first %] to [% pager.last %] of [% pager.total_entries %]
- |
+
+ [% tprintf( loc('%d to %d of %d'), pager.first, pager.last, pager.total_entries ) %]
+
[% IF pager.next_page %]
- <a href="[% c.req.uri_with({ $param => pager.next_page }) %]">Next &rarr;</a>
- [% ELSE %]
- Next &rarr;
+ <a class="next" href="[% c.req.uri_with({ $param => pager.next_page }) %][% '#' _ hash IF hash %]">[% loc('Next') %]</a>
[% END %]
</p>
+[% IF NOT admin %]
+</section>
+[% END %]
[% END %]
diff --git a/templates/web/default/report/banner.html b/templates/web/default/report/banner.html
index 52bfa6e67..bd7798d79 100644
--- a/templates/web/default/report/banner.html
+++ b/templates/web/default/report/banner.html
@@ -5,7 +5,7 @@
</p>
[% END %]
-[% IF problem.is_open AND date.now - problem.lastupdate_local.epoch > 8 * 7 * 24 * 60 * 60 %]
+[% IF problem.is_open AND date.now - problem.lastupdate.epoch > 8 * 7 * 24 * 60 * 60 %]
[% INCLUDE banner, id = 'unknown', text = loc('This problem is old and of unknown status.') %]
[% END %]
[% IF problem.is_fixed %]
diff --git a/templates/web/default/report/updates.html b/templates/web/default/report/updates.html
index b7adb014f..83f746d56 100644
--- a/templates/web/default/report/updates.html
+++ b/templates/web/default/report/updates.html
@@ -7,21 +7,21 @@
[% IF update.whenanswered %]
[%# A questionnaire update, currently saying report is still open %]
- [% tprintf( loc( 'Still open, via questionnaire, %s' ), prettify_dt( update.whenanswered_local ) ) %]
+ [% tprintf( loc( 'Still open, via questionnaire, %s' ), prettify_dt( update.whenanswered ) ) %]
[% RETURN %]
[% END %]
[% IF update.anonymous || update.name == '' %]
- [% tprintf( loc( 'Posted anonymously at %s' ), prettify_dt( update.confirmed_local ) ) -%]
+ [% tprintf( loc( 'Posted anonymously at %s' ), prettify_dt( update.confirmed ) ) -%]
[%- ELSIF update.user.from_body;
user_name = update.user.name | html;
body = update.user.body;
IF body == 'Bromley Council';
body = "$body <img src='/cobrands/bromley/favicon.png' alt=''>";
END %]
- [% tprintf( loc( 'Posted by %s (<strong>%s</strong>) at %s' ), user_name, body, prettify_dt( update.confirmed_local ) ) -%]
+ [% tprintf( loc( 'Posted by %s (<strong>%s</strong>) at %s' ), user_name, body, prettify_dt( update.confirmed ) ) -%]
[%- ELSE %]
- [% tprintf( loc( 'Posted by %s at %s' ), update.name, prettify_dt( update.confirmed_local ) ) | html -%]
+ [% tprintf( loc( 'Posted by %s at %s' ), update.name, prettify_dt( update.confirmed ) ) | html -%]
[%- END -%]
[%- update_state = '' %]
[%- IF update.mark_fixed %][% update_state = ", " _ loc( 'marked as fixed' ) %][% END %]
diff --git a/templates/web/fixmybarangay/alert/index.html b/templates/web/fixmybarangay/alert/index.html
index d9bb74ee9..8e2ce7518 100644
--- a/templates/web/fixmybarangay/alert/index.html
+++ b/templates/web/fixmybarangay/alert/index.html
@@ -30,9 +30,11 @@ FixMyBarangay has a RSS feeds and email alerts for local problems.
<div class="sticky-sidebar" id="alert_recent">
<aside>
<h2>[% loc('Some photos of recent reports') %]</h2>
- [% FOREACH p IN photos %]
+ [% FOREACH p IN photos;
+ photo = p.get_photo_params
+ %]
<a href="/report/[% p.id %]"><img border="0" height="100"
- src="/photo/[% p.id %].tn.jpeg" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
[% END %]
</aside>
</div>
diff --git a/templates/web/fixmystreet/contact/index.html b/templates/web/fixmystreet/contact/index.html
index 450b6e2ef..174fd1d7e 100644
--- a/templates/web/fixmystreet/contact/index.html
+++ b/templates/web/fixmystreet/contact/index.html
@@ -19,9 +19,9 @@
<blockquote>
<p>
[% IF update.anonymous %]
- [% tprintf( loc('Update below added anonymously at %s'), prettify_dt( update.confirmed_local ) ) %]
+ [% tprintf( loc('Update below added anonymously at %s'), prettify_dt( update.confirmed ) ) %]
[% ELSE %]
- [% tprintf( loc('Update below added by %s at %s'), update.name, prettify_dt( update.confirmed_local ) ) | html %]
+ [% tprintf( loc('Update below added by %s at %s'), update.name, prettify_dt( update.confirmed ) ) | html %]
[% END %]
</p>
@@ -43,9 +43,9 @@
<p>
[% IF problem.anonymous %]
- [% tprintf( loc('Reported anonymously at %s'), prettify_dt( problem.confirmed_local ) ) %]
+ [% tprintf( loc('Reported anonymously at %s'), prettify_dt( problem.confirmed ) ) %]
[% ELSE %]
- [% tprintf( loc('Reported by %s at %s'), problem.user.name, prettify_dt( problem.confirmed_local ) ) | html %]
+ [% tprintf( loc('Reported by %s at %s'), problem.user.name, prettify_dt( problem.confirmed ) ) | html %]
[% END %]
</p>
diff --git a/templates/web/fixmystreet/index.html b/templates/web/fixmystreet/index.html
index 5d7d31baa..f45509891 100644
--- a/templates/web/fixmystreet/index.html
+++ b/templates/web/fixmystreet/index.html
@@ -47,8 +47,7 @@ kinds of problems like missed bins use our
<section class="full-width">
<ul class="issue-list-a">
[% FOREACH problem IN recent_photos %]
- [% problem.photo = 1; # Definitely is
- INCLUDE 'report/_item.html', no_fixed = 1 %]
+ [% INCLUDE 'report/_item.html', no_fixed = 1 %]
[% END %]
</ul>
</section>
diff --git a/templates/web/fixmystreet/my/my.html b/templates/web/fixmystreet/my/my.html
index 3134c335f..12f68bd80 100644
--- a/templates/web/fixmystreet/my/my.html
+++ b/templates/web/fixmystreet/my/my.html
@@ -57,7 +57,7 @@ END %]
<li>&ldquo;[% u.text | html %]&rdquo;
&ndash; <a href="[% c.uri_for( '/report', u.problem_id ) %]#update_[% u.id %]">[% u.problem.title | html %]</a>.
<p><small class="council_sent_info">
- [% tprintf( loc("Added %s"), prettify_dt( u.confirmed_local, 'date' ) ) %]
+ [% tprintf( loc("Added %s"), prettify_dt( u.confirmed, 'date' ) ) %]
</small></p>
</li>
[% "</ul>" IF loop.last %]
diff --git a/templates/web/fixmystreet/pagination.html b/templates/web/fixmystreet/pagination.html
deleted file mode 100644
index 4f4d00a79..000000000
--- a/templates/web/fixmystreet/pagination.html
+++ /dev/null
@@ -1,15 +0,0 @@
-[% IF pager.last_page > 1 %]
-<section class="full-width">
- <p class="pagination">
- [% IF pager.previous_page %]
- <a class="prev" href="[% c.req.uri_with({ $param => pager.previous_page }) %]">Previous</a>
- [% END %]
-
- [% pager.first %] to [% pager.last %] of [% pager.total_entries %]
-
- [% IF pager.next_page %]
- <a class="next" href="[% c.req.uri_with({ $param => pager.next_page }) %]">Next</a>
- [% END %]
- </p>
-</section>
-[% END %]
diff --git a/templates/web/fixmystreet/report/_item.html b/templates/web/fixmystreet/report/_item.html
index 508b02614..852633f76 100644
--- a/templates/web/fixmystreet/report/_item.html
+++ b/templates/web/fixmystreet/report/_item.html
@@ -1,13 +1,15 @@
<li>
<a class="text" href="[% c.uri_for('/report', problem.id ) %]">
- [% IF problem.photo %]
- <img class="img" height="60" width="90" src="/photo/[% problem.id %].fp.jpeg" alt="">
+ [% IF problem.photo;
+ photo = problem.get_photo_params
+ %]
+ <img class="img" height="60" width="90" src="[% photo.url_fp %]" alt="">
[% END %]
<h4>[% problem.title | html %]</h4>
- <small>[% prettify_dt( problem.confirmed_local, 1 ) %]
+ <small>[% prettify_dt( problem.confirmed, 1 ) %]
[%- IF dist %], [% dist %]km[% END %]
[%- IF include_lastupdate AND problem.confirmed != problem.lastupdate AND problem.whensent != problem.lastupdate %],
- [% tprintf('last updated %s', prettify_dt( problem.lastupdate_local, 1 ) ) %]
+ [% tprintf(loc('last updated %s'), prettify_dt( problem.lastupdate, 1 ) ) %]
[%- END %]
[% IF include_lastupdate %]
[% IF problem.bodies_str_ids.size > 1 %] [% loc('(sent to both)') %]
diff --git a/templates/web/fixmystreet/report/banner.html b/templates/web/fixmystreet/report/banner.html
index ce4666a6a..83c780958 100644
--- a/templates/web/fixmystreet/report/banner.html
+++ b/templates/web/fixmystreet/report/banner.html
@@ -5,7 +5,7 @@
</div>
[% END %]
-[% IF c.cobrand.moniker != 'bromley' AND problem.bodies_str != '2482' AND problem.is_open AND date.now - problem.lastupdate_local.epoch > 8 * 7 * 24 * 60 * 60 %]
+[% IF c.cobrand.moniker != 'bromley' AND problem.bodies_str != '2482' AND problem.is_open AND date.now - problem.lastupdate.epoch > 8 * 7 * 24 * 60 * 60 %]
[% INCLUDE banner, id = 'unknown', text = loc('Unknown') %]
[% END %]
[% IF problem.is_fixed %]
diff --git a/templates/web/zurich/admin/header.html b/templates/web/zurich/admin/header.html
index 41cb520f5..be146f0e1 100644
--- a/templates/web/zurich/admin/header.html
+++ b/templates/web/zurich/admin/header.html
@@ -14,9 +14,20 @@
%]
<style type="text/css">
.adminhidden { color: #666666; }
+ .active { background-color: #ffffee; cursor: pointer; }
.error { color: red; }
.overdue { background-color: #ffcccc; }
select { width: auto; }
+ #fms_pan_zoom { top: 13em !important; }
</style>
+<script>
+$(function(){
+ $('.row-link').hover(function(){
+ $(this).toggleClass("active");
+ }).click(function(){
+ window.location = this.getElementsByTagName('a')[0];
+ }).find('td:last').hide();
+ $('th.edit').hide();
+});
+</script>
- <h1 style="clear:both;">[% title %]</h1>
diff --git a/templates/web/zurich/admin/index-dm.html b/templates/web/zurich/admin/index-dm.html
index a88100ee4..530e72c59 100644
--- a/templates/web/zurich/admin/index-dm.html
+++ b/templates/web/zurich/admin/index-dm.html
@@ -3,14 +3,15 @@
[% status_message %]
-<h2>[% loc('Submitted') %]</h2>
-[% INCLUDE list, problems = unconfirmed.all %]
+<h2 id="submitted">[% loc('Submitted') %]</h2>
+[% INCLUDE list, problems = unconfirmed.all, hash = 'submitted' %]
-<h2>[% loc('Planned') %]</h2>
-[% INCLUDE list, problems = approval.all %]
+<h2 id="planned">[% loc('Planned') %]</h2>
+[% INCLUDE list, problems = approval.all, hash = 'planned' %]
-<h2>[% loc('All reports') %]</h2>
-[% INCLUDE list, problems = other.all, include_subdiv = 1 %]
+<h2 id="alle">[% loc('All reports') %]</h2>
+[% INCLUDE list, problems = other.all, include_subdiv = 1, hash = 'alle' %]
+[% INCLUDE 'pagination.html', admin = 1, param = 'p', hash = 'alle' %]
[% INCLUDE 'admin/footer.html' %]
@@ -19,14 +20,13 @@
<tr>
<th>[% loc('ID') %]</th>
<th>[% loc('Description') %]</th>
- <th>[% loc('Category') %]</th>
- <th>[% loc('Submitted') %]</th>
- <th>[% loc('Updated') %]</th>
- <th>[% loc('Status') %]</th>
+ [% FOREACH col IN [ [ 'category', loc('Category') ], [ 'created', loc('Submitted') ], [ 'lastupdate', loc('Updated') ], [ 'state', loc('Status') ] ] %]
+ <th><a href="[% INCLUDE sort_link choice = col.0 %]#[% hash %]">[% col.1 %] [% INCLUDE sort_arrow choice = col.0 %]</a></th>
+ [% END %]
[% IF include_subdiv %]
<th>[% loc('Subdivision/Body') %]</th>
[% END %]
- <th>*</th>
+ <th class='edit'>*</th>
</tr>
<tr class="filter-row">
<td colspan="8"><input type="text" placeholder="[%= loc('Filter report list') %]" /></td>
diff --git a/templates/web/zurich/admin/index-sdm.html b/templates/web/zurich/admin/index-sdm.html
index 4e4009c16..76593ead0 100644
--- a/templates/web/zurich/admin/index-sdm.html
+++ b/templates/web/zurich/admin/index-sdm.html
@@ -1,14 +1,15 @@
[% PROCESS 'admin/header.html' title=loc('Summary') -%]
[% PROCESS 'admin/report_blocks.html' %]
-<h2>[% loc('New reports') %]</h2>
-[% INCLUDE list, problems = reports_new.all %]
+<h2 id="new">[% loc('New reports') %]</h2>
+[% INCLUDE list, problems = reports_new.all, hash = 'new' %]
-<h2>[% loc('Reports awaiting approval') %]</h2>
-[% INCLUDE list, problems = reports_unpublished.all, no_edit = 1 %]
+<h2 id="wait">[% loc('Reports awaiting approval') %]</h2>
+[% INCLUDE list, problems = reports_unpublished.all, no_edit = 1, hash = 'wait' %]
-<h2>[% loc('Reports published') %]</h2>
-[% INCLUDE list, problems = reports_published.all, no_edit = 1 %]
+<h2 id="alle">[% loc('Reports published') %]</h2>
+[% INCLUDE list, problems = reports_published.all, no_edit = 1, hash = 'alle' %]
+[% INCLUDE 'pagination.html', admin = 1, param = 'p', hash = 'alle' %]
[% INCLUDE 'admin/footer.html' %]
@@ -17,12 +18,11 @@
<tr>
<th>[% loc('ID') %]</th>
<th>[% loc('Description') %]</th>
- <th>[% loc('Category') %]</th>
- <th>[% loc('Submitted') %]</th>
- <th>[% loc('Updated') %]</th>
- <th>[% loc('Status') %]</th>
+ [% FOREACH col IN [ [ 'category', loc('Category') ], [ 'created', loc('Submitted') ], [ 'lastupdate', loc('Updated') ], [ 'state', loc('Status') ] ] %]
+ <th><a href="[% INCLUDE sort_link choice = col.0 %]#[% hash %]">[% col.1 %] [% INCLUDE sort_arrow choice = col.0 %]</a></th>
+ [% END %]
[% IF NOT no_edit %]
- <th>*</th>
+ <th class='edit'>*</th>
[% END %]
</tr>
<tr class="filter-row">
diff --git a/templates/web/zurich/admin/index.html b/templates/web/zurich/admin/index.html
index ab835b5a3..a51c7f6fe 100644
--- a/templates/web/zurich/admin/index.html
+++ b/templates/web/zurich/admin/index.html
@@ -6,12 +6,6 @@
<li>[% tprintf( loc('%d council contacts &ndash; %d confirmed, %d unconfirmed'), contacts.total, contacts.1, contacts.0) %]</li>
</ul>
-[% IF c.cobrand.admin_show_creation_graph -%]
- <p>
- <a href="[% c.config.BASE_URL %]/fms-live-creation.png">[% loc('Graph of problem creation by status over time') %]</a>
- </p>
-[% END -%]
-
<h2>[% loc('Problem breakdown by state') %]</h2>
<ul>
[% FOREACH state IN problems.keys.sort %]
diff --git a/templates/web/zurich/admin/list_updates.html b/templates/web/zurich/admin/list_updates.html
index 7a78d4c63..c475d839e 100644
--- a/templates/web/zurich/admin/list_updates.html
+++ b/templates/web/zurich/admin/list_updates.html
@@ -1,3 +1,4 @@
+[% IF updates.size %]
<h2>[% loc('Updates') %]</h2>
<table cellspacing="0" cellpadding="2" border="1">
@@ -14,3 +15,4 @@
</tr>
[% END -%]
</table>
+[% END %]
diff --git a/templates/web/zurich/admin/problem_row.html b/templates/web/zurich/admin/problem_row.html
index 617490232..8b1a30cb0 100644
--- a/templates/web/zurich/admin/problem_row.html
+++ b/templates/web/zurich/admin/problem_row.html
@@ -1,18 +1,19 @@
[%- FOR problem IN problems %]
[% SET p_body = problem.bodies.values.0 %]
- [% IF page == 'search' %]
- [% NEXT IF admin_type == 'sdm' AND p_body.id != body.id %]
- [% NEXT IF admin_type == 'dm' AND p_body.id != body.id AND p_body.parent.id != body.id %]
- [% END %]
<tr[%
- ' class="adminhidden"' IF problem.state == 'hidden';
- ' class="overdue"' IF c.cobrand.overdue( problem );
+ SET classes = [];
+ classes.push('adminhidden') IF problem.state == 'hidden';
+ classes.push('overdue') IF c.cobrand.overdue( problem );
+ classes.push('row-link') IF NOT no_edit;
+ ' class="' _ classes.join(' ') _ '"' IF classes.size;
%]>
- <td class="record-id">[%- IF problem.is_visible -%]
- <a href="[% c.uri_for_email( '/report', problem.id ) %]">[% problem.id %]</a>
- [%- ELSE %]
- [%- problem.id %]
- [%- END -%]</td>
+ <td class="record-id">
+ [% IF no_edit AND problem.is_visible %]
+ <a href="[% c.uri_for_email( '/report', problem.id ) %]">[% problem.id %]</a>
+ [% ELSE %]
+ [% problem.id %]
+ [% END %]
+ </td>
<td>[% PROCESS value_or_nbsp value=problem.title %]</td>
<td>[% PROCESS value_or_nbsp value=problem.category %]</td>
<td>[% PROCESS format_date this_date=problem.created %]</td>
diff --git a/templates/web/zurich/admin/report_edit-sdm.html b/templates/web/zurich/admin/report_edit-sdm.html
index faad3ec55..39d74881c 100644
--- a/templates/web/zurich/admin/report_edit-sdm.html
+++ b/templates/web/zurich/admin/report_edit-sdm.html
@@ -1,5 +1,13 @@
-[% PROCESS 'admin/header.html' title=tprintf(loc('Editing problem %d'), problem.id ) -%]
-[% PROCESS 'admin/report_blocks.html' %]
+[%
+ PROCESS "maps/zurich.html";
+ PROCESS 'admin/header.html'
+ title = tprintf(loc('Editing problem %d'), problem.id ),
+ bodyclass = 'mappage';
+ PROCESS 'admin/report_blocks.html'
+-%]
+
+[% map_html %]
+</div>
[% status_message %]
@@ -9,9 +17,9 @@
<p align="right"><input type="submit" name="send_back" value="[% loc('Not for my subdivision') %]"></p>
-<ul>
+<ul class="no-bullets">
<li><a href="[% c.uri_for_email( '/report', problem.id ) %]">[% loc('View report on site' )%]</a></li>
-<li>[% loc('Details:') %] [% problem.detail | html %]
+<li><span class="mock-label">[% loc('Details:') %]</span> [% problem.detail | html %]
[% IF problem.extra.original_detail %]
<br>[%
SET safe = problem.extra.original_detail | html;
@@ -19,26 +27,28 @@
%]
[% END %]
</li>
-<li>[% loc('Co-ordinates:') %] [% problem.local_coords.join(',') %]
+<li><span class="mock-label">[% loc('Co-ordinates:') %]</span> [% problem.local_coords.join(',') %]
+ <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]">
+ <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]">
([%
SET safe = problem.postcode | html;
tprintf( loc('originally entered: &ldquo;%s&rdquo;'), safe )
%],
[% IF problem.used_map %][% loc('used map') %][% ELSE %][% loc("didn't use map") %][% END %])</li>
-<li>[% loc('Category:') %] [% problem.category | html %] </li>
-<li>[% loc('Name:') %] [% problem.name | html %]
-<li>[% loc('Email:') %] [% problem.user.email | html %]
+<li><span class="mock-label">[% loc('Category:') %]</span> [% problem.category | html %] </li>
+<li><span class="mock-label">[% loc('Name:') %]</span> [% problem.name | html %]
+<li><span class="mock-label">[% loc('Email:') %]</span> [% problem.user.email | html %]
[% IF NOT problem.extra.email_confirmed %]<span class="error">[% loc('Unconfirmed') %]</span>[% END %]
-<li>[% loc('Phone:') %] [% IF problem.user.phone %][% problem.user.phone | html %][% ELSE %]<em>[% loc('None') %]</em>[% END %]</li>
-<li>[% loc('Created:') %] [% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</li>
+<li><span class="mock-label">[% loc('Phone:') %]</span> [% IF problem.user.phone %][% problem.user.phone | html %][% ELSE %]<em>[% loc('None') %]</em>[% END %]</li>
+<li><span class="mock-label">[% loc('Created:') %]</span> [% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</li>
[% IF problem.photo %]
[% photo = problem.get_photo_params %]
<li><img alt="" src="[% c.cobrand.base_url %][% photo.url %]"></li>
[% END %]
-<li>[% loc('State:') %] [% states.${problem.state} %]</li>
+<li><span class="mock-label">[% loc('State:') %]</span> [% states.${problem.state} %]</li>
<li><label for="internal_notes">[% loc('Internal notes:') %]</label>
<textarea name='internal_notes' id='internal_notes' cols=60 rows=5>[% problem.extra.internal_notes | html %]</textarea></li>
diff --git a/templates/web/zurich/admin/report_edit.html b/templates/web/zurich/admin/report_edit.html
index 7fdaeabff..059c4b5c0 100644
--- a/templates/web/zurich/admin/report_edit.html
+++ b/templates/web/zurich/admin/report_edit.html
@@ -15,11 +15,11 @@
<input type="hidden" name="token" value="[% token %]" >
<input type="hidden" name="submit" value="1" >
-<ul>
+<ul class="no-bullets">
<li><a href="[% c.uri_for_email( '/report', problem.id ) %]">[% loc('View report on site' )%]</a></li>
[% IF problem.state == 'fixed - council' OR problem.state == 'closed' %]
- <li>[% loc('Details:') %] [% problem.detail | html %]
+ <li><span class="mock-label">[% loc('Details:') %]</span> [% problem.detail | html %]
[% IF problem.extra.original_detail %]
<br>[%
SET detail_safe = problem.extra.original_detail | html;
@@ -40,26 +40,28 @@
</li>
[% END %]
-<li>[% loc('Co-ordinates:') %] [% problem.local_coords.join(',') %]
+<li><span class="mock-label">[% loc('Co-ordinates:') %]</span> [% problem.local_coords.join(',') %]
+ <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]">
+ <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]">
+
([%
SET safe = problem.postcode | html;
tprintf( loc('originally entered: &ldquo;%s&rdquo;'), safe )
%],
[% IF problem.used_map %][% loc('used map') %][% ELSE %][% loc("didn't use map") %][% END %])</li>
-<li>[% loc('Name:') %] [% problem.name | html %] <input type='hidden' name='name' id='name' value='[% problem.name | html %]'></li>
-<li>[% loc('Email:') %] [% problem.user.email | html %] <input type='hidden' id='email' name='email' value='[% problem.user.email | html %]'>
+<li><span class="mock-label">[% loc('Name:') %]</span> [% problem.name | html %] <input type='hidden' name='name' id='name' value='[% problem.name | html %]'></li>
+<li><span class="mock-label">[% loc('Email:') %]</span> [% problem.user.email | html %] <input type='hidden' id='email' name='email' value='[% problem.user.email | html %]'>
[% IF NOT problem.extra.email_confirmed %]<span class="error">[% loc('Unconfirmed') %]</span>[% END %]
</li>
-<li>[% loc('Phone:') %] [% IF problem.user.phone %][% problem.user.phone | html %][% ELSE %]<em>[% loc('None') %]</em>[% END %]</li>
-<li>[% loc('Created:') %] [% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</li>
+<li><span class="mock-label">[% loc('Phone:') %]</span> [% IF problem.user.phone %][% problem.user.phone | html %][% ELSE %]<em>[% loc('None') %]</em>[% END %]</li>
+<li><span class="mock-label">[% loc('Created:') %]</span> [% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</li>
[% IF problem.photo %]
[% photo = problem.get_photo_params %]
<li><img alt="" src="[% c.cobrand.base_url %][% photo.url %]">
<br>
-[% IF rotated %]Photo may be cached for a while.<br>[% END %]
<input type="submit" name="rotate_photo" value="[% loc('Rotate Left') %]">
<input type="submit" name="rotate_photo" value="[% loc('Rotate Right') %]">
<br>
@@ -71,7 +73,7 @@
<p><label for="internal_notes">[% loc('Internal notes:') %]</label>
<textarea name='internal_notes' id='internal_notes' cols=60 rows=5>[% problem.extra.internal_notes | html %]</textarea></p>
-<p>[% loc('State:') %] <select name="state" id="state">
+<p><span class="mock-label">[% loc('State:') %]</span> <select name="state" id="state">
<option value="">--</option>
[% FOREACH s IN [
['unconfirmed', loc('Submitted')]
@@ -92,7 +94,7 @@
[% IF problem.state == 'unconfirmed' OR problem.state == 'confirmed' %]
-<ul>
+<ul class="no-bullets">
<li class="assignation">
<label for="body_subdivision">[% loc('Assign to subdivision:') %]</label>
<select name="body_subdivision" id="body_subdivision">
@@ -163,6 +165,12 @@ $(function(){
</li>
</ul>
+[% ELSIF problem.state == 'fixed - council' %]
+
+<p><span class="mock-label">[% loc('Public response:') %]</span>
+[% problem.extra.public_response | html %]
+</p>
+
[% END %]
<p align="right">
diff --git a/templates/web/zurich/admin/reports.html b/templates/web/zurich/admin/reports.html
index f8c022630..b0bc733c4 100644
--- a/templates/web/zurich/admin/reports.html
+++ b/templates/web/zurich/admin/reports.html
@@ -5,23 +5,23 @@
<p><label for="search">[% loc('Search:') %]</label> <input type="text" name="search" size="30" id="search" value="[% searched | html %]">
</form>
-
-[% IF searched %]
+[% IF problems.size %]
<table cellspacing="0" cellpadding="2" border="1">
<tr>
<th>[% loc('ID') %]</th>
<th>[% loc('Description') %]</th>
- <th>[% loc('Category') %]</th>
- <th>[% loc('Submitted') %]</th>
- <th>[% loc('Updated') %]</th>
- <th>[% loc('Status') %]</th>
- <th>*</th>
+ [% FOREACH col IN [ [ 'category', loc('Category') ], [ 'created', loc('Submitted') ], [ 'lastupdate', loc('Updated') ], [ 'state', loc('Status') ] ] %]
+ <th><a href="[% INCLUDE sort_link choice = col.0 %]">[% col.1 %] [% INCLUDE sort_arrow choice = col.0 %]</a></th>
+ [% END %]
+ <th class='edit'>*</th>
</tr>
- [% INCLUDE 'admin/problem_row.html', page = 'search' %]
+ [% INCLUDE 'admin/problem_row.html' %]
</table>
-[% INCLUDE 'admin/list_updates.html' %]
+[% INCLUDE 'pagination.html', admin = 1, param = 'p' IF pager %]
[% END %]
+[% INCLUDE 'admin/list_updates.html' %]
+
[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/zurich/admin/stats.html b/templates/web/zurich/admin/stats.html
new file mode 100644
index 000000000..92521ff1d
--- /dev/null
+++ b/templates/web/zurich/admin/stats.html
@@ -0,0 +1,54 @@
+[% INCLUDE 'admin/header.html' title=loc('Stats') %]
+[% PROCESS 'admin/report_blocks.html' %]
+[% USE date %]
+
+<p style="float:right"><a href="[% c.uri_with( { export=1 } ) %]">[% loc('All Reports') %]</a></p>
+
+[% IF start_date AND end_date %]
+<p><strong>[% tprintf( loc( 'All reports between %s and %s' ), start_date.ymd, end_date.ymd ) | html %]</strong></p>
+[% END %]
+
+<form method="get" action="[% c.uri_for('stats') %]">
+<p><select name="ym">
+ <option value="">[% loc('All reports') %]</option>
+ [% FOR y IN [ 2013 .. date.format(date.now, '%Y') ];
+ SET max = 12;
+ max = date.format(date.now, '%m') IF y == date.format(date.now, '%Y');
+ FOR m IN [ 1 .. max ];
+ m = m | format('%02d');
+ SET v = m _ '.' _ y;
+ %]
+ <option[% ' selected' IF v == ym %]>[% v %]</option>
+ [% END %]
+ [% END %]
+</select>
+
+<input type="submit" value="[% loc('Go') %]">
+</form>
+
+<ul>
+<li>[% loc('Total') %]: [% reports_total || 0 %]
+<li>[% loc('Closed') %]: [% reports_solved || 0 %]
+<li>[% loc('Hidden') %]: [% reports_spam || 0 %]
+<li>Externe Adressen: [% reports_assigned || 0 %]
+<li>[% loc('Moderated by division within one working day') %]: [% reports_moderated || 0 %]
+<li>[% loc('Dealt with by subdivision within 5 working days') %]: [% reports_dealtwith || 0 %]
+<li>[% loc('Assign to different category:') %] [% reports_category_changed || 0 %]
+<li>[% loc('Photo') %]: [% pictures_taken || 0 %]
+<li>[% loc('Publish photo') %]: [% pictures_published || 0 %]
+<!-- <li>[% loc('Phone:') %] [% users_phone || 0 %] -->
+<li>[% loc('Confirmed') %]: [% email_confirmed || 0 %]
+<li>[% loc('Name:') %] [% name_provided || 0 %]
+</ul>
+
+<table>
+<tr><th>[% loc('Service:') %]</th><th>[% loc('Count') %]</th></tr>
+[% WHILE ( s = per_service.next ) %]<tr><td>[% s.service || 'Web' %]</td><td>[% s.get_column('c') %]</td></tr>[% END %]
+</table>
+
+<table>
+<tr><th>[% loc('Category') %]</th><th>[% loc('Count') %]</th></tr>
+[% WHILE ( c = per_category.next ) %]<tr><td>[% c.category %]</td><td>[% c.get_column('c') %]</td></tr>[% END %]
+</table>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/zurich/auth/general.html b/templates/web/zurich/auth/general.html
new file mode 100644
index 000000000..23af75dcf
--- /dev/null
+++ b/templates/web/zurich/auth/general.html
@@ -0,0 +1,71 @@
+[% INCLUDE 'header.html', title = loc('Sign in or create an account') %]
+
+[% IF email_error;
+
+ # other keys include fqdn, mxcheck if you'd like to write a custom error message
+
+ errors = {
+ missing => loc('Please enter your email'),
+ other => loc('Please check your email address is correct')
+ };
+
+ loc_email_error = errors.$email_error || errors.other;
+END %]
+
+<form action="[% c.uri_for() %]" method="post" name="general_auth_login" class="validate">
+ <fieldset>
+
+ <h1>[% loc('Sign in') %]</h1>
+
+ <input type="hidden" name="r" value="[% c.req.params.r | html %]">
+
+ <div id="form_sign_in_yes" class="form-box">
+
+ <label class="n" for="email">[% loc('Email') %]</label>
+ [% IF loc_email_error %]
+ <div class="form-error">[% loc_email_error %]</div>
+ [% ELSIF sign_in_error %]
+ <div class="form-error">[% loc('There was a problem with your email/password combination. If you cannot remember your password, or do not have one, please fill in the &lsquo;sign in by email&rsquo; section of the form.') %]</div>
+ [% END %]
+ <input type="email" class="required email" id="email" name="email" value="[% email | html %]" placeholder="[% loc('Your email address') %]">
+
+ <label for="password_sign_in">[% loc('Password (optional)') %]</label>
+ <div class="form-txt-submit-box">
+ <input type="password" class="required" 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>
+
+ <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>
+ </fieldset>
+</form>
+
+<form action="[% c.uri_for() %]" method="post" name="general_auth_register" class="validate">
+ <fieldset>
+ <input type="hidden" name="r" value="[% c.req.params.r | html %]">
+
+ <h1>[% loc('<strong>No</strong> let me sign in by email') %]</h1>
+ <div id="form_sign_in_no" class="form-box">
+
+ <label class="n" for="email2">[% loc('Email') %]</label>
+ [% IF loc_email_error %]
+ <div class="form-error">[% loc_email_error %]</div>
+ [% END %]
+ <input type="email" class="required email" id="email2" name="email" value="[% email | html %]" placeholder="[% loc('Your email address') %]">
+
+ <label for="name">[% loc('Name') %]</label>
+ <input type="text" class="required" name="name" value="" placeholder="[% loc('Your name') %]">
+
+ <label for="password_register">[% loc('Password (optional)') %]</label>
+ <div class="form-txt-submit-box">
+ <input type="password" class="required" name="password_register" id="password_register" value="" placeholder="[% loc('Enter a password') %]">
+ <input class="green-btn" type="submit" name="email_sign_in" value="Registieren">
+ </div>
+
+ </div>
+ </fieldset>
+</form>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/zurich/faq/faq-de-ch.html b/templates/web/zurich/faq/faq-de-ch.html
index a354810df..79b908227 100755
--- a/templates/web/zurich/faq/faq-de-ch.html
+++ b/templates/web/zurich/faq/faq-de-ch.html
@@ -1,190 +1,82 @@
-[% INCLUDE 'header.html', title => loc('Frequently Asked Questions'), bodyclass => 'twothirdswidthpage' %]
-
-<div class="sticky-sidebar">
- <aside>
- <ul class="plain-list">
- <li><a href="#faq">Frequently Asked Questions</a></li>
- <li><a href="#practical">Practical Questions</a></li>
- <li><a href="#organisation">Organisation Questions</a></li>
- <li><a href="/privacy">Privacy and cookies</a></li>
- </ul>
- </aside>
-</div>
-
-<h1><a name="faq"></a>Frequently Asked Questions</h1>
- <dl>
- <dt>What is FixMyStreet?</dt>
- <dd>FixMyStreet is a site to help people report, view,
-or discuss local problems they&rsquo;ve found to their local council by
-simply locating them on a map. It launched in early February
-2007.</dd>
- <dt>What sort of problems should I report with FixMyStreet?</dt>
- <dd>FixMyStreet is primarily for reporting things which are
-<strong>broken or dirty or damaged or dumped, and need fixing, cleaning
-or clearing</strong>, such as:
-
- <ul><li>Abandoned vehicles
- <li>Dog Fouling
- <li>Flyposting or graffiti
- <li>Flytipping or litter
- <li>Streetcleaning, such as broken glass in a cycle lane
- <li>Unlit lampposts
- <li>Potholes
- </ul>
- </dd>
-
- <dt>What isn&rsquo;t FixMyStreet for?</dt>
- <dd>FixMyStreet is not a way of getting in touch with [% c.cobrand.is_council ? 'the' : 'your' %] council for all
- issues &ndash; please use FixMyStreet only for problems such as the above. We
- often route problem reports via cleansing services or highways and so using
- FixMyStreet for other matters may result in a delay in your report getting
- to the right department. <strong>You will need to contact [% c.cobrand.is_council ? 'the' : 'your' %] council
- directly for problems such as</strong>:
-
- <ul><li>Anti-social behaviour
- <li>Any urgent or emergency problems
- <li>Noise pollution or barking dogs
- <li>Fires and smoke/smell pollution
- <li>Missing wheelie bins or recycling boxes or missed rubbish collections
- <li>Proposals for speed bumps/ CCTV/ pedestrian crossings/ new road layouts/ etc.
- <li>Complaining about your neighbours
- <li>Complaining about the council
- <li>Joy riding, drug taking, animal cruelty, or other criminal activity
- </ul>
- <p>Councils often have direct hotlines for these sorts of issues.</p>
- </dd>
-
- <dt>How do I use the site?</dt>
- <dd>After entering a postcode or location, you are presented
-with a map of that area. You can view problems already reported in that area,
-or report ones of your own simply by clicking on the map at the location of
-the problem.</dd>
- <dt>How are the problems solved?</dt>
- <dd>They are reported to the [% IF !c.cobrand.is_council %]relevant[% END %] council by email. The
-council can then resolve the problem the way they normally would.
-Alternatively, you can discuss the problem on the website with others, and
-then together lobby the council to fix it, or fix it directly yourselves.</dd>
- <dt>Is it free?</dt>
- <dd>The site is free to use, yes. FixMyStreet is run
-by a registered charity, though, so if you want to make a contribution, <a
-href="https://secure.mysociety.org/donate/">please do</a>.</dd>
-
- <dt>Can I use FixMyStreet on my mobile?</dt>
- <dd>
- <p>The FixMyStreet website should work on your mobile phone, adapting to
- the size of your screen automatically. We plan to release updated native
- apps in the near future.
- <ul>
- <li><em>iPhone:</em> Our basic app from 2008 is available for download
- on the App Store:
- <a href="http://itunes.apple.com/gb/app/fixmystreet/id297456545">FixMyStreet</a>,
- <li><em>Android:</em> A volunteer, Anna Powell-Smith, has written an app
- available from the
- <a href="https://market.android.com/details?id=com.android.fixmystreet">Android Market</a>.
- <li><em>Nokia:</em> A volunteer, Thomas Forth, has written an app available from the
- <a href="http://store.ovi.com/content/107557">Ovi Store</a>.
- </ul>
- </dd>
-
- </dl>
-
- <h2><a name="practical"></a>Practical Questions</h2>
- <dl>
- <dt>I&rsquo;m from a council, where do you send the reports?</dt>
- <dd>You can either leave a test report or <a href="/contact">contact us</a>
-to find out where reports go at the moment. Also <a href="/contact">contact us</a>
-to update the address or addresses we use.</dd>
- <dt>I&rsquo;m from a council, can we have FixMyStreet on our website?</dt>
- <dd>Yes you can! We offer branded, hosted versions of FixMyStreet for local council websites. <a href="http://www.mysociety.org/for-councils/fixmystreet/">Full details</a>.</dd>
- <dt>Do you remove silly or illegal content?</dt>
- <dd>FixMyStreet is not responsible for the content and accuracy
-of material submitted by its users. We reserve the right to edit or remove any
-problems or updates which we consider to be inappropriate upon being informed
-by a user of the site.</dd>
- <dt>Why does the site use kilometres for measurements?</dt>
- <dd>Thanks for asking politely &ndash; we never quite understand why some of the rudest
- emails we receive are on this topic. The British national
- grid reference system, devised by Ordnance Survey (the British national
- mapping agency) around the time of the second world war, uses eastings and
- northings measured in metres and kilometres; the maps we use are from
- Ordnance Survey and so this is what we use to display distances.
- There you have it: not everything British is in miles!</dd>
-
- <dt>Why can&rsquo;t I zoom out more on the reporting map?</dt>
- <dd>We want to keep FixMyStreet locally focused, so restrict the ability to
- move radically between areas. The map on Your Reports will let you see all
- the reports you&rsquo;ve made, wherever they are. If you&rsquo;re from the
- council then the emailed version of the problem report also contains the
- closest road and postcode to the pin on the map.</dd>
-
- <dt>This site is great – why aren&rsquo;t you better publicised?</dt>
- <dd>As a tiny charity we simply don&rsquo;t have a publicity budget, and we
- rely on word of mouth to advertise the site. We have a whole <a
- href="posters/">array of posters, flyers and badges</a> if you&rsquo;d like
- to publicise us on the web or in your local area, and why not write to your
- local paper to let them know about us?</dd> </dl>
-
- <h2><a name="organisation"></a>Organisation Questions</h2>
+[% INCLUDE 'header.html', title => loc('Hilfe'), bodyclass => 'fullwidthpage' %]
+
+<h1><a name="faq"></a>Hilfe</h1>
+
<dl>
- <dt>Who built FixMyStreet?</dt>
- <dd>This site was built by <a href="http://www.mysociety.org/">mySociety</a>,
- in conjunction with the <a href="http://www.youngfoundation.org.uk/">Young Foundation</a>.
-mySociety is the project of a registered charity which has grown out of the community of
-volunteers who built sites like <a href="http://www.theyworkforyou.com/">TheyWorkForYou.com</a>.
-mySociety&rsquo;s primary mission is to build Internet projects which give people simple, tangible
-benefits in the civic and community aspects of their lives. Our first project
-was <a href="http://www.writetothem.com/">WriteToThem</a>, where you can write to any of your
-elected representatives, for free. The charity is called UK Citizens Online Democracy and is charity number 1076346. mySociety
-can be contacted by email at <a href="mailto:hello&#64;mysociety.org">hello&#64;mysociety.org</a>,
-or by post at mySociety, 483 Green Lanes, London, N13 4BS, UK.</dd>
- <dt><img src="/i/moj.png" align="right" alt="Ministry of Justice" hspace="10">Who pays for it?</dt>
- <dd>FixMyStreet was originally paid for via the Department for
- Constitutional Affairs Innovations Fund. It is now funded by a variety of means, from commercial
- work to <a href="http://www.mysociety.org/donate/">donations</a>.</dd>
- <dt><a name="nfi"></a>Wasn&rsquo;t this site called Neighbourhood Fix-It?</dt>
- <dd>Yes, we changed the name mid June 2007. We decided
-Neighbourhood Fix-It was a bit of a mouthful, hard to spell, and hard to publicise (does the URL have a dash in it or not?). The domain FixMyStreet became available, and everyone liked the name.</dd>
- <dt>Do you need any help with the project?</dt>
- <dd>Yes, we can use help in all sorts of ways, technical or
-non-technical. Please see our <a
-href="http://www.mysociety.org/helpus/">Get Involved page</a>.</dd>
- <dt>I&rsquo;d like a site like this for my own location/ where&rsquo;s the "source code" to this site?</dt>
- <dd>
-The software behind this site is open source, and available
-to you mainly under the GNU Affero GPL software license. You can <a
-href="http://github.com/mysociety/fixmystreet">download the
-source code</a> and help us develop it.
-You&rsquo;re welcome to use it in your own projects, although you must also
-make available the source code to any such projects.
-<a href="http://www.fiksgatami.no/">Fiksgatami</a> is an example of our code
-being used in a Norwegian version of this site.
+
+<dt>Was ist «Züri wie neu»</dt>
+<dd>
+«Züri wie neu» ist eine Online-Plattform, über die die Einwohnerinnen und
+Einwohner der Stadt Zürich auf Mängel und Schäden der städtischen Infrastruktur
+hinweisen können. «Züri wie neu» wird von der Stadtverwaltung moderiert und
+transparent geführt. Die Meldungen werden den zuständigen Fachstellen
+zugewiesen und innert fünf Arbeitstagen abschliessend beantwortet. Fällt eine
+Meldung nicht in den Zuständigkeitsbereich der Stadtverwaltung, wird die
+Meldung anonymisiert der zuständigen dritten Stelle per E-Mail zugestellt.
+</dd>
+
+<dt>Welche Probleme kann ich über «Züri wie neu» melden?</dt>
+<dd>
+<p>Gemeldet werden können sämtliche Schäden an der Infrastruktur der Stadt Zürich.
+Dabei kann es sich um ein Loch im Strassenbelag, ein Graffiti am Stadthaus oder
+eine durch Vandalen beschädigte Parkbank handeln.
+
+<p>Es können Probleme zu folgenden Kategorien gemeldet werden:
+
+<ul>
+<li>Abfall / Sammelstellen</li>
+<li>Beleuchtung</li>
+<li>Graffiti</li>
+<li>Spielplatz / Sitzbank</li>
+<li>Strasse / Trottoir / Platz</li>
+<li>Tiere / Grünflächen</li>
+</ul>
+
+</dd>
+
+<dt>Was kann ich nicht über «Züri wie neu» melden?</dt>
+
+<dd>
+Mängel die nicht auf Stadtgebiet liegen.
+<br>Melden Sie «Züri wie neu» KEINE Notfälle. Die Notrufnummern lauten:
+<br>Medizinisch - 144 Polizei - 117 Feuer - 118 Allgemein - 112
</dd>
-<dt>I&rsquo;d prefer code in a different language?</dt>
+
+<dt>Wie verwende ich die Webseite?</dt>
<dd>
-VisibleGovernment.ca wrote their own code for
-<a href="http://www.fixmystreet.ca/">http://www.fixmystreet.ca/</a>, which is
-written in GeoDjango and available under an MIT licence at <a
-href="http://github.com/visiblegovernment/django-fixmystreet/tree/master">github</a>.
-Or <a href="http://www.fixmystreet.org.nz/">FixMyStreet.org.nz</a> is written in
-Drupal.
+<p>
+Geben Sie zuerst eine Adresse an oder lassen sie ihren Standort automatisch
+über den entsprechenden Link lokalisieren. Mittels Mausklick in die danach
+angezeigte Karte können Sie den exakten Ort des Mangels angeben. Als letzten
+Schritt füllen sie die Felder des Formulars aus und schicken die Meldung ab.
</p>
+<p>
+Weiter können Sie bestehende Meldungen sowie auch die Rückmeldungen der
+Verwaltung betrachten.
+</p>
+</dd>
+
+<dt>Wie werden die Probleme gelöst?</dt>
+<dd>
+Die Meldungen werden innerhalb von fünf Arbeitstagen von den dafür zuständigen
+Fachstellen bearbeitet und mit einer entsprechenden Rückmeldung versehen.
</dd>
- <dt>People build things, not organisations. Who <em>actually</em> built it?</dt>
- <dd>Matthew Somerville and Francis Irving wrote the site,
-Chris Lightfoot wrote the tileserver and map cutter, Richard Pope created
-our pins, Deborah Kerr keeps things up-to-date and does user support,
-Ayesha Garrett designed our posters, and Tom Steinberg managed it all.
-
-Thanks also to
-<a href="http://www.ordnancesurvey.co.uk">Ordnance Survey</a> (for the maps,
-UK postcodes, and UK addresses &ndash; data &copy; Crown copyright, all
-rights reserved, Ministry of Justice 100037819&nbsp;2008),
-Yahoo! for their BSD-licensed JavaScript libraries, the entire free software
-community (this particular project was brought to you by Perl, PostgreSQL,
-and the number 161.290) and <a
-href="http://www.bytemark.co.uk/">Bytemark</a> (who kindly host all
-our servers).
-
-Let us know if we&rsquo;ve missed anyone.</dd>
- </dl>
+
+<dt>Kann ich «Züri wie neu» auf meinem Smartphone nutzen?</dt>
+<dd>
+Ja, sowohl über die für mobile Geräte optimierte Webseite, als auch über die
+iOS- und Android-App.
+</dd>
+
+<dt>Kann ich auch Probleme ausserhalb von Zürich melden?</dt>
+<dd>Nein.</dd>
+
+<dt>Werden meine E-Mail-Adresse, mein Name und meine Telefonnummer vertraulich behandelt?</dt>
+<dd>
+Die Kontaktinformationen werden nur stadtintern für Rückfragen verwendet. Sie
+werden weder im Internet publiziert noch an Dritte weitergegeben.
+</dd>
+
+</dl>
+
[% INCLUDE 'footer.html' pagefooter = 'yes' %]
diff --git a/templates/web/zurich/footer.html b/templates/web/zurich/footer.html
index a570a66a3..ece8763f0 100644
--- a/templates/web/zurich/footer.html
+++ b/templates/web/zurich/footer.html
@@ -9,18 +9,17 @@
[% IF c.user_exists %]
<p>
[% tprintf(loc('Hi %s'), c.user.name || c.user.email) %]
- </p><p><a href="/auth/sign_out">[% loc('sign out') %]</a>
+ </p><p><a href="/admin">[% loc('Summary') %]</a> | <a href="/auth/sign_out">[% loc('sign out') %]</a>
</p>
- [% ELSE %]
+ [% END %]
<ul id="main-menu" class="mob-only">
- <li><[% IF c.req.uri.path == '/' %]span[% ELSE %]a href="/"[% END %]
- >[% loc("Report a problem") %]</[% c.req.uri.path == '/' ? 'span' : 'a' %]></li>[%
+ <li><[% IF c.req.uri.path == '/' %]a onclick="$('html, body').animate({scrollTop:0}, 500); return false;" href="#site-header"[% ELSE %]a href="/"[% END %]
+ >[% loc("Report a problem") %]</[% c.req.uri.path == '/' ? 'a' : 'a' %]></li>[%
%]<li><[% IF c.req.uri.path == '/reports' %]span[% ELSE %]a href="/reports"[% END
%]>[% loc("All reports") %]</[% c.req.uri.path == '/reports' ? 'span' : 'a' %]></li>[%
%]<li><[% IF c.req.uri.path == '/faq' %]span[% ELSE %]a href="/faq"[% END
%]>[% loc("Help") %]</[% c.req.uri.path == '/faq' ? 'span' : 'a' %]></li>
</ul>
- [% END %]
</div>
</div>
</div>
@@ -29,12 +28,14 @@
<!-- [% INCLUDE 'debug_footer.html' %] -->
</div> <!-- .wrapper -->
- <div id="zurich-footer" class="desk-only">
- &copy; 2012 Stadt Z&uuml;rich
+ <div id="zurich-footer-wrapper" class="desk-only">
+ <div id="zurich-footer">
+ &copy; 2013 Stadt Z&uuml;rich
<span class="hidden">|</span> <a href="http://www.stadt-zuerich.ch/content/portal/de/index/footer/rechtliche_hinweise.html">Rechtliche Hinweise</a>
<span class="hidden">|</span> <a href="http://www.stadt-zuerich.ch/content/portal/de/index/footer/impressum.html">Impressum</a>
<span class="hidden">|</span> <a href="http://www.stadt-zuerich.ch/content/portal/de/index/footer/barrierefreiheit.html">Barrierefreiheit</a>
</div>
+ </div>
</body>
</html>
diff --git a/templates/web/zurich/header.html b/templates/web/zurich/header.html
index 8c8e49775..7d18459b8 100644
--- a/templates/web/zurich/header.html
+++ b/templates/web/zurich/header.html
@@ -24,7 +24,7 @@
<script src="[% start %][% version('/js/modernizr.custom.js') %]" charset="utf-8"></script>
<script src="[% start %][% version('/cobrands/fixmystreet/position_map.js') %]" charset="utf-8"></script>
- [% INCLUDE 'common_header_tags.html', js_override = '/cobrands/fixmystreet/fixmystreet.js', site_title = 'FixMyZurich' %]
+ [% INCLUDE 'common_header_tags.html', js_override = '/cobrands/fixmystreet/fixmystreet.js', site_title = 'Züri wie neu' %]
[% extra_js %]
<!-- CDN for now FIXME --><script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js" charset="utf-8"></script>
@@ -38,7 +38,8 @@
<div class="table-cell">
<header id="site-header" role="banner">
<div class="container">
- <a href="http://www.stadt-zuerich.ch/" id="site-logo">FixMyZurich</a>
+ <a href="/" id="site-logo-text">Züri wie neu</a>
+ <a href="http://www.stadt-zuerich.ch/" id="site-logo">Stadt Zürich</a>
<a href="#main-nav" id="nav-link">Main Navigation</a>
</div>
</header>
@@ -67,6 +68,9 @@
<li [% IF pagename == 'users' OR pagename == 'user_edit' %]class="current"[% END %]>
<a href="/admin/users">[% loc('Users') %]</a>
</li>
+ <li [% IF pagename == 'stats' %]class="current"[% END %]>
+ <a href="/admin/stats">[% loc('Stats') %]</a>
+ </li>
[% END %]
<li class="search-box">
<form method="get" action="[% c.uri_for('reports') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
diff --git a/templates/web/zurich/report/_item.html b/templates/web/zurich/report/_item.html
index 41164cdd1..7adb7cdd4 100644
--- a/templates/web/zurich/report/_item.html
+++ b/templates/web/zurich/report/_item.html
@@ -1,17 +1,19 @@
<li>
<a class="text" href="[% c.uri_for('/report', problem.id ) %]">
- [% IF problem.state != 'unconfirmed' AND problem.photo AND problem.extra.publish_photo %]
- <img class="img" height="60" width="90" src="/photo/[% problem.id %].fp.jpeg" alt="">
+ [% IF problem.state != 'unconfirmed' AND problem.photo AND problem.extra.publish_photo;
+ photo = problem.get_photo_params
+ %]
+ <img class="img" height="60" width="90" src="[% photo.url_fp %]" alt="">
[% END %]
[% IF problem.state != 'unconfirmed' %]
<h4>[% problem.title | html %]</h4>
[% ELSE %]
<h4><em>[% loc('Awaiting moderation') %]</em></h4>
[% END %]
- <small>[% prettify_dt( problem.created_local, 'zurich' ) %]
+ <small>[% prettify_dt( problem.created, 'zurich' ) %]
[%- IF dist %], [% dist %]km[% END %]
[%- IF include_lastupdate AND problem.created != problem.lastupdate AND problem.whensent != problem.lastupdate %],
- [% tprintf('last updated %s', prettify_dt( problem.lastupdate_local, 'zurich' ) ) %]
+ [% tprintf(loc('last updated %s'), prettify_dt( problem.lastupdate, 'zurich' ) ) %]
[%- END %]
[% IF NOT no_fixed AND problem.is_fixed %]
[% loc('(fixed)') %]
diff --git a/templates/web/zurich/report/_main.html b/templates/web/zurich/report/_main.html
index e6c310873..c5fbabf1c 100644
--- a/templates/web/zurich/report/_main.html
+++ b/templates/web/zurich/report/_main.html
@@ -1,7 +1,7 @@
<div class="problem-header cf">
<h1>[% tprintf( loc('Reported in the %s category'), problem.category ) %]</h1>
<p class="sub">
- [% prettify_dt( problem.created_local, 'zurich' ) %]
+ [% prettify_dt( problem.created, 'zurich' ) %]
[%- IF !problem.used_map %]<br>[% loc('there is no pin shown as the user did not use the map') %][% END %]
</p>
diff --git a/templates/web/zurich/report/updates.html b/templates/web/zurich/report/updates.html
index 69c8af99f..786ecd582 100644
--- a/templates/web/zurich/report/updates.html
+++ b/templates/web/zurich/report/updates.html
@@ -4,7 +4,7 @@
<li>
<div class="update-wrap">
<div class="update-text">
- <p class="meta-2">[% prettify_dt( problem.lastupdate_local, 'zurich' ) %]</p>
+ <p class="meta-2">[% prettify_dt( problem.lastupdate, 'zurich' ) %]</p>
[% IF problem.state == 'fixed - council' %]
[% add_links( problem.extra.public_response ) | html_para %]
[% ELSIF problem.state == 'closed' AND problem.external_body %]
diff --git a/templates/web/zurich/tracking_code.html b/templates/web/zurich/tracking_code.html
new file mode 100644
index 000000000..f94fbdcd5
--- /dev/null
+++ b/templates/web/zurich/tracking_code.html
@@ -0,0 +1,18 @@
+[% IF c.config.BASE_URL == "http://zurich.fixmystreet.staging.mysociety.org" %]
+<script type="text/javascript">
+
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-38427437-1']);
+ _gaq.push (['_gat._anonymizeIp']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+
+</script>
+[% ELSE %]
+<!-- Tracking code not inserted as "[% c.config.BASE_URL %]" not "http://www.fixmystreet.com" -->
+[% END %]
diff --git a/web/cobrands/fixmystreet/_base.scss b/web/cobrands/fixmystreet/_base.scss
index d72910450..724185be9 100644
--- a/web/cobrands/fixmystreet/_base.scss
+++ b/web/cobrands/fixmystreet/_base.scss
@@ -258,7 +258,6 @@ fieldset {
input[type=text],
input[type=password],
input[type=email],
-input[type=file],
textarea {
@include box-sizing(border-box);
width: 100%;
@@ -269,7 +268,6 @@ textarea {
input[type=text],
input[type=password],
input[type=email],
- input[type=file],
textarea {
max-width: 95%;
}
@@ -295,17 +293,13 @@ textarea {
input[type=text],
input[type=password],
-input[type=email],
-input[type=file] {
+input[type=email] {
border: 0.125em solid #888888;
@include border-radius(0.25em);
display: block;
font-size: 1em;
line-height: 1em;
}
-input[type=file] {
- margin-bottom:1em;
-}
label{
display: block;
@@ -1020,7 +1014,7 @@ a:hover.button-left {
// Left and right so that zoom can be left, pan right.
#fms_pan_zoom {
right: 0.5em !important;
- top: 0.5em !important;
+ top: 2.75em !important;
left: 0.5em !important;
}
// The left and right of the above causes the navigation to move off-screen left in IE6.
@@ -1409,9 +1403,7 @@ table.nicetable {
background: $primary;
padding-left:0.5em;
padding-right:0.5em;
- color:#1a1a1a;
&:hover {
- color:#1a1a1a;
text-decoration:none;
background:$primary/1.1;
}
diff --git a/web/cobrands/fixmystreet/images/spinner-white.gif b/web/cobrands/fixmystreet/images/spinner-white.gif
new file mode 100644
index 000000000..7db88b06b
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/spinner-white.gif
Binary files differ
diff --git a/web/cobrands/zurich/_zurich.scss b/web/cobrands/zurich/_zurich.scss
index b71670a92..cfc89e88e 100644
--- a/web/cobrands/zurich/_zurich.scss
+++ b/web/cobrands/zurich/_zurich.scss
@@ -8,9 +8,14 @@ a:hover {
text-decoration: underline;
}
+// mySociety addition for box shadow on front page with static image
+body.frontpage #zurich-footer-wrapper {
+ padding: 1px 0;
+ @include box-shadow(0 0 6px 1px #000);
+}
+
#zurich-footer {
- margin-top: 2em; // mySociety
- margin-left: 12px; // mySociety
+ margin: 2em auto; // mySociety
font-size: 67.5%;
line-height: 1.5em;
clear: both;
diff --git a/web/cobrands/zurich/base.scss b/web/cobrands/zurich/base.scss
index 8111f2726..c3246a1b1 100644
--- a/web/cobrands/zurich/base.scss
+++ b/web/cobrands/zurich/base.scss
@@ -51,7 +51,7 @@
#site-logo {
background: url(logo_portal.jpg) 0px -24px no-repeat;
width: 200px;
- height:44px;
+ height: 48px;
left:0;
top:4px;
}
@@ -66,6 +66,22 @@
background-color: $mobile_header_blue;
}
+// fix here:
+// a percentage width on input#pc breaks iPhone landscape/portrait switching
+// and the other changes make this fix pretty
+
+#front-main #postcodeForm div {
+ background: inherit;
+ border-color:transparent;
+ input#pc {
+ max-width: 15em;
+ background-color: #fff;
+ }
+ input#sub {
+ width: 3em;
+ }
+}
+
// No grey background or other bits
// The amount of resetting here shows this needs refactoring, so that it is FMS making the changes
// Also look into why full-width pulls things out, but then it is its children
@@ -106,3 +122,10 @@ h4.static-with-rule {
padding-left: 0.8em;
padding-right: 0.8em;
}
+
+#fms_pan_zoom_panup,
+#fms_pan_zoom_pandown,
+#fms_pan_zoom_panleft,
+#fms_pan_zoom_panright {
+ display: none;
+}
diff --git a/web/cobrands/zurich/layout.scss b/web/cobrands/zurich/layout.scss
index 3a2d8ddb0..46ea45856 100644
--- a/web/cobrands/zurich/layout.scss
+++ b/web/cobrands/zurich/layout.scss
@@ -19,12 +19,12 @@ body {
border: none;
}
}
-// Except on map pages
-body.mappage .content {
+// Except on map pages (which includes the front page)
+body.mappage .content, body.frontpage .content {
@include box-shadow(0 0 6px 1px #000);
}
.ie6, .ie7, .ie8 {
- body.mappage .content {
+ body.mappage .content, body.frontpage .content {
border: 1px solid #666;
}
}
@@ -45,20 +45,53 @@ body.mappage.admin .nav-wrapper-2 {
body.frontpage #site-logo, #site-logo {
width: 415px;
- height: 16px;
+ height: 83px;
background: url(logo_portal.jpg) top left no-repeat;
top: 0;
- text-indent: 0;
- padding-left: 10px;
+ left: auto; // base set this to 0
+}
+
+// Static map on front page
+body.frontpage {
+ .table-cell {
+ background-position: 50% 117px;
+ background-repeat: no-repeat;
+ background-image: url(mapbg-1024.jpg);
+ @media all and (min-width: 1025px) {
+ background-image: url(mapbg-1600.jpg);
+ }
+ .content {
+ margin: 2em auto; // Spacing around front content on top of static map
+ }
+ }
+
+ #site-header {
+ height: 117px;
+ background-color: #fff;
+ @include box-shadow(0 0 6px 1px #000);
+ }
+}
+
+#site-logo-text {
+ position: absolute;
+ top: 0;
+ z-index: 3;
padding-top: 83px;
+ padding-left: 10px;
color: #585858;
font-size: 85%;
- left: auto; // base set this to 0
+}
+body.mappage #site-logo-text {
+ position: fixed;
}
.nav-wrapper {
.nav-wrapper-2 {
- border-top: solid 18px white;
+ border-top: none;
+ }
+ .nav-wrapper-3 {
+ height: 99px;
+ padding-top: 18px;
}
}
@@ -109,9 +142,14 @@ body.mappage {
background-color: inherit;
color: inherit;
margin: 0 0 2em 0;
+ #postcodeForm div {
+ border-color: $dark_blue;
+ input#pc {
+ max-width: none;
+ }
+ }
}
-/* TODO Change the main-nav to be what is wanted */
#main-nav {
ul#main-menu {
li {
@@ -160,6 +198,9 @@ body.mappage {
}
body.mappage {
+ #main-nav {
+ width: auto;
+ }
#main-nav ul#main-menu li a,
#main-nav ul#main-menu li span {
padding: 0.75em;
@@ -191,6 +232,10 @@ body.twothirdswidthpage {
background: $col_fixed_label;
@include background(linear-gradient(#769643, $col_fixed_label 4px));
}
+ &#closed {
+ padding-top: 2em;
+ background-image: none;
+ }
}
}
.ie6 .banner p {
@@ -200,7 +245,13 @@ body.twothirdswidthpage {
}
#fms_pan_zoom {
- top: 7.75em !important;
+ top: 9em !important;
+}
+#fms_pan_zoom_zoomin {
+ top: 0 !important;
+}
+#fms_pan_zoom_zoomout {
+ top: 44px !important;
}
// Admin specific changes
@@ -212,12 +263,24 @@ body.fullwidthpage.admin .content {
body.mappage.admin .content {
margin-top: 6em;
margin-left: 0.5em;
-
}
.admin {
.content {
margin: 2em 0 1em;
padding: 0 0 0 0;
+ ul.no-bullets {
+ margin-left: 0;
+ > li {
+ list-style: none;
+ }
+ }
+ li.assignation {
+ list-style: none;
+ }
+ .mock-label {
+ font-weight: bold;
+ padding-right: 0.333em;
+ }
}
#zurich-footer {
@@ -228,7 +291,8 @@ body.mappage.admin .content {
width: 100%;
font-size: 0.9em;
border: 1px solid $table_border_color;
- border-collapse:collapse;
+ border-collapse: collapse;
+ margin-bottom: 1em;
th, td {
padding: 0.666em 0.5em;
border: 1px solid $table_border_color;
@@ -239,6 +303,9 @@ body.mappage.admin .content {
border-bottom: 2px solid $table_heading_underline_col;
border-left: 1px solid $table_heading_border_col;
border-right: 1px solid $table_heading_border_col;
+ a:link, a:visited {
+ color: white;
+ }
}
td.record-id {
text-align: center;
diff --git a/web/cobrands/zurich/mapbg-1024.jpg b/web/cobrands/zurich/mapbg-1024.jpg
new file mode 100644
index 000000000..9adb82b98
--- /dev/null
+++ b/web/cobrands/zurich/mapbg-1024.jpg
Binary files differ
diff --git a/web/cobrands/zurich/mapbg-1600.jpg b/web/cobrands/zurich/mapbg-1600.jpg
new file mode 100644
index 000000000..9321bd612
--- /dev/null
+++ b/web/cobrands/zurich/mapbg-1600.jpg
Binary files differ
diff --git a/web/i/pin-green-big.png b/web/i/pin-green-big.png
new file mode 100644
index 000000000..16d73230a
--- /dev/null
+++ b/web/i/pin-green-big.png
Binary files differ
diff --git a/web/i/pin-red-big.png b/web/i/pin-red-big.png
new file mode 100644
index 000000000..2d970b9e2
--- /dev/null
+++ b/web/i/pin-red-big.png
Binary files differ
diff --git a/web/js/fixmystreet.js b/web/js/fixmystreet.js
index e25c2a571..838351e8b 100644
--- a/web/js/fixmystreet.js
+++ b/web/js/fixmystreet.js
@@ -52,7 +52,8 @@ $(function(){
var form_submitted = 0;
var submitted = false;
- $("form.validate").validate({
+ $("form.validate").each(function(){
+ $(this).validate({
rules: validation_rules,
messages: translation_strings,
onkeyup: false,
@@ -85,6 +86,7 @@ $(function(){
submitted = false;
},
invalidHandler: function(form, validator) { submitted = true; }
+ });
});
$('input[type=submit]').click( function(e) { form_submitted = 1; } );
@@ -142,7 +144,8 @@ $(function(){
if($('.mobile').length){
$link.append(' <img src="/cobrands/fixmystreet/images/spinner-black.gif" alt="" align="bottom">');
}else{
- $link.append(' <img src="/cobrands/fixmystreet/images/spinner-yellow.gif" alt="" align="bottom">');
+ var spincolor = $('<span>').css("color","white").css("color") === $('#front-main').css("background-color")? 'white' : 'yellow';
+ $link.append(' <img src="/cobrands/fixmystreet/images/spinner-' + spincolor + '.gif" alt="" align="bottom">');
}
geo_position_js.getCurrentPosition(function(pos) {
$link.find('img').remove();
diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js
index 88dc6d69e..e28a4d982 100644
--- a/web/js/map-OpenLayers.js
+++ b/web/js/map-OpenLayers.js
@@ -418,7 +418,19 @@ OpenLayers.Control.PermalinkFMS = OpenLayers.Class(OpenLayers.Control.Permalink,
href = href.substring( 0, href.indexOf(separator) );
}
- href += separator + OpenLayers.Util.getParameterString(this.createParams(null, this.map.getZoom()+fixmystreet.zoomOffset));
+ var center = this.map.getCenter();
+ if ( center && fixmystreet.state_map && fixmystreet.state_map == 'full' ) {
+ // Translate the permalink co-ords so that 'centre' is accurate
+ var $content = $('.content'), mb = $('#map_box'),
+ q = ( $content.offset().left - mb.offset().left + $content.width() ) / 2;
+ if (q < 0) { q = 0; }
+ var p = this.map.getViewPortPxFromLonLat(center);
+ p.x += q;
+ p.y += 25;
+ center = this.map.getLonLatFromViewPortPx(p);
+ }
+
+ href += separator + OpenLayers.Util.getParameterString(this.createParams(center, this.map.getZoom()+fixmystreet.zoomOffset));
// Could use mlat/mlon here as well if we are on a page with a marker
if (this.anchor && !this.element) {
window.location.href = href;
diff --git a/web/js/map-wmts-zurich.js b/web/js/map-wmts-zurich.js
index 682c62f39..9fed68b8a 100644
--- a/web/js/map-wmts-zurich.js
+++ b/web/js/map-wmts-zurich.js
@@ -2,6 +2,34 @@
* Maps for FMZ using Zurich council's WMTS tile server
*/
+function fixmystreet_zurich_admin_drag() {
+ var admin_drag = new OpenLayers.Control.DragFeature( fixmystreet.markers, {
+ onComplete: function(feature, e) {
+ var lonlat = feature.geometry.clone();
+ lonlat.transform(
+ fixmystreet.map.getProjectionObject(),
+ new OpenLayers.Projection("EPSG:4326")
+ );
+ if (window.confirm( 'Richtiger Ort?' ) ) {
+ // Store new co-ordinates
+ document.getElementById('fixmystreet.latitude').value = lonlat.y;
+ document.getElementById('fixmystreet.longitude').value = lonlat.x;
+ } else {
+ // Put it back
+ var lat = document.getElementById('fixmystreet.latitude').value;
+ var lon = document.getElementById('fixmystreet.longitude').value;
+ lonlat = new OpenLayers.LonLat(lon, lat).transform(
+ new OpenLayers.Projection("EPSG:4326"),
+ fixmystreet.map.getProjectionObject()
+ );
+ fixmystreet.markers.features[0].move(lonlat);
+ }
+ }
+ } );
+ fixmystreet.map.addControl( admin_drag );
+ admin_drag.activate();
+}
+
$(function(){
$('#map_layer_toggle').toggle(function(){
$(this).text('Luftbild');
@@ -10,6 +38,15 @@ $(function(){
$(this).text('Stadtplan');
fixmystreet.map.setBaseLayer(fixmystreet.map.layers[0]);
});
+
+ /* Admin dragging of pin */
+ if (fixmystreet.page == 'admin') {
+ if ($.browser.msie) {
+ $(window).load(fixmystreet_zurich_admin_drag);
+ } else {
+ fixmystreet_zurich_admin_drag();
+ }
+ }
});
/*
@@ -34,6 +71,11 @@ $(function(){
fixmystreet.controls.push( new OpenLayers.Control.PanZoomFMS({id: 'fms_pan_zoom' }) );
}
+ /* Linking back to around from report page, keeping track of map moves */
+ if ( fixmystreet.page == 'report' ) {
+ fixmystreet.controls.push( new OpenLayers.Control.PermalinkFMS('key-tool-problems-nearby', '/around') );
+ }
+
fixmystreet.map_type = OpenLayers.Layer.WMTS;
// Set DPI - default is 72