aboutsummaryrefslogtreecommitdiffstats
path: root/templates/web/base
diff options
context:
space:
mode:
authorMatthew Somerville <matthew@mysociety.org>2014-07-07 16:59:23 +0100
committerMatthew Somerville <matthew@mysociety.org>2014-07-08 17:59:17 +0100
commitba8d2c4ba6f6c0216d618e77d368b640a2b92d1e (patch)
tree8b9e1a960f91c006606b5e0767a84a400dfc2fb0 /templates/web/base
parent8f2c5942e3aa5d3b85e76b7353ab7ada87f97fc6 (diff)
Rename 'default' web directory to 'base'.
This should reduce confusion with the Default cobrand and override order.
Diffstat (limited to 'templates/web/base')
-rw-r--r--templates/web/base/admin/bodies.html75
-rw-r--r--templates/web/base/admin/body-form.html236
-rw-r--r--templates/web/base/admin/body.html192
-rw-r--r--templates/web/base/admin/body_edit.html103
-rw-r--r--templates/web/base/admin/config_page.html146
-rw-r--r--templates/web/base/admin/council_contacts.txt4
-rw-r--r--templates/web/base/admin/edit-league.html21
-rw-r--r--templates/web/base/admin/flagged.html62
-rw-r--r--templates/web/base/admin/footer.html1
-rw-r--r--templates/web/base/admin/header.html16
-rw-r--r--templates/web/base/admin/index.html50
-rw-r--r--templates/web/base/admin/list_updates.html46
-rw-r--r--templates/web/base/admin/problem_row.html43
-rw-r--r--templates/web/base/admin/questionnaire.html30
-rw-r--r--templates/web/base/admin/report_blocks.html42
-rw-r--r--templates/web/base/admin/report_edit.html101
-rw-r--r--templates/web/base/admin/reports.html33
-rw-r--r--templates/web/base/admin/stats.html97
-rw-r--r--templates/web/base/admin/timeline.html44
-rw-r--r--templates/web/base/admin/update_edit.html67
-rw-r--r--templates/web/base/admin/user-form.html56
-rw-r--r--templates/web/base/admin/user_edit.html8
-rw-r--r--templates/web/base/admin/users.html49
-rw-r--r--templates/web/base/alert/_list.html100
-rw-r--r--templates/web/base/alert/choose.html14
-rw-r--r--templates/web/base/alert/index.html53
-rw-r--r--templates/web/base/alert/list.html41
-rw-r--r--templates/web/base/alert/updates.html21
-rwxr-xr-xtemplates/web/base/around/_report_banner.html10
-rwxr-xr-xtemplates/web/base/around/_updates.html12
-rw-r--r--templates/web/base/around/around_index.html24
-rw-r--r--templates/web/base/around/around_map_list_items.html18
-rwxr-xr-xtemplates/web/base/around/display_location.html110
-rw-r--r--templates/web/base/around/location_error.html1
-rw-r--r--templates/web/base/around/on_map_list_items.html15
-rw-r--r--templates/web/base/around/postcode_form.html13
-rwxr-xr-xtemplates/web/base/around/tabbed_lists.html23
-rw-r--r--templates/web/base/auth/change_password.html39
-rw-r--r--templates/web/base/auth/general.html84
-rw-r--r--templates/web/base/auth/sign_out.html7
-rw-r--r--templates/web/base/auth/token.html26
-rw-r--r--templates/web/base/common_header_tags.html41
-rw-r--r--templates/web/base/contact/blurb.html9
-rw-r--r--templates/web/base/contact/index.html101
-rw-r--r--templates/web/base/contact/submit.html20
-rw-r--r--templates/web/base/contact/who.html0
-rw-r--r--templates/web/base/dashboard/index.html172
-rw-r--r--templates/web/base/debug_footer.html40
-rw-r--r--templates/web/base/debug_header.html5
-rw-r--r--templates/web/base/email_sent.html34
-rw-r--r--templates/web/base/errors.html5
-rwxr-xr-xtemplates/web/base/errors/generic.html8
-rw-r--r--templates/web/base/errors/page_error_404_not_found.html20
-rwxr-xr-xtemplates/web/base/faq/faq-en-gb.html198
-rw-r--r--templates/web/base/footer.html35
-rw-r--r--templates/web/base/front/international_banner.html0
-rw-r--r--templates/web/base/front/stats.html43
-rw-r--r--templates/web/base/header.html38
-rw-r--r--templates/web/base/header_logo.html0
-rw-r--r--templates/web/base/header_opengraph.html0
-rw-r--r--templates/web/base/header_rss.html3
-rw-r--r--templates/web/base/index-steps.html42
-rw-r--r--templates/web/base/index.html60
-rw-r--r--templates/web/base/js/translation_strings.html48
-rw-r--r--templates/web/base/js/validation_rules.html7
-rw-r--r--templates/web/base/maps/fms.html15
-rw-r--r--templates/web/base/maps/google-ol.html15
-rw-r--r--templates/web/base/maps/google.html35
-rw-r--r--templates/web/base/maps/mapquest-attribution.html14
-rw-r--r--templates/web/base/maps/openlayers.html91
-rw-r--r--templates/web/base/maps/osm-streetview.html13
-rw-r--r--templates/web/base/maps/osm.html14
-rw-r--r--templates/web/base/maps/pins_js.html4
-rw-r--r--templates/web/base/my/my.html88
-rw-r--r--templates/web/base/open311/index.html216
-rw-r--r--templates/web/base/pagination.html19
-rw-r--r--templates/web/base/questionnaire/completed-open.html11
-rw-r--r--templates/web/base/questionnaire/completed.html28
-rw-r--r--templates/web/base/questionnaire/creator_fixed.html23
-rw-r--r--templates/web/base/questionnaire/index.html123
-rw-r--r--templates/web/base/report/_council_sent_info.html5
-rw-r--r--templates/web/base/report/_main.html23
-rw-r--r--templates/web/base/report/_support.html17
-rw-r--r--templates/web/base/report/banner.html22
-rw-r--r--templates/web/base/report/display.html56
-rw-r--r--templates/web/base/report/new/category.html20
-rw-r--r--templates/web/base/report/new/category_extras.html26
-rw-r--r--templates/web/base/report/new/councils_extra_text.html1
-rw-r--r--templates/web/base/report/new/councils_text.html9
-rw-r--r--templates/web/base/report/new/councils_text_all.html27
-rw-r--r--templates/web/base/report/new/councils_text_none.html28
-rw-r--r--templates/web/base/report/new/councils_text_some.html28
-rw-r--r--templates/web/base/report/new/extra_name.html18
-rw-r--r--templates/web/base/report/new/fill_in_details.html35
-rw-r--r--templates/web/base/report/new/fill_in_details_form.html220
-rw-r--r--templates/web/base/report/new/fill_in_details_text.html13
-rw-r--r--templates/web/base/report/new/form_heading.html0
-rw-r--r--templates/web/base/report/new/notes.html11
-rw-r--r--templates/web/base/report/new/report_import.html92
-rw-r--r--templates/web/base/report/photo.html8
-rw-r--r--templates/web/base/report/update-form.html165
-rw-r--r--templates/web/base/report/update.html22
-rw-r--r--templates/web/base/report/updates.html64
-rw-r--r--templates/web/base/report_created.html9
-rwxr-xr-xtemplates/web/base/reports/_list-entry.html6
-rw-r--r--templates/web/base/reports/_rss.html2
-rwxr-xr-xtemplates/web/base/reports/_ward-list.html9
-rwxr-xr-xtemplates/web/base/reports/body.html111
-rwxr-xr-xtemplates/web/base/reports/index.html42
-rwxr-xr-xtemplates/web/base/reports/ward.html1
-rw-r--r--templates/web/base/static/about-en-gb.html9
-rwxr-xr-xtemplates/web/base/static/iphone.html52
-rw-r--r--templates/web/base/static/posters.html43
-rw-r--r--templates/web/base/tokens/abuse.html7
-rw-r--r--templates/web/base/tokens/confirm_alert.html17
-rw-r--r--templates/web/base/tokens/confirm_problem.html31
-rw-r--r--templates/web/base/tokens/confirm_update.html20
-rw-r--r--templates/web/base/tokens/error.html9
118 files changed, 5049 insertions, 0 deletions
diff --git a/templates/web/base/admin/bodies.html b/templates/web/base/admin/bodies.html
new file mode 100644
index 000000000..8bf7954f3
--- /dev/null
+++ b/templates/web/base/admin/bodies.html
@@ -0,0 +1,75 @@
+[% INCLUDE 'admin/header.html' title=loc('Bodies') -%]
+
+[% INCLUDE 'admin/edit-league.html' %]
+
+[% IF bodies.size == 0 %]
+ <p class="fms-admin-info">
+ [% loc('Currently no bodies have been created.') %]
+ <br>
+ [% loc('You need to add bodies (such as councils or departments) so that you can then add
+ the categories of problems they can handle (such as potholes or streetlights) and the
+ contacts (such as an email address) to which reports are sent.') %]
+ </p>
+[% ELSE %]
+ <table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('Name') %]</th>
+ [% IF c.cobrand.moniker == 'zurich' %]
+ <th>[% loc('Email') %]</th>
+ [% ELSE %]
+ <th>[% loc('Category') %]</th>
+ [% END %]
+ <th>[% loc('Deleted') %]</th>
+ </tr>
+ [%- FOREACH body IN bodies %]
+ [%- SET id = body.id %]
+ [% NEXT IF c.cobrand.moniker == 'zurich' AND admin_type == 'dm' AND (body.parent OR body.bodies) %]
+ <tr[% IF body.deleted %] class="adminhidden"[% END %]>
+ <td>
+ [% IF c.cobrand.moniker == 'zurich' %]
+ [% FILTER repeat(4*body.api_key) %]&nbsp;[% END %]
+ [% IF admin_type == 'super' %]
+ <a href="[% c.uri_for( 'body', id ) %]">[% body.name %]</a>
+ [% ELSE %]
+ [% body.name %]
+ [% END %]
+ [% ELSE %] [%# not Zurich: all bodies should be links %]
+ <a href="[% c.uri_for( 'body', id ) %]">[% body.name %]</a>
+ [%- ', ' _ body.parent.name IF body.parent -%]
+ [% END %]
+ </td>
+ [% IF c.cobrand.moniker == 'zurich' %]
+ <td>[% body.endpoint %]</td>
+ [% ELSE %]
+ <td>
+ [% IF counts.$id %]
+ [% tprintf( loc('%d addresses'), counts.$id.c) IF c.cobrand.moniker != 'emptyhomes' %]
+ [% IF counts.$id.deleted %]
+ (1+ deleted)
+ [% ELSIF counts.$id.confirmed != counts.$id.c %]
+ (some unconfirmed)
+ [% END %]
+ [% ELSE %]
+ no categories
+ [% END %]
+ </td>
+ [% END %]
+ <td>[% IF body.deleted %][% loc('Yes') %][% END %]</td>
+ </tr>
+ [%- END %]
+ </table>
+[% END %]
+
+[% IF c.cobrand.moniker == 'zurich' %]
+ [% IF admin_type == 'super' %]
+ <h2>[% loc('Add body') %]</h2>
+ [% INCLUDE 'admin/body-form.html', body='' %]
+ [% END %]
+[% ELSE %]
+ <div class="admin-box">
+ <h2>[% loc('Add body') %]</h2>
+ [% INCLUDE 'admin/body-form.html', body='' %]
+ </div>
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/body-form.html b/templates/web/base/admin/body-form.html
new file mode 100644
index 000000000..608a77dc2
--- /dev/null
+++ b/templates/web/base/admin/body-form.html
@@ -0,0 +1,236 @@
+ <form method="post" action="[% body ? c.uri_for('body', body.id) : c.uri_for('bodies') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <div class="fms-admin-info">
+ [% loc(
+ "Add a <strong>body</strong> for each administrative body, such as a council or department
+ to which problem reports can be sent. You can add one or more contacts (for different
+ categories of problem) to each body."
+ ) %]
+ </div>
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "The body's <strong>name</strong> identifies the body (for example, <em>Borsetshire District Council</em>)
+ and may be displayed publically."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="name">[% loc('Name') %]</label>
+ <input type="text" name="name" id="name" value="[% body.name %]" size="50">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "Identify a <strong>parent</strong> if this body is itself part of another body.
+ For basic installations, you don't need to join bodies in this way."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="parent">[% loc('Parent') %]</label>
+ <select name="parent" id="parent">
+ <option value=""> -- [% loc('Select a body') %] -- </option>
+ [% FOR b IN bodies %]
+ <option value="[% b.id %]"[% ' selected' IF body.parent.id == b.id %]>[% b.name %]</option>
+ [% END %]
+ </select>
+ </p>
+
+ [% IF areas.size == 0 AND c.config.MAPIT_URL AND (NOT c.config.MAPIT_TYPES OR c.config.MAPIT_TYPES.size==O) %]
+ <p class="fms-admin-warning">
+ [% tprintf( loc(
+ '<code>MAPIT_URL</code> is set (<code>%s</code>) but no <code>MAPIT_TYPES</code>.<br>
+ This is probably why "area covered" is empty (below).<br>
+ Maybe add some <code>MAPIT_TYPES</code> to your config file?'), c.config.MAPIT_URL)
+ %]
+ </p>
+ [% END %]
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "This body will only be sent reports for problems that are located in the <strong>area covered</strong>.
+ A body will not receive any reports unless it covers at least one area."
+ ) %]
+ <br>
+ [% IF c.config.MAPIT_URL %]
+ [% tprintf( loc("The list of available areas is being provided by the MapIt service at %s."), c.config.MAPIT_URL) %]
+ [% ELSE %]
+ [% loc(
+ "No specific areas are currently available, because the <code>MAPIT_URL</code> in
+ your config file is not pointing to a live MapIt service.") %]
+ [% END %]
+ <br>
+ [% loc("For more information, see <a href='http://fixmystreet.org/customising/fms_and_mapit' class='admin-offsite-link'>How FixMyStreet uses Mapit</a>.")%]
+ </p>
+ </div>
+ <p>
+ <label for="area_ids">[% loc('Area covered') %]</label>
+ <select name="area_ids" id="area_ids" multiple>
+ <option value=""> -- [% loc('Select an area') %] -- </option>
+ [% SET body_areas = body.areas %]
+ [% FOR area IN areas %]
+ [% SET aid = area.id %]
+ <option value="[% area.id %]"[% ' selected' IF body_areas.$aid %]>[% area.name %]</option>
+ [% END %]
+ </select>
+ </p>
+
+ <div class="admin-hint">
+ <p>[% loc( "You can mark a body as deleted if you do not want it to be active on the site." ) %]</p>
+ </div>
+ <p>
+ <label for="deleted">[% loc('Flag as deleted') %]</label>
+ <input type="checkbox" name="deleted" id="deleted" value="1"[% ' checked' IF body.deleted %]>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "The <strong>send method</strong> determines how problem reports will be sent to the body.
+ If you leave this blank, <strong>send method defaults to email</strong>."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="send_method">Send Method</label>
+ <select name="send_method" id="send_method">
+ <option value=""> -- Select a method -- </option>
+ [% FOR method IN send_methods %]
+ <option value="[% method %]"[% ' selected' IF body.send_method == method %]>[% method %]</option>
+ [% END %]
+ </select>
+ </p>
+
+ <div class="admin-open311-only">
+ <p class="fms-admin-info">
+ [% loc(
+ "These settings are for bodies that use Open311 (or other back-end integration) to receive problem reports.<br>
+ <strong>You don't need to set them if the Send Method is email.</strong>.
+ For more information on Open311, see
+ <a href='https://www.mysociety.org/2013/01/17/open311-explained/' class='admin-offsite-link'>this article</a>.
+ "
+ ) %]
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "The <strong>endpoint</strong> is the URL of the service that FixMyStreet will connect to
+ when sending reports to this body."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="endpoint">[% loc('Endpoint') %]</label>
+ <input type="text" name="endpoint" id="endpoint" value="[% body.endpoint %]" size="50">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "The <strong>jurisdiction</strong> is only needed if the endpoint is serving more
+ than one. If the body is running its own endpoint, you can usually leave this blank."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="jurisdiction">Open311 Jurisdiction</label>
+ <input type="text" name="jurisdiction" id="jurisdiction" value="[% body.jurisdiction %]" size="50">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "Some endpoints require an <strong>API key</strong> to indicate that the reports are being
+ sent from your FixMyStreet installation."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for="api_key">Open311 API Key</label>
+ <input type="text" name="api_key" id="api_key" value="[% body.api_key %]" size="25">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "Enable <strong>Open311 update-sending</strong> if the endpoint will send and receive
+ updates to existing reports. If you're not sure, it probably does not, so leave this unchecked.
+ For more information, see
+ <a href='https://www.mysociety.org/2013/02/20/open311-extended/' class='admin-offsite-link'>this article</a>."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" id="send_comments" name="send_comments"[% ' checked' IF body.send_comments %]>
+ <label for="send_comments" class="inline">Use Open311 update-sending extension</label>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "If you've enabled Open311 update-sending above, you must identify which
+ FixMyStreet <strong>user</strong> will be attributed as the creator of those updates
+ when they are shown on the site. Enter the ID (number) of that user."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <label for"comment_user_id">User ID to attribute fetched comments to</label>
+ <input type="text" name="comment_user_id" value="[% body.comment_user_id %]">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "If you've enabled Open311 update-sending above, enable <strong>suppression of alerts</strong>
+ if you do <strong>not</strong> want that user to be notified whenever these updates are created."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" id="suppress_alerts" name="suppress_alerts"[% ' checked' IF body.suppress_alerts %]>
+ <label for="suppress_alerts" class="inline">Do not send email alerts on fetched comments to problem creator</label>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "If you've enabled Open311 update-sending above, Open311 usually only accepts OPEN or CLOSED status in
+ its updates. Enable <strong>extended Open311 stauses</strong> if you want to allow extra states to be passed.
+ Check that your cobrand supports this feature before switching it on."
+ ) %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" id="send_extended_statuses" name="send_extended_statuses"[% ' checked' IF conf.send_extended_statuses %]>
+ <label for="send_extended_statuses" class="inline">Send extended Open311 statuses with service request updates</label>
+ </p>
+ </div>
+
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "Enable this <strong>can be devolved</strong> setting if one or more contacts have a
+ different endpoint (and send method) from the body's. For example, if reports for some categories of
+ problem must be emailed, while others can be sent over Open311."
+ ) %]
+ <br>
+ [%# NB 'email' is a literal setting, so not translating it in following string? %]
+ [% tprintf( loc('Leave this blank if all reports to this body should be sent using the same send method (e.g., "%s").'), body.send_method or 'email' ) %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" id="can_be_devolved" name="can_be_devolved"[% ' checked' IF body.can_be_devolved %]>
+ <label for="can_be_devolved" class="inline">Send method or endpoints can be devolved to contacts (i.e, can be different from the body's)</label>
+ </p>
+
+ <p>
+ <input type="hidden" name="posted" value="body">
+ <input type="hidden" name="token" value="[% token %]">
+ <input type="submit" value="[% body ? loc('Update body') : loc('Add body') %]">
+ </p>
+ </form>
+
diff --git a/templates/web/base/admin/body.html b/templates/web/base/admin/body.html
new file mode 100644
index 000000000..b207d18ca
--- /dev/null
+++ b/templates/web/base/admin/body.html
@@ -0,0 +1,192 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Council contacts for %s'), body.name) -%]
+
+[% IF updated %]
+ <p>
+ <em>[% updated %]</em>
+ </p>
+[% END %]
+
+<p>
+ [% IF example_pc %]
+ <a href="[% c.uri_for_email( '/around', { pc => example_pc } ) %]" class="admin-offsite-link">[% tprintf( loc('Example postcode %s'), example_pc ) | html %]</a> |
+ [% END %]
+ [% IF c.cobrand.moniker == 'emptyhomes' %]
+ <a href="[% c.uri_for( 'reports', search => 'body:' _ body_id ) %]">[% loc('List all reported problems' ) %]</a> |
+ [% ELSE %]
+ <a href="[% c.uri_for_email( '/reports/' _ body_id ) %]" class="admin-offsite-link">[% loc('List all reported problems' ) %]</a> |
+ [% END %]
+ <a href="[% c.uri_for( 'body', body_id, { text => 1 } ) %]">[% loc('Text only version') %]</a>
+</p>
+
+[% IF body.send_method == 'Open311' %]
+ <h2>
+ Council contacts configured via Open311
+ </h2>
+[% END %]
+
+[% IF c.cobrand.moniker == 'fixmystreet' %]
+ <p class="error">Do not give these out except to people at the council.</p>
+[% END %]
+
+[% IF body.areas.size == 0 %]
+ <p class="fms-admin-warning">
+ [% loc("This body covers no area. This means that it has no jurisdiction over problems reported <em>at any location</em>.
+ Consequently, none of its categories will appear in the drop-down category menu when users report problems.
+ Currently, users <strong>cannot report problems to this body</strong>.") %]
+ <br>
+ [% loc("Fix this by choosing an <strong>area covered</strong> in the <em>Edit body details</em> form below.") %]
+ </p>
+[% END %]
+
+[% IF live_contacts == 0 %]
+ <p class="fms-admin-warning">
+ [% loc("This body has no contacts. This means that currently problems reported to this body <strong>will not be sent</strong>.") %]
+ <br>
+ [% loc("Add a contact using the form below.") %]
+ </p>
+[% END %]
+
+<form method="post" action="[% c.uri_for('body', body_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+
+ <table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('Category') %]</th>
+ <th>[% loc('Email') %]</th>
+ <th>[% loc('Confirmed') %]</th>
+ <th>[% loc('Deleted') %]</th>
+ <th>[% loc('Devolved') %]</th>
+ <th>[% loc('Last editor') %]</th>
+ <th>[% loc('Note') %]</th>
+ <th>[% loc('Public') %]</th>
+ <th>[% loc('When edited') %]</th>
+ <th>[% loc('Confirm') %]</th>
+ </tr>
+ [% WHILE ( contact = contacts.next ) %]
+ <tr [% IF contact.deleted %]class="is-deleted"[% END %]>
+ <td class="contact-category"><a href="[% c.uri_for( 'body_edit', body_id, contact.category ) %]">[% contact.category %]</a></td>
+ <td>[% contact.email | html %]</td>
+ <td>[% IF contact.confirmed %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% IF contact.deleted %]<strong>[% loc('Yes') %]</strong>[% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% IF body.can_be_devolved && contact.send_method %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% contact.editor %]</td>
+ <td>[% contact.note | html %]</td>
+ <td>[% contact.non_public ? loc('Non Public') : loc('Public') %]</td>
+ <td>[% contact.whenedited.ymd _ ' ' _ contact.whenedited.hms %]</td>
+ <td><input type="checkbox" name="confirmed" value="[% contact.category %]"></td>
+ </tr>
+ [% END %]
+ </table>
+
+ <p>
+ <input type="hidden" name="posted" value="update">
+ <input type="hidden" name="token" value="[% token %]">
+ <input type="submit" name="Update statuses" value="[% loc('Update statuses') %]">
+ </p>
+</form>
+
+<div class="admin-box">
+ <h2>[% loc('Add new category') %]</h2>
+ <p class="fms-admin-info">
+ [% loc("Each contact for the body has a category, which is displayed to the public.
+ Different categories <strong>can have the same contact</strong> (email address).
+ This means you can add many categories even if you only have one contact for the body.
+ ") %]
+ </p>
+
+ <form method="post" action="[% c.uri_for('body', body_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ <div class="admin-hint">
+ <p>
+ [% loc('Choose a <strong>category</strong> name that makes sense to the public (e.g., "Pothole", "Street lighting") but is helpful
+ to the body too. These will appear in the drop-down menu on the report-a-problem page.') %]
+ <br>
+ [% loc("If two or more bodies serve the same location, FixMyStreet combines identical categories into a single entry in
+ the menu. Make sure you use the same category name in the bodies if you want this to happen.") %]
+ </p>
+ </div>
+ <p>
+ <strong>[% loc('Category:') %] </strong><input type="text" name="category" size="30">
+ </p>
+ [% END %]
+
+ <div class="admin-hint">
+ <p>
+ [% loc("The <strong>email address</strong> is the destination to which reports about this category will be sent.
+ Other categories for this body may have the same email address.") %]
+ </p>
+ [% IF (body.send_method AND body.send_method != 'Email') OR body.can_be_devolved %]
+ <p>
+ [% loc("If you're using <strong>a send method that is not email</strong>, enter the service ID (Open311) or equivalent identifier here.") %]
+ </p>
+ [% END %]
+ </div>
+
+ <p>
+ <strong>[% loc('Email address:') %] </strong><input type="text" name="email" size="30">
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc("Check <strong>confirmed</strong> to indicate that this contact has been confirmed as correct.
+ If you are not sure of the origin or validity of the contact, leave this unchecked.") %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" name="confirmed" value="1" id="confirmed">
+ <label for="confirmed" class="inline">[% loc('Confirmed') %]</label>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc("Check <strong>deleted</strong> to remove the category from use.
+ It will not appear as an available category in the drop-down menu on the report-a-problem page.") %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" name="deleted" value="1" id="deleted">
+ <label for="deleted" class="inline">[% loc('Deleted') %]</label>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc("Use the <strong>note</strong> to record details that are only displayed in the admin. Notes are not shown publicly, and are not sent to the body.") %]
+ </p>
+ </div>
+ <p>
+ <strong>[% loc('Note:') %] </strong> <textarea name="note" rows="3" cols="40"></textarea>
+ </p>
+
+ <div class="admin-hint">
+ <p>
+ [% loc("Check <strong>private</strong> if reports in this category should <strong>never be displayed on the website</strong>.
+ <br>
+ Normally, categories are not private.
+ <br>
+ This is suitable for issues that you want to allow users to report to the body, but for which there is no public
+ interest in displaying the report. In the UK, we've used this for services like requesting an extra rubbish bin
+ at a specific address.") %]
+ </p>
+ </div>
+ <p>
+ <input type="checkbox" name="non_public" value="1" id="non_public">
+ <label for="non_public" class="inline">[% loc('Private') %]</label>
+ </p>
+
+ <p>
+ <input type="hidden" name="posted" value="new" >
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="submit" name="Create category" value="[% loc('Create category') %]" >
+ </p>
+
+ <div>
+ <input type="hidden" name=".cgifields" value="confirmed" >
+ <input type="hidden" name=".cgifields" value="deleted" >
+ </div>
+ </form>
+</div>
+<div class="admin-box">
+ <h2>[% loc('Edit body details') %]</h2>
+ [% INCLUDE 'admin/body-form.html' %]
+</div>
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/body_edit.html b/templates/web/base/admin/body_edit.html
new file mode 100644
index 000000000..f2bae0c0b
--- /dev/null
+++ b/templates/web/base/admin/body_edit.html
@@ -0,0 +1,103 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Council contacts for %s'), body.name) -%]
+
+[% BLOCK highlightchanged_yesno %]
+[%- output = loc('No') %]
+[%- IF new.$value %][% output = loc('Yes') %][% END %]
+[%- IF old && old.$value != new.$value %]<strong>[% output %]</strong>[% ELSE %][% output %][% END %]
+[%- END %]
+
+[% BLOCK highlightchanged %]
+[%- IF old && old.$value != new.$value %]<strong>[% new.$value %]</strong>[% ELSE %][% new.$value %][% END %]
+[%- END %]
+<p>
+<em>[% updated %]</em>
+</p>
+
+<p>
+[% IF example_pc %]
+<a href="[% c.uri_for_email( '/around', { pc => example_pc } ) %]" class="admin-offsite-link">[% tprintf( loc('Example postcode %s'), example_pc ) | html %]</a>
+[% END %]
+</p>
+
+<form method="post" action="[% c.uri_for('body', body_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <p><strong>[% loc('Category:') %] </strong>[% contact.category | html %]
+ <input type="hidden" name="category" value="[% contact.category | html %]" >
+ <input type="hidden" name="token" value="[% token %]" >
+ <p><strong>[% loc('Email:') %] </strong>
+ <input type="text" name="email" value="[% contact.email | html %]" size="30">
+
+ <p>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <input type="checkbox" name="confirmed" value="1" id="confirmed"[% ' checked' IF contact.confirmed %]>
+ <label class="inline" for="confirmed">[% loc('Confirmed' ) %]</label>
+ [% ELSE %]
+ <input type="hidden" name="confirmed" value="1">
+ [% END %]
+ <input type="checkbox" name="deleted" value="1" id="deleted"[% ' checked' IF contact.deleted %]>
+ <label class="inline" for="deleted">[% loc('Deleted') %]</label>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <input type="checkbox" name="non_public" value="1" id="non_public"[% ' checked' IF contact.non_public %]>
+ <label class="inline" for="non_public">[% loc('Private') %]</label>
+ [% END %]
+ </p>
+
+ <p><strong>[% loc('Note:') %] </strong><textarea name="note" rows="3" cols="40">[% contact.note | html %]</textarea>
+
+ [% IF body.can_be_devolved %]
+ <h2>[% loc('Configure Endpoint') %]</h2>
+ <form method="post" action="[% c.uri_for('body', body_id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <p>
+ <label for="endpoint">Endpoint</label>
+ <input type="text" name="endpoint" id="endpoint" value="[% contact.endpoint %]" size="50">
+ </p>
+
+ <p>
+ <label for="jurisdiction">Jurisdiction</label>
+ <input type="text" name="jurisdiction" id="jurisdiction" value="[% contact.jurisdiction %]" size="50">
+ </p>
+
+ <p>
+ <label for="api_key">Api Key</label>
+ <input type="text" name="api_key" id="api_key" value="[% contact.api_key %]" size="25">
+ </p>
+
+ <p>
+ <label for="send_method">Send Method</label>
+ <select name="send_method">
+ <option value=""> -- Select a method -- </option>
+ [% FOR method IN send_methods %]
+ <option value="[% method %]"[% ' selected' IF contact.send_method == method %]>[% method %]</option>
+ [% END %]
+ </select>
+ </p>
+ [% END %]
+
+ <input type="hidden" name="posted" value="new">
+ <p><input type="submit" name="Save changes" value="[% loc('Save changes') %]">
+</form>
+
+<h2>[% loc('History') %]</h2>
+<table border="1">
+ <tr>
+ <th>[% loc('When edited') %]</th>
+ <th>[% loc('Email') %]</th>
+ <th>[% loc('Confirmed') %]</th>
+ <th>[% loc('Deleted') %]</th>
+ <th>[% loc('Editor') %]</th>
+ <th>[% loc('Note') %]</th>
+ </tr>
+ [%- prev = '' %]
+ [%- WHILE ( contact = history.next ) %]
+ <tr>
+ <td>[% contact.whenedited.ymd _ ' ' _ contact.whenedited.hms %]</td>
+ <td>[% PROCESS highlightchanged old=prev new=contact value='email' %]</td>
+ <td>[% PROCESS highlightchanged_yesno old=prev new=contact value='confirmed' %]</td>
+ <td>[% PROCESS highlightchanged_yesno old=prev new=contact value='deleted' %]</td>
+ <td>[% contact.editor %]</td>
+ <td>[% contact.note | html %]</td>
+ </tr>
+ [%- prev = contact %]
+ [%- END %]
+</table>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/config_page.html b/templates/web/base/admin/config_page.html
new file mode 100644
index 000000000..83300e4db
--- /dev/null
+++ b/templates/web/base/admin/config_page.html
@@ -0,0 +1,146 @@
+[% INCLUDE 'admin/header.html' title=loc('Configuration') -%]
+
+[% BLOCK subsection %]
+<tr><td colspan=3><strong>[% heading %]</strong></td></tr>
+[% END %]
+
+[% BLOCK just_value %]
+[% SET conf = c.config.$value IF NOT conf;
+ conf = conf.join(', ') IF conf.size %]
+<tr>
+ <td>[% value %]</td>
+ <td colspan=2>[% conf or conf_default %]</td>
+</tr>
+[% END %]
+
+[% BLOCK with_cobrand %]
+[% SET conf = c.config.$value IF NOT conf;
+ conf = conf.join(', ') IF conf.size;
+ cob = cob.join(', ') IF conf.size %]
+<tr>
+ <td>[% value %]</td>
+ <td>[% conf %]</td>
+ <td>[% cob IF cob != conf %]</td>
+</tr>
+[% END %]
+
+<p>A summary of this site's configuration,
+running version <strong>[% git_version || 'unknown' %]</strong>.
+</p>
+
+<table>
+<tr><th>Variable</th>
+ <th>general.yml value</th>
+ <th>Cobrand module override</th>
+</tr>
+
+[% INCLUDE subsection heading="URLs" %]
+[% INCLUDE with_cobrand value="BASE_URL" cob=c.cobrand.base_url %]
+[% INCLUDE with_cobrand value="ADMIN_BASE_URL" cob=c.cobrand.admin_base_url %]
+
+[% INCLUDE subsection heading="Display" %]
+[% allowed_conf = FOR k IN c.config.ALLOWED_COBRANDS %]
+ [% IF k.keys %][% k.items.join(':') %][% ELSE %][% k %][% END %]
+ [%- ',' IF NOT loop.last %]
+[% END %]
+[% INCLUDE just_value value="ALLOWED_COBRANDS" conf = allowed_conf %]
+<tr>
+<td>Web templates</td>
+<td colspan=2>[% c.cobrand.path_to_web_templates.join('<br>') %]</td>
+</tr>
+[% INCLUDE with_cobrand value="MAP_TYPE" cob=c.cobrand.map_type %]
+[% INCLUDE with_cobrand value="EXAMPLE_PLACES"
+ conf = decode(c.config.EXAMPLE_PLACES.join(', '))
+ cob = c.cobrand.example_places %]
+[% INCLUDE with_cobrand value="LANGUAGES"
+ cob = c.cobrand.languages %]
+<tr><td>Language override</td>
+ <td>-</td>
+ <td>
+ [% 'domain=' _ c.cobrand.language_domain IF c.cobrand.language_domain %]
+ [% 'language=' _ c.cobrand.language_override IF c.cobrand.language_override %]
+ </td>
+</tr>
+[% INCLUDE with_cobrand value="ALL_REPORTS_PER_PAGE" cob=c.cobrand.reports_per_page %]
+[% INCLUDE just_value value="RSS_LIMIT" %]
+[% INCLUDE just_value value="AREA_LINKS_FROM_PROBLEMS" %]
+
+[% INCLUDE subsection heading="Geocoder" %]
+[% INCLUDE just_value value="GEOCODER"
+ conf_default = '<em>(None; default Nominatim OSM)</em>'
+%]
+[% disconf = FOR k IN c.config.GEOCODING_DISAMBIGUATION %]
+ [% k.key %]=[% k.value %][% ',' IF NOT loop.last %]
+[% END %]
+[% discob = FOR k IN c.cobrand.disambiguate_location %]
+ [% k.key %]=[% k.value %][% ',' IF NOT loop.last %]
+[% END %]
+[% INCLUDE with_cobrand value="GEOCODING_DISAMBIGUATION"
+ conf = disconf
+ cob = discob %]
+
+[% INCLUDE subsection heading="MapIt" %]
+[% INCLUDE just_value value="MAPIT_URL" %]
+[% INCLUDE with_cobrand value="MAPIT_TYPES"
+ cob = c.cobrand.area_types %]
+[% INCLUDE just_value value="MAPIT_ID_WHITELIST" %]
+[% INCLUDE just_value value="MAPIT_GENERATION" %]
+[% INCLUDE with_cobrand value="MAPIT_TYPES_CHILDREN"
+ cob = c.cobrand.area_types_children %]
+
+[% INCLUDE subsection heading="Database" %]
+[% INCLUDE just_value value="FMS_DB_HOST" %]
+[% INCLUDE just_value value="FMS_DB_PORT" %]
+[% INCLUDE just_value value="FMS_DB_NAME" %]
+[% INCLUDE just_value value="FMS_DB_USER" %]
+
+[% INCLUDE subsection heading="Email" %]
+[% INCLUDE just_value value="EMAIL_DOMAIN" %]
+[% INCLUDE with_cobrand value="CONTACT_NAME" cob=c.cobrand.contact_name %]
+[% INCLUDE with_cobrand value="CONTACT_EMAIL" cob=c.cobrand.contact_email %]
+[% INCLUDE just_value value="DO_NOT_REPLY_EMAIL" %]
+
+[% INCLUDE subsection heading="Development" %]
+[% INCLUDE just_value value="STAGING_SITE" %]
+[% INCLUDE just_value value="SEND_REPORTS_ON_STAGING" %]
+[% INCLUDE just_value value="UPLOAD_DIR" %]
+[% INCLUDE just_value value="GEO_CACHE" %]
+[% INCLUDE just_value value="TESTING_COUNCILS" %]
+[% INCLUDE just_value value="SMTP_SMARTHOST" %]
+[% INCLUDE just_value value="TIME_ZONE" %]
+[% INCLUDE just_value value="GAZE_URL" %]
+
+</table>
+
+<h2>Cobrand module</h2>
+
+Other things can be changed on a cobrand basis by using functions in an
+(optional) Cobrand .pm module, as explained in the
+<a href="http://fixmystreet.org/customising/" class="admin-offsite-link">customising section of our
+documentation</a>. If you wish to add new functionality just for your cobrand
+that can't be done simply by changes to your cobrand's templates, you might
+need to add a new Cobrand function.
+
+<p>Examples of cobrand functions are below; this is not exhaustive.
+Many were added for one specific cobrand, so didn't need a general
+configuration option. Please feel free to discuss on <a
+href="http://fixmystreet.org/community/" class="admin-offsite-link">our mailing list</a> if you think
+something should be moved to the general.yml file, done differently,
+or have any questions.</p>
+
+<ul style="font-size: 80%">
+<li>allow_photo_upload: [% c.cobrand.allow_photo_upload %],
+ allow_photo_display: [% c.cobrand.allow_photo_display %]</li>
+<li>send_questionnaires: [% c.cobrand.send_questionnaires %],
+ ask_ever_reported: [% c.cobrand.ask_ever_reported %]</li>
+<li>default_map_zoom: [% c.cobrand.default_map_zoom or '-' %]</li>
+<li>default_show_name: [% c.cobrand.default_show_name %]</li>
+<li>users_can_hide: [% c.cobrand.users_can_hide %]</li>
+<li>report_sent_confirmation_email: [% c.cobrand.report_sent_confirmation_email %]</li>
+<li>never_confirm_reports: [% c.cobrand.never_confirm_reports %],
+ allow_anonymous_reports: [% c.cobrand.allow_anonymous_reports %],
+ show_unconfirmed_reports: [% c.cobrand.show_unconfirmed_reports %]</li>
+</ul>
+
+[% INCLUDE 'admin/footer.html' %]
+
diff --git a/templates/web/base/admin/council_contacts.txt b/templates/web/base/admin/council_contacts.txt
new file mode 100644
index 000000000..2d1e04bfa
--- /dev/null
+++ b/templates/web/base/admin/council_contacts.txt
@@ -0,0 +1,4 @@
+[% WHILE ( contact = contacts.next ) -%]
+[%- NEXT IF contact.deleted || ! contact.confirmed %]
+[% contact.category %] [% contact.email %]
+[%- END %]
diff --git a/templates/web/base/admin/edit-league.html b/templates/web/base/admin/edit-league.html
new file mode 100644
index 000000000..4f31eeb2e
--- /dev/null
+++ b/templates/web/base/admin/edit-league.html
@@ -0,0 +1,21 @@
+<div class="admin-hint">
+ <p>
+ [% loc(
+ "The diligency prize league table shows editors' activity (who's been editing the most records)."
+ ) %]
+ </p>
+</div>
+<h2>[% loc('Diligency prize league table') %]</h2>
+[% IF edit_activity.count %]
+<ul>
+ [% WHILE ( editor = edit_activity.next ) %]
+ <li>[% tprintf( loc('%d edits by %s'), editor.get_column('c'), editor.editor ) %]</li>
+ [% END %]
+</ul>
+[% ELSE %]
+<p>
+[% loc('No edits have yet been made.') %]
+</p>
+[% END %]
+
+
diff --git a/templates/web/base/admin/flagged.html b/templates/web/base/admin/flagged.html
new file mode 100644
index 000000000..518d1b14e
--- /dev/null
+++ b/templates/web/base/admin/flagged.html
@@ -0,0 +1,62 @@
+[% INCLUDE 'admin/header.html' title=loc('Flagged reports and users') %]
+[% PROCESS 'admin/report_blocks.html' %]
+
+<p class="fms-admin-info">
+ [% loc("You can flag any report or user by editing them, and they will be listed on this page.
+ For example, this can useful if you want to keep an eye on a user who has posted inappropriate
+ reports in the past.") %]
+</p>
+
+<h2>[% loc( 'Problems' ) %]</h2>
+[% IF problems.size > 0 %]
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('ID') %]</th>
+ <th>[% loc('Title') %]</th>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Body') %]</th>
+ <th>[% loc('State') %]</th>
+ <th>*</th>
+ </tr>
+ [% INCLUDE 'admin/problem_row.html' %]
+</table>
+[% ELSE %]
+ <p class="fms-admin-warning">
+ [% loc('No flagged problems found.') %]
+ </p>
+[% END %]
+
+<h2>[% loc( 'Users' ) %]</h2>
+<p class="fms-admin-info">
+ [% loc("Flagged users are not restricted in any way. This is just a list of users that have been marked for attention.") %]
+</p>
+
+[% IF users.size %]
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Email') %]</th>
+ <th>[% loc('In abuse table?') %]</th>
+ <th>&nbsp;</th>
+ </tr>
+ [%- FOREACH user IN users %]
+ <tr [% IF user.flagged == 2 %]class="is-deleted"[% END %]>
+ <td>[% user.name | html %]</td>
+ <td>[% user.email | html %]</td>
+ <td>
+ [% IF user.flagged == 2 %] <strong>[% loc('Yes') %]</strong> [% ELSE %] &nbsp; [% END %]
+ </td>
+ <td>
+ <a href="[% c.uri_for( 'reports', search => user.email ) %]">list content</a>
+ [% IF user.id %] | <a href="[% c.uri_for( 'user_edit', user.id ) %]">[% loc('edit user') %]</a>[% END %]
+ </td>
+ </tr>
+ [%- END %]
+</table>
+[%- ELSE %]
+<p class="fms-admin-warning">
+ [% loc('No flagged users found.') %]
+</p>
+[%- END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/footer.html b/templates/web/base/admin/footer.html
new file mode 100644
index 000000000..4c891c4ff
--- /dev/null
+++ b/templates/web/base/admin/footer.html
@@ -0,0 +1 @@
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/admin/header.html b/templates/web/base/admin/header.html
new file mode 100644
index 000000000..9f3503e20
--- /dev/null
+++ b/templates/web/base/admin/header.html
@@ -0,0 +1,16 @@
+[% INCLUDE 'header.html' admin = 1, bodyclass = 'fullwidthpage admin show-admin-notes' %]
+<style type="text/css">
+dt { clear: left; float: left; font-weight: bold; }
+dd { margin-left: 8em; }
+.adminhidden { color: #666666; }
+.error { color: red; }
+select { width: auto; }
+</style>
+
+ <p><strong>[% loc('FixMyStreet admin:') %]</strong>
+ [%- FOREACH link IN allowed_links %]
+ <a href="[% c.uri_for( link ) %]">[% allowed_pages.$link.0 %]</a>
+ [% IF NOT loop.last %]|[% END %]
+ [% END %]</p>
+
+ <h1>[% title %]</h1>
diff --git a/templates/web/base/admin/index.html b/templates/web/base/admin/index.html
new file mode 100644
index 000000000..ad5932d97
--- /dev/null
+++ b/templates/web/base/admin/index.html
@@ -0,0 +1,50 @@
+[% INCLUDE 'admin/header.html' title=loc('Summary') -%]
+
+[% IF total_bodies == 0 %]
+ <p class="fms-admin-info">
+ [% loc('Currently no bodies have been created.') %]
+ <br>
+ [% tprintf( loc('You need to <a href="%s">add some bodies</a> (such as councils or departments) before any reports can be sent.'), c.uri_for('bodies')) %]
+ </p>
+[% END %]
+
+[%- BLOCK states -%]
+<h2>[% title %]</h2>
+
+[%- FOREACH state IN object.keys.sort %]
+[%- '<ul>' IF loop.first %]
+ <li>[% object.$state %] [% state %]</li>
+[%- "\n</ul>" IF loop.last %]
+[%- END %]
+[% END -%]
+
+ <ul>
+ <li>[% tprintf( loc('<strong>%d</strong> live problems'), total_problems_live ) %];
+ [% tprintf( loc('from %d different users'), total_problems_users ) %]</li>
+ <li>[% tprintf( loc('%d live updates'), comments.confirmed || 0 ) %]</li>
+ <li>[% tprintf( loc('%d confirmed alerts, %d unconfirmed'), alerts.1, alerts.0) %]</li>
+ <li>[% tprintf( loc('%d questionnaires sent &ndash; %d answered (%s%%)'), questionnaires.total, questionnaires.1, questionnaires_pc) %]</li>
+ <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" class="admin-offsite-link">[% loc('Graph of problem creation by status over time') %]</a>
+ </p>
+[% END -%]
+
+[% PROCESS states title=loc('Problem breakdown by state') object=problems %]
+
+[% PROCESS states title=loc('Update breakdown by state') object=comments %]
+
+[% FOREACH category IN categories %]
+ [% IF loop.first %]
+ <h2>[% loc('Category fix rate for problems > 4 weeks old') %]</h2>
+ <table>
+ <tr><th>[% loc('Category') %]</th><th>[% loc('Total') %]</th><th>[% loc('Fixed') %]</th></tr>
+ [% END %]
+ <tr><td>[% category.key %]</td><td>[% category.value.total %]</td><td>[% category.value.fixed / category.value.total * 100 | format('%.1f') %]%</td></tr>
+ [% '</table>' IF loop.last %]
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/list_updates.html b/templates/web/base/admin/list_updates.html
new file mode 100644
index 000000000..02845b0ee
--- /dev/null
+++ b/templates/web/base/admin/list_updates.html
@@ -0,0 +1,46 @@
+[% IF updates.size %]
+<h2>[% loc('Updates') %]</h2>
+
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('ID') %]</th>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Owner') %]</th>
+ <th>[% loc('Council') %]</th>
+ <th>[% loc('Cobrand') %]</th>
+ <th>[% loc('State') %]</th>
+ <th>[% loc('Text') %]</th>
+ <th>*</th>
+ </tr>
+[% FOREACH update IN updates -%]
+ <tr[% ' class="adminhidden"' IF update.state == 'hidden' || update.problem.state == 'hidden' %]>
+ <td>[%- IF update.state == 'confirmed' && update.problem.state != 'hidden' -%]
+ [%- cobrand_data = update.cobrand_data;
+ cobrand_data = c.data_for_generic_update IF !update.cobrand;
+ IF cobrand_data;
+ uri = c.uri_for_email( '/report', update.problem.id, cobrand_data );
+ ELSE;
+ uri = c.uri_for_email( '/report', update.problem.id );
+ END;
+ %]
+ <a href="[% uri %]#update_[% update.id %]" class="admin-offsite-link">[% update.id %]</a>
+ [%- ELSE %]
+ [%- update.id %]
+ [%- END -%]</td>
+ <td>[% PROCESS value_or_nbsp value=update.name %]
+ <br>[% PROCESS value_or_nbsp value=update.user.email %]
+ <br>[% loc('Anonymous') %]: [% IF update.anonymous %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]
+ </td>
+ <td>[% IF update.user.id == update.problem.user_id %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% IF update.user.belongs_to_body( update.problem.bodies_str ) %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</td>
+ <td>[% update.cobrand %]<br>[% update.cobrand_data | html %]</td>
+ <td>[% update.state %]<br><small>
+ [% loc('Created:') %] [% PROCESS format_time time=update.created %]
+ <br>[% loc('Confirmed:') %] [% PROCESS format_time time=update.confirmed %]
+ </small></td>
+ <td>[% update.text | html %]</td>
+ <td><a href="[% c.uri_for( 'update_edit', update.id ) %]">[% loc('Edit') %]</a></td>
+ </tr>
+[% END -%]
+</table>
+[% END %]
diff --git a/templates/web/base/admin/problem_row.html b/templates/web/base/admin/problem_row.html
new file mode 100644
index 000000000..2413a6062
--- /dev/null
+++ b/templates/web/base/admin/problem_row.html
@@ -0,0 +1,43 @@
+[%- FOR problem IN problems %]
+ <tr[% ' class="adminhidden"' IF problem.state == 'hidden' %]>
+ <td class="record-id">[%- IF problem.is_visible -%]
+ [%- cobrand_data = problem.cobrand_data;
+ cobrand_data = c.data_for_generic_problem IF !problem.cobrand;
+ IF cobrand_data;
+ uri = c.uri_for_email( '/report', problem.id, cobrand_data );
+ ELSE;
+ uri = c.uri_for_email( '/report', problem.id );
+ END;
+ %]
+ <a href="[% uri %]" class="admin-offsite-link">[% problem.id %]</a>
+ [%- ELSE %]
+ [%- problem.id %]
+ [%- END -%]</td>
+ <td>[% PROCESS value_or_nbsp value=problem.title %]</td>
+ <td>
+ [% PROCESS value_or_nbsp value=problem.name %]
+ <br>[% PROCESS value_or_nbsp value=problem.user.email %]
+ <br>[% loc('Anonymous') %]: [% IF problem.anonymous %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]
+ </td>
+ <td>
+ [% PROCESS value_or_nbsp value=problem.category %]
+ <br>[%- IF edit_body_contacts -%]
+ [% FOR body IN problem.bodies.values %]
+ <a href="[% c.uri_for('body', body.id ) %]">[% PROCESS value_or_nbsp value=body.name %]</a>
+ [% END %]
+ [%- ELSE -%]
+ [%- PROCESS value_or_nbsp value=problem.bodies_str -%]
+ [%- END -%]
+ <br>[% problem.cobrand %]<br>[% problem.cobrand_data | html %]
+ </td>
+ <td>[% problem.state %]<br><small>
+ [% loc('Created') %]:&nbsp;[% PROCESS format_time time=problem.created %]
+ <br>[% loc('When sent') %]:&nbsp;[% PROCESS format_time time=problem.whensent %]
+ [%- IF problem.is_visible %]<br>[% loc('Confirmed:' ) %]&nbsp;[% PROCESS format_time time=problem.confirmed %][% END -%]
+ [%- IF problem.is_fixed %]<br>[% loc('Fixed:') %] [% PROCESS format_time time=problem.lastupdate %][% END -%]
+ [%- IF problem.is_closed %]<br>[% loc('Closed:') %] [% PROCESS format_time time=problem.lastupdate %][% END -%]
+ [%- IF problem.is_open %]<br>[% loc('Last&nbsp;update:') %] [% PROCESS format_time time=problem.lastupdate %][% END -%]
+ </small></td>
+ <td><a href="[% c.uri_for( 'report_edit', problem.id ) %]">[% loc('Edit') %]</a></td>
+ </tr>
+[%- END -%]
diff --git a/templates/web/base/admin/questionnaire.html b/templates/web/base/admin/questionnaire.html
new file mode 100644
index 000000000..680e0d214
--- /dev/null
+++ b/templates/web/base/admin/questionnaire.html
@@ -0,0 +1,30 @@
+[% INCLUDE 'admin/header.html' title=loc('Survey Results') %]
+
+<table border="1">
+ <tr>
+ <th>[% loc('Reported before') %]</th>
+ <th>[% loc('Not reported before') %]</th>
+ </tr>
+ [% IF questionnaires.total > 0 %]
+ <tr>
+ <td>[% questionnaires.1 %] ([% 100 * questionnaires.1 / questionnaires.total | format('%.1f') %]%)</td>
+ <td>[% questionnaires.0 %] ([% 100 * questionnaires.0 / questionnaires.total | format('%.1f') %]%)</td>
+ </tr>
+ [% ELSE %]
+ <tr>
+ <td>[% loc('n/a') %]</td>
+ <td>[% loc('n/a') %]</td>
+ </tr>
+ [% END %]
+</table>
+
+<h2>[% loc('Problem state change based on survey results') %]</h2>
+
+<table>
+<tr><th>[% loc('Old state') %]</th><th>[% loc('New state') %]</th><th>[% loc('Total') %]</th></tr>
+[% WHILE ( s = state_changes.next ) %]
+<tr><td>[% s.old_state %]</td><td>[% s.new_state %]</td><td>[% s.get_column('c') %] ([% 100 * s.get_column('c') / state_changes_count | format('%.1f') %]%)</td></tr>
+[% END %]
+</table>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/report_blocks.html b/templates/web/base/admin/report_blocks.html
new file mode 100644
index 000000000..c2cffc352
--- /dev/null
+++ b/templates/web/base/admin/report_blocks.html
@@ -0,0 +1,42 @@
+[% BLOCK value_or_nbsp -%]
+ [%- IF value %][% value | html %][% ELSE %]&nbsp;[% END %]
+[%- END %]
+
+[% BLOCK format_time -%]
+ [%- IF time %][% time.ymd %]&nbsp;[% time.hms %][% ELSE %][% no_time || '&nbsp;' %][% END %][% no_time = '' %]
+[%- END %]
+
+[% BLOCK abuse_button -%]
+[% IF allowed_pages.abuse_edit -%]
+[% IF email_in_abuse %]<small>[% loc('(Email in abuse table)') %]</small>[% ELSE %]<input type="submit" name="banuser" value="[% loc('Ban email address') %]" />[% END %]
+[%- END %]
+[%- END %]
+
+[% BLOCK flag_button -%]
+[% IF user.flagged || user_flagged %]<input type="submit" name="removeuserflag" value="[% loc('Remove flag') %]">[% ELSE %]<input type="submit" name="flaguser" value="[% loc('Flag user') %]" />[% END %]
+[%- END %]
+
+[%# note: date format here (i.e., dd.mm.YYYY) currently used by Zurich %]
+[% BLOCK format_date -%]
+ [%- IF this_date %]
+ [% 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/base/admin/report_edit.html b/templates/web/base/admin/report_edit.html
new file mode 100644
index 000000000..12560fdf3
--- /dev/null
+++ b/templates/web/base/admin/report_edit.html
@@ -0,0 +1,101 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing problem %d'), problem.id ) -%]
+[% PROCESS 'admin/report_blocks.html' %]
+
+[% status_message %]
+
+<form method="post" action="[% c.uri_for( 'report_edit', problem.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="hidden" name="submit" value="1" >
+<ul>
+ [%- cobrand_data = problem.cobrand_data;
+ cobrand_data = c.data_for_generic_problem IF !problem.cobrand;
+ IF cobrand_data;
+ uri = c.uri_for_email( '/report', problem.id, cobrand_data );
+ ELSE;
+ uri = c.uri_for_email( '/report', problem.id );
+ END;
+ %]
+<li><a href="[% uri %]" class="admin-offsite-link">[% loc('View report on site' )%]</a></li>
+<li><label for='title'>[% loc('Subject:') %]</label> <input size=60 type='text' id='title' name='title' value='[% problem.title | html %]'></li>
+<li><label for='detail'>[% loc('Details:') %]</label>
+<textarea name='detail' id='detail' cols=60 rows=10>[% problem.detail | html %]</textarea></li>
+
+<li>[% loc('Co-ordinates:') %] [% problem.latitude %], [% problem.longitude %]
+( [%
+ SET postcode_safe = problem.postcode | html;
+ tprintf( loc('originally entered: &ldquo;%s&rdquo;'), postcode_safe )
+%],
+[% IF problem.used_map %][% loc('used map') %][% ELSE %][% loc("didn't use map") %][% END %])</li>
+
+<li>[% loc('For council(s):') %] [% IF problem.bodies_str %][% problem.bodies_str %][% ELSE %]<em>[% loc('None' ) %]</em>[% END %] ([% loc('other areas:') %] [% problem.areas | remove('^,') | remove( ',$' ) %])</li>
+[% IF problem.extra.address %]
+<li>[% loc('Property address:') %] [% problem.extra.address | html %]</li>
+[% END %]
+<li><label class="inline" for="state">[% loc('State:') %]</label> <select name="state" id="state">
+[% FOREACH group IN [
+ [ loc('Open'), [
+ [ 'confirmed', loc('Open') ], [ 'investigating', loc('Investigating') ],
+ [ 'planned', loc('Planned') ], [ 'in progress', loc('In progress') ],
+ [ 'action scheduled', loc('Action Scheduled') ],
+ ] ],
+ [ loc('Fixed'), [
+ [ 'fixed', loc('Fixed') ], [ 'fixed - user', loc('Fixed - User') ],
+ [ 'fixed - council', loc('Fixed - Council') ]
+ ] ],
+ [ loc('Closed'), [
+ [ 'unable to fix', loc('Unable to fix') ], [ 'not responsible', loc('Not Responsible') ],
+ [ 'duplicate', loc('Duplicate') ], [ 'closed', loc('Closed') ],
+ [ 'internal referral', loc('Internal referral') ],
+ ] ],
+ [ loc('Hidden'), [
+ [ 'hidden', loc('Hidden') ], [ 'partial', loc('Partial') ], [ 'unconfirmed',loc('Unconfirmed') ]
+ ] ]
+] %]
+ <optgroup label="[% group.0 %]">
+ [% FOREACH state IN group.1 %]
+ <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
+ [% END %]
+ </optgroup>
+[% END %]
+</select></li>
+<li>[% loc('Category:') %] [% problem.category | html %] </li>
+<li><label class="inline" for="anonymous">[% loc('Anonymous:') %]</label> <select name="anonymous" id="anonymous">
+<option [% 'selected ' IF problem.anonymous %]value="1">[% loc('Yes') %]</option>
+<option [% 'selected ' IF !problem.anonymous %]value="0">[% loc('No') %]</option>
+</select></li>
+<li>[% loc('Name:') %] <input type='text' name='name' id='name' value='[% problem.name | html %]'></li>
+<li>[% loc('Email:') %] <input type='text' id='email' name='email' value='[% problem.user.email | html %]'> [% PROCESS abuse_button %] [% PROCESS flag_button user=problem.user %]</li>
+<li>[% loc('Phone:') %] [% problem.user.phone | html %]</li>
+<li>[% loc('Created:') %] [% PROCESS format_time time=problem.created %]</li>
+<li>[% loc('Confirmed:') %] [% PROCESS format_time time=problem.confirmed no_time='-' %]</li>
+<li>[% loc('Sent:') %] [% PROCESS format_time time=problem.whensent %] [% IF problem.state == 'confirmed' %]<input onclick="return confirm('[% loc('You really want to resend?') %]')" type="submit" name="resend" value="[% loc('Resend report') %]">[% END %]</li>
+<li>[% loc('Last update:') %] [% PROCESS format_time time=problem.lastupdate %]</li>
+<li>[% loc('Service:') %] [% problem.service %]</li>
+<li>[% loc('Cobrand:') %] [% problem.cobrand %]</li>
+<li>[% loc('Cobrand data:') %] [% problem.cobrand_data %]</li>
+<li>[% loc('Extra data:') %] [% problem.extra ? 'Yes' : 'No' %]</li>
+<li>[% loc('Going to send questionnaire?') %] [% IF problem.send_questionnaire %][% loc('Yes') %][% ELSE %][% loc('No') %][% END %]</li>
+<li><label class="inline" for="flagged">[% loc('Flagged:') %]</label> <input type="checkbox" name="flagged"[% ' checked' IF problem.flagged %]></li>
+<li><label class="inline" for="non_public">[% loc('Private') %]:</label> <input type="checkbox" name="non_public"[% ' checked' IF problem.non_public %]></li>
+
+[% IF problem.photo %]
+[% photo = problem.get_photo_params %]
+<li><img alt="Photo of this report" height="[% photo.height %]" width="[% photo.width %]" src="[% c.cobrand.base_url %]
+ [%~ IF problem.photo.length == 40 ~%]
+ /photo/[% problem.photo %].temp.jpeg
+ [%~ ELSE ~%]
+ [% photo.url %]
+ [%~ END %]">
+<br>
+<input type="submit" name="rotate_photo" value="[% loc('Rotate Left') %]">
+<input type="submit" name="rotate_photo" value="[% loc('Rotate Right') %]">
+<br>
+<input type="checkbox" id="remove_photo" name="remove_photo" value="1">
+<label class="inline" for="remove_photo">[% loc("Remove photo (can't be undone!)") %]</label></li>
+[% END %]
+</ul>
+<input type="submit" name="Submit changes" value="[% loc('Submit changes') %]" ></form>
+
+[% INCLUDE 'admin/list_updates.html' %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/reports.html b/templates/web/base/admin/reports.html
new file mode 100644
index 000000000..7267dd11d
--- /dev/null
+++ b/templates/web/base/admin/reports.html
@@ -0,0 +1,33 @@
+[% INCLUDE 'admin/header.html' title=loc('Search Reports') %]
+[% 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" value="[% searched | html %]">
+</form>
+
+[% IF problems.size %]
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('ID') %]</th>
+ <th>[% loc('Title') %]</th>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Body') %]</th>
+ <th>[% loc('State') %]</th>
+ <th>*</th>
+ </tr>
+ [% INCLUDE 'admin/problem_row.html' %]
+</table>
+
+[% INCLUDE 'pagination.html', admin = 1, param = 'p' IF pager %]
+
+[% ELSIF searched %]
+
+<div class="fms-admin-warning">
+ [% loc("Searching found no reports.") %]
+</div>
+
+[% END %]
+
+[% INCLUDE 'admin/list_updates.html' %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/stats.html b/templates/web/base/admin/stats.html
new file mode 100644
index 000000000..d143d9f28
--- /dev/null
+++ b/templates/web/base/admin/stats.html
@@ -0,0 +1,97 @@
+[% INCLUDE 'admin/header.html' title=loc('Stats') %]
+
+[% IF show_count %]
+<p>
+<strong>[% tprintf( unconfirmed ? loc( 'All reports between %s and %s' ) : loc( 'Confirmed reports between %s and %s' ), start_date.ymd, end_date.ymd ) | html %]</strong>
+</p>
+[% IF bymonth %]
+<table>
+ <thead>
+ <td style="width: 8em"><strong>[% loc('Year') %]</strong></td>
+ <td style="width: 8em"><strong>[% loc('Month') %]</strong></td>
+ <td><strong>[% loc('Count') %]</strong></td>
+ </thead>
+ [% total = 0 %]
+ [% WHILE ( state = states.next ) %]
+ [% total = total + state.get_column( 'count' ) %]
+ <tr>
+ <td>[% state.get_column( 'c_year') | html %]</td>
+ <td>[% state.get_column( 'c_month') | html %]</td>
+ <td>[% state.get_column( 'count' ) %]</td>
+ </tr>
+ [% END %]
+ <tr>
+ <td colspan="2"><strong>[% loc( 'Total' ) %]</strong></td>
+ <td><strong>[% total %]</strong></td>
+ </tr>
+</table>
+[% ELSE %]
+<table>
+ <thead>
+ <td style="width: 8em"><strong>[% loc('Current state') %]</strong></td>
+ <td><strong>[% loc('Count') %]</strong></td>
+ </thead>
+ [% total = 0 %]
+ [% WHILE ( state = states.next ) %]
+ [% total = total + state.get_column( 'count' ) %]
+ <tr>
+ <td>[% state.state | html %]</td>
+ <td>[% state.get_column( 'count' ) %]</td>
+ </tr>
+ [% END %]
+ <tr>
+ <td><strong>[% loc( 'Total' ) %]</strong></td>
+ <td><strong>[% total %]</strong></td>
+ </tr>
+</table>
+[% END %]
+
+[% IF unconfirmed %]
+ <p>
+ <small>[% loc( 'Note that when including unconfirmed reports we use the date the report was created which may not be in the same month the report was confirmed so the numbers may jump about a little' ) %]</small>
+ </p>
+[% END %]
+[% END %]
+
+[% IF errors %]
+ [% FOREACH error IN errors %]
+ <p class="error">[% error %]</p>
+ [% END %]
+[% END %]
+
+<form method="post" action="[% c.uri_for('stats') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <p>
+ <label for="start_date">[% loc('Start Date:') %]</label><input type="text"
+ placeholder="[% loc('Click here or enter as dd/mm/yyyy') %]" name="start_date" id="start_date"
+ value="[% start_date ? start_date.strftime( '%d/%m/%Y') : '' | html %]" />
+ </p>
+
+ <p>
+ <label for="end_date">[% loc('End Date:') %]</label><input type="text"
+ placeholder="[% loc('Click here or enter as dd/mm/yyyy') %]" name="end_date" id="end_date" size="5"
+ value="[% end_date ? end_date.strftime( '%d/%m/%Y') : '' | html %]" />
+ </p>
+
+ <p>
+ <input type="checkbox" name="unconfirmed" id="unconfirmed"[% unconfirmed ? ' checked' : '' %] /><label class="inline" for="unconfirmed">[% loc('Include unconfirmed reports') %]</label>
+ </p>
+
+ <p>
+ <input type="checkbox" name="bymonth" id="bymonth"[% bymonth ? ' checked' : '' %] /><label class="inline" for="bymonth">[% loc('By Date') %]</label>
+ </p>
+
+ <p>
+ [% loc('Council:') %] <select id='body' name='body'>
+ <option value=''>[% loc('No council') %]</option>
+ [% FOR body IN bodies %]
+ <option value="[% body.id %]"[% ' selected' IF body.id == selected_body %]>[% body.name %]</option>
+ [% END %]
+ </select>
+ </p>
+
+ <p>
+ <input type="submit" name="getcounts" size="30" id="getcounts" value="Get Count" />
+ </p>
+</form>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/timeline.html b/templates/web/base/admin/timeline.html
new file mode 100644
index 000000000..6bf350a58
--- /dev/null
+++ b/templates/web/base/admin/timeline.html
@@ -0,0 +1,44 @@
+[% INCLUDE 'admin/header.html' title=loc('Timeline') %]
+
+[%- BLOCK problem_name %]
+ [%- tprintf(loc('by %s'), problem.name) | html %] &lt;[% problem.user.email | html %]&gt;, '[% problem.title | html %]'
+[%- END %]
+
+[%- date = '' %]
+[% FOREACH moment IN time.keys.sort.reverse %]
+ [%- curdate = time.$moment.0.date.strftime('%A, %e %B %Y') -%]
+ [%- IF date != curdate %]
+ [% '</dl>' IF date %]
+ <h2>[% curdate %]</h2>
+
+ <dl>
+ [%- date = curdate -%]
+ [%- END -%]
+ <dt><b>[% time.$moment.0.date.hms %]</b></dt>
+ <dd>
+ [% FOREACH item IN time.$moment %]
+ [%- SWITCH item.type -%]
+ [% CASE 'problemCreated' %]
+ [%- tprintf(loc('Problem %d created'), item.obj.id) %]; [% PROCESS problem_name problem=item.obj -%]
+ [% CASE 'problemConfirmed' %]
+ [%- tprintf( loc('Problem %s confirmed'), '<a href="' _ c.uri_for_email( '/report', item.obj.id ) _ '" class="admin-offsite-link">' _ item.obj.id _ '</a>') %]; [% PROCESS problem_name problem=item.obj -%]
+ [% CASE 'problemSent' %]
+ [% tprintf(loc("Problem %s sent to council %s"), '<a href="' _ c.uri_for_email( '/report', item.obj.id ) _ '" class="admin-offsite-link">' _ item.obj.id _ '</a>', item.obj.bodies_str ) %]
+ [% CASE 'quesSent' %]
+ [% tprintf(loc("Questionnaire %d sent for problem %d"), item.obj.id, item.obj.problem_id ) %]
+ [% CASE 'quesAnswered' %]
+ [% tprintf(loc("Questionnaire %d answered for problem %d, %s to %s"), item.obj.id, item.obj.problem_id, item.obj.old_state, item.obj.new_state ) %]
+ [% CASE 'update' %]
+ [% name = ( item.obj.name || 'anonymous' ) | html %]
+ [% tprintf(loc("Update %s created for problem %d; by %s"), "<a href='" _ c.uri_for_email( '/report', item.obj.problem_id ) _ "#update_" _ item.obj.id _ "' class='admin-offsite-link'>" _ item.obj.id _ "</a>", item.obj.problem_id, name) %] &lt;[% item.obj.user.email | html %]&gt;
+ [% 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.strftime('%H:%M:%S %e %B %Y') ) %]
+ [%- END %]
+ <br />
+ [%- END %]
+ </dd>
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/update_edit.html b/templates/web/base/admin/update_edit.html
new file mode 100644
index 000000000..5ffce8bc4
--- /dev/null
+++ b/templates/web/base/admin/update_edit.html
@@ -0,0 +1,67 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing update %d'), update.id ) -%]
+[% PROCESS 'admin/report_blocks.html' %]
+
+[% status_message %]
+
+<form method="post" action="[% c.uri_for( 'update_edit', update.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="hidden" name="submit" value="1" >
+<ul>
+ [%- cobrand_data = update.cobrand_data;
+ cobrand_data = c.data_for_generic_update IF !update.cobrand;
+ IF cobrand_data;
+ uri = c.uri_for_email( '/report', update.problem_id, cobrand_data );
+ ELSE;
+ uri = c.uri_for_email( '/report', update.problem_id );
+ END;
+ %]
+<li><a href="[% uri %]#update_[% update.id %]" class="admin-offsite-link">[% loc('View report on site' )%]</a></li>
+
+<li><label for='detail'>[% loc('Text:') %]</label>
+<textarea name='text' id='text' cols=60 rows=10>[% update.text | html %]</textarea></li>
+
+<li><label for="anonymous">[% loc('Anonymous:') %]</label> <select name="anonymous" id="anonymous">
+<option [% 'selected ' IF update.anonymous %]value="1">[% loc('Yes') %]</option>
+<option [% 'selected ' IF !update.anonymous %]value="0">[% loc('No') %]</option>
+</select></li>
+<li><label for="state">[% loc('State:') %]</label> <select name="state" id="state">
+ [% FOREACH state IN [ ['confirmed', loc('Open')], ['hidden', loc('Hidden')], ['unconfirmed',loc('Unconfirmed')] ] %]
+ <option [% 'selected ' IF state.0 == update.state %] value="[% state.0 %]">[% state.1 %]</option>
+ [% END %]
+</select></li>
+<li>[% loc('Name:') %] <input type='text' name='name' id='name' value='[% update.name | html %]'></li>
+<li>[% loc('Email:') %] <input type='text' id='email' name='email' value='[% update.user.email | html %]'>
+[%- IF update.user.from_body && update.user.from_body.id == update.problem.bodies_str %]
+[% ' (' _ tprintf(loc('user is from same council as problem - %d'), update.user.from_body.id ) _')' %]
+[% END -%]
+[%- IF update.user.id == update.problem.user.id %]
+[% ' (' _ loc('user is problem owner') _')' %]
+[% END -%]
+</li>
+[% IF update.problem_state %]
+<li>[% tprintf(loc('Update changed problem state to %s'), update.problem_state) %]</li>
+[% ELSIF update.mark_fixed %]
+<li>[% loc('Update marked problem as fixed') %]</li>
+[% ELSIF update.user.id == update.problem.user.id && update.mark_open %]
+<li>[% loc('Update reopened problem') %]</li>
+[% END %]
+[% PROCESS abuse_button %] [% PROCESS flag_button user=update.user %]</li>
+<li>[% loc('Cobrand:') %] [% update.cobrand %]</li>
+<li>[% loc('Cobrand data:') %] [% update.cobrand_data %]</li>
+<li>[% loc('Created:') %] [% PROCESS format_time time=update.created %]</li>
+
+[% IF update.photo %]
+[% photo = update.get_photo_params %]
+<li><img alt="Photo of this update" height="[% photo.height %]" width="[% photo.width %]" src="[% c.cobrand.base_url %]
+ [%~ IF update.photo.length == 40 ~%]
+ /photo/[% update.photo %].temp.jpeg
+ [%~ ELSE ~%]
+ [% photo.url %]
+ [%~ END ~%]">
+<input type="checkbox" id="remove_photo" name="remove_photo" value="1">
+<label for="remove_photo" class="inline">[% loc("Remove photo (can't be undone!)") %]</label></li>
+[% END %]
+</ul>
+<input type="submit" name="Submit changes" value="[% loc('Submit changes') %]" ></form>
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/user-form.html b/templates/web/base/admin/user-form.html
new file mode 100644
index 000000000..4a57b05a0
--- /dev/null
+++ b/templates/web/base/admin/user-form.html
@@ -0,0 +1,56 @@
+<form method="post" action="[% c.uri_for( 'user_edit', user.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="hidden" name="submit" value="1" >
+
+ [% IF c.cobrand.moniker == 'zurich' AND field_errors.email %]
+ <p class='error'>[% field_errors.email %]</p>
+ [% END %]
+ <ul class="no-bullets">
+ <li>
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "The user's <strong>name</strong> is displayed publicly on reports that have not been marked <em>anonymous</em>.
+ Names are not necessarily unique.")
+ %]
+ </p>
+ </div>
+ [% loc('Name:') %] <input type='text' name='name' id='name' value='[% user.name | html %]'>
+ </li>
+ <li>[% loc('Email:') %] <input type='text' id='email' name='email' value='[% user.email | html %]'></li>
+ <li>
+ <div class="admin-hint">
+ <p>
+ [% loc(
+ "Normal (public) users should not be associated with any <strong>body</strong>.<br>
+ Authorised staff users can be associated with the body they represent.<br>
+ Depending on the implementation, staff users may have access to the dashboard (summary of
+ activity across their body), the ability to hide reports or set special report statuses.")
+ %]
+ </p>
+ </div>
+ [% loc('Body:') %] <select id='body' name='body'>
+ <option value=''>[% loc('No body') %]</option>
+ [% FOR body IN bodies %]
+ <option value="[% body.id %]"[% ' selected' IF body.id == user.from_body.id %]>[% body.name %]</option>
+ [% END %]
+ </li>
+ </select>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <li>
+ <div class="admin-hint">
+ <p>
+ [% loc("Mark users whose behaviour you want to keep a check on as <strong>flagged</strong>.") %]
+ <br>
+ [% tprintf(loc("Flagged users are listed on the <a href='%s'>flagged</a> page."), c.uri_for( 'flagged' )) %]
+ <br>
+ [% loc("You can add an abusive user's email to the abuse list, which automatically hides (and never sends) reports they create.") %]
+ </p>
+ </div>
+
+ [% loc('Flagged:') %] <input type="checkbox" id="flagged" name="flagged"[% user.flagged ? ' checked' : '' %]>
+ </li>
+ [% END %]
+ </ul>
+ <input type="submit" name="Submit changes" value="[% loc('Submit changes') %]" >
+</form>
diff --git a/templates/web/base/admin/user_edit.html b/templates/web/base/admin/user_edit.html
new file mode 100644
index 000000000..d69c873a3
--- /dev/null
+++ b/templates/web/base/admin/user_edit.html
@@ -0,0 +1,8 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing user %d'), user.id ) -%]
+[% PROCESS 'admin/report_blocks.html' %]
+
+[% status_message %]
+
+[% INCLUDE 'admin/user-form.html' %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/admin/users.html b/templates/web/base/admin/users.html
new file mode 100644
index 000000000..db97c7d59
--- /dev/null
+++ b/templates/web/base/admin/users.html
@@ -0,0 +1,49 @@
+[% INCLUDE 'admin/header.html' title=loc('Search Users') %]
+[% PROCESS 'admin/report_blocks.html' %]
+
+<div class="fms-admin-info">
+ [% loc("User search finds matches in users' names and email addresses.") %]
+</div>
+<form method="get" action="[% c.uri_for('users') %]" 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" value="[% searched | html %]">
+</form>
+
+[% IF users.size %]
+
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Email') %]</th>
+ <th>[% loc('Body') %]</th>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <th>[% loc('Flagged') %]</th>
+ [% END %]
+ <th>*</th>
+ </tr>
+[%- FOREACH user IN users %]
+ <tr>
+ <td>[% PROCESS value_or_nbsp value=user.name %]</td>
+ <td><a href="[% c.uri_for( 'reports', search => user.email ) %]">[% PROCESS value_or_nbsp value=user.email %]</a></td>
+ <td>[% PROCESS value_or_nbsp value=user.from_body.name %]</td>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <td>[% user.flagged == 2 ? loc('(Email in abuse table)') : user.flagged ? loc('Yes') : '&nbsp;' %]</td>
+ [% END %]
+ <td>[% IF user.id %]<a href="[% c.uri_for( 'user_edit', user.id ) %]">[% loc('Edit') %]</a>[% END %]</td>
+ </tr>
+[%- END -%]
+</table>
+
+[% ELSIF searched %]
+
+<div class="fms-admin-warning">
+ [% loc("Searching found no users.") %]
+</div>
+
+[% END %]
+
+[% IF NOT searched %]
+<h2>[% loc('Add user') %]</h2>
+[% INCLUDE 'admin/user-form.html', user = '' %]
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/base/alert/_list.html b/templates/web/base/alert/_list.html
new file mode 100644
index 000000000..2ffcfae39
--- /dev/null
+++ b/templates/web/base/alert/_list.html
@@ -0,0 +1,100 @@
+ <input type="hidden" name="type" value="local">
+ <input type="hidden" name="pc" value="[% pc | html %]">
+
+ <p>
+ [% IF pretty_pc %]
+ [% tprintf( loc('Here are the types of local problem alerts for &lsquo;%s&rsquo;.'), pretty_pc ) %]
+ [% END %]
+ [% loc('Select which type of alert you\'d like and click the button for an RSS feed, or enter your email address to subscribe to an email alert.') %]
+ </p>
+
+ [% INCLUDE 'errors.html' %]
+
+ <p>
+ [% loc('The simplest alert is our geographic one:') %]
+ </p>
+
+ <p id="rss_local">
+ <input type="radio" name="feed" id="[% rss_feed_id %]" value="[% rss_feed_id %]"[% IF rss_feed_id == selected_feed || selected_feed == '' %] checked[% END %]>
+ <label for="[% rss_feed_id %]">[% tprintf( loc('Problems within %.1fkm of this location'), population_radius ) %]</label>
+ [% loc('(a default distance which covers roughly 200,000 people)') %] <a href='[% rss_feed_uri %]'>
+ <img src='/i/feed.png' width='16' height='16' title='[% loc('RSS feed of nearby problems') %]' alt='[% loc('RSS feed') %]' border='0'></a>
+ </p>
+
+ <p id="rss_local_alt">
+ [% loc('(alternatively the RSS feed can be customised, within') %]
+ <a href="[% rss_feed_2k %]">2km</a> / <a href="[% rss_feed_5k %]">5km</a> / <a href="[% rss_feed_10k %]">10km</a> / <a href="[% rss_feed_20k %]">20km</a>)
+ </p>
+
+ <p>
+ [% IF c.cobrand.is_council %]
+ Or you can subscribe to an alert for all council problems or one based upon what ward you&rsquo;re in:
+ [% ELSE %]
+ [% loc("Or you can subscribe to an alert based upon what ward or council you&rsquo;re in:") %]
+ [% END %]
+ </p>
+
+ [% IF reported_to_options %]
+ <div id="rss_list">
+ <p><strong>
+ [% loc('Problems within the boundary of:') %]
+ </strong></p>
+ <ul class="plain-list">
+ [% ELSE %]
+ <div><ul id="rss_feed">
+ [% END %]
+
+ [% FOREACH option IN options %]
+ <li[% IF ! (loop.count % 2) %] class="a"[% END %]>
+ <input type="radio" name="feed" id="[% option.id %]" value="[% option.id %]"[% IF option.id == selected_feed %] checked[% END %]>
+ <label class="inline" for="[% option.id %]">[% option.text %]</label>
+ <a href="[% option.uri %]"><img src="/i/feed.png" width="16" height="16"
+title="[% option.rss_text %]" alt="RSS feed" border="0"></a>
+ </li>
+ [% END %]
+</ul>
+ [% IF reported_to_options %]
+ <p><strong>
+ [% loc('Or problems reported to:') %]
+ </strong></p>
+ <ul class="plain-list">
+ [% FOREACH option IN reported_to_options %]
+ <li[% IF ! (loop.count % 2) %] class="a"[% END %]>
+ <input type="radio" name="feed" id="[% option.id %]" value="[% option.id %]"[% IF option.id == selected_feed %] checked[% END %]>
+ <label class="inline" for="[% option.id %]">[% option.text %]</label>
+ <a href="[% option.uri %]"><img src="/i/feed.png" width="16" height="16"
+ title="[% option.rss_text %]" alt="RSS feed" border="0"></a>
+ </li>
+ [% END %]
+ </ul>
+ <p><small>
+ [% loc( 'FixMyStreet sends different categories of problem
+to the appropriate council, so problems within the boundary of a particular council
+might not match the problems sent to that council. For example, a graffiti report
+will be sent to the district council, so will appear in both of the district
+council&rsquo;s alerts, but will only appear in the "Within the boundary" alert
+for the county council.' ) %]
+ </small></p>
+</div>
+<div id="rss_buttons">
+ [% END %]
+
+ <p>
+ <input type="submit" name="rss" value="[% loc('Give me an RSS feed') %]">
+ <p>
+
+ <p id="alert_or">
+ [% loc('or') %]
+ </p>
+
+ [% UNLESS c.user_exists %]
+ <p>
+ [% loc('Your email:') %] <input type="text" id="rznvy" name="rznvy" value="[% rznvy | html %]" size="30">
+ </p>
+ [% END %]
+
+ <p>
+ <input type="submit" name="alert" value="[% loc('Subscribe me to an email alert') %]">
+ </p>
+ </div> <!-- ???? -->
+
diff --git a/templates/web/base/alert/choose.html b/templates/web/base/alert/choose.html
new file mode 100644
index 000000000..312b9f520
--- /dev/null
+++ b/templates/web/base/alert/choose.html
@@ -0,0 +1,14 @@
+[% INCLUDE 'header.html', title => loc('Local RSS feeds and email alerts') %]
+
+<h1>[% loc('Local RSS feeds and email alerts') %]</h1>
+
+[% IF possible_location_matches %]
+ <p>[% loc('We found more than one match for that location. We show up to ten matches, please try a different search if yours is not here.') %]</p>
+ <ul class="pc_alternatives plain-list">
+ [% FOREACH match IN possible_location_matches %]
+ <li><a href="[% choose_target_uri %]?latitude=[% match.latitude | uri %];longitude=[% match.longitude | uri %]">[% match.address | html %]</a></li>
+ [% END %]
+ </ul>
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/alert/index.html b/templates/web/base/alert/index.html
new file mode 100644
index 000000000..e3dead34a
--- /dev/null
+++ b/templates/web/base/alert/index.html
@@ -0,0 +1,53 @@
+[% INCLUDE 'header.html', title = loc('Local RSS feeds and email alerts'), bodyclass = 'twothirdswidthpage alertindex' %]
+
+<h1>[% loc('Local RSS feeds and email alerts') %]</h1>
+
+<p>
+[% IF c.cobrand.is_council %]
+FixMyStreet has a variety of RSS feeds and email alerts for local problems, including
+alerts for all problems within a particular ward, or all problems
+within a certain distance of a particular location.
+[% ELSE %]
+[% loc('FixMyStreet has a variety of RSS feeds and email alerts for local problems, including
+alerts for all problems within a particular ward or council, or all problems
+within a certain distance of a particular location.') %]
+[% END %]
+</p>
+
+[% IF location_error %]
+ <div class="error">[% location_error %]</div>
+[% ELSE %]
+ [% INCLUDE 'errors.html' %]
+[% END %]
+
+<p>
+[% IF c.cobrand.is_council %]
+To find out what local alerts we have for you, please enter your [% c.cobrand.council_area %] postcode or street name and area:
+[% ELSE %]
+[% loc('To find out what local alerts we have for you, please enter your postcode or street name and area' ) %]
+[% END %]
+</p>
+<form method="get" action="/alert/list" class="full-width">
+ <fieldset>
+ <div class="form-txt-submit-box">
+ <input type="text" name="pc" value="[% pc | html %]" placeholder="[% tprintf(loc('e.g. ‘%s’ or ‘%s’'), c.cobrand.example_places) %]">
+ <input class="green-btn" type="submit" value="[% loc('Go') %]">
+ </div>
+ </fieldset>
+</form>
+
+[% IF photos.size %]
+<div class="sticky-sidebar" id="alert_recent">
+ <aside>
+ <h2>[% loc('Some photos of recent reports') %]</h2>
+ [% FOREACH p IN photos;
+ photo = p.get_photo_params;
+ %]
+ <a href="/report/[% p.id %]"><img border="0" height="100"
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ [% END %]
+ </aside>
+</div>
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/alert/list.html b/templates/web/base/alert/list.html
new file mode 100644
index 000000000..447bfcd76
--- /dev/null
+++ b/templates/web/base/alert/list.html
@@ -0,0 +1,41 @@
+[%
+ IF pretty_pc;
+ title = tprintf( loc("Local RSS feeds and email alerts for ‘%s’"), pretty_pc );
+ ELSE;
+ title = loc('Local RSS feeds and email alerts');
+ END;
+%]
+
+[% INCLUDE 'header.html', title = title, bodyclass = 'twothirdswidthpage' %]
+
+[% IF pretty_pc %]
+ [%
+ pretty_pc = pretty_pc | html | replace(' ', '&nbsp;');
+ title = tprintf( loc("Local RSS feeds and email alerts for ‘%s’"), pretty_pc );
+ %]
+[% END %]
+
+
+<h1>[% title %]</h1>
+
+<form id="alerts" name="alerts" method="post" action="/alert/subscribe">
+
+ [% IF photos.size %]
+ <div id="alert_photos" class="sticky-sidebar">
+ <aside>
+ <h2>[% loc('Photos of recent nearby reports') %]</h2>
+ [% FOREACH p IN photos;
+ photo = p.get_photo_params;
+ %]
+ <a href="/report/[% p.id %]"><img border="0" height="100"
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ [% END %]
+ </aside>
+ </div>
+ [% END %]
+
+ [% INCLUDE 'alert/_list.html' %]
+
+</form>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/alert/updates.html b/templates/web/base/alert/updates.html
new file mode 100644
index 000000000..5efc41bac
--- /dev/null
+++ b/templates/web/base/alert/updates.html
@@ -0,0 +1,21 @@
+[% title = loc('Local RSS feeds and email alerts') %]
+
+[% INCLUDE 'header.html', title => title %]
+
+
+[% INCLUDE 'errors.html' %]
+
+<p>
+[% loc('Receive email when updates are left on this problem.') %]
+</p>
+
+<form action="/alert/subscribe" method="post">
+<label class="n" for="alert_rznvy">[% loc('Email:') %]</label>
+<input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30">
+<input type="hidden" name="id" value="[% problem_id | html %]">
+<input type="hidden" name="type" value="updates">
+<input type="submit" value="[% loc('Subscribe') %]">
+</form>
+
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/around/_report_banner.html b/templates/web/base/around/_report_banner.html
new file mode 100755
index 000000000..024fe08d9
--- /dev/null
+++ b/templates/web/base/around/_report_banner.html
@@ -0,0 +1,10 @@
+<p id="text_map" class="banner">
+ [% loc( 'To <strong>report a problem</strong>, click on the map at the correct location.' ) %]
+ [%
+ tprintf(
+ loc("<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this step</a>.</small>"),
+ url_skip
+ )
+ %]
+ <span id="text_map_arrow"></span>
+</p>
diff --git a/templates/web/base/around/_updates.html b/templates/web/base/around/_updates.html
new file mode 100755
index 000000000..8110a6c7c
--- /dev/null
+++ b/templates/web/base/around/_updates.html
@@ -0,0 +1,12 @@
+<h1>[% loc('Problems in this area') %]</h1>
+
+<p id="alert_links_area">
+ <a id="email_alert" rel="nofollow" href="[% email_url | html %]">
+ [%- loc('Email me new local problems') -%]
+</a> |
+ <a href="[% rss_url | html %]" id="rss_alert">
+ <span>[% rss_alt %]</span>
+ <img src="/i/feed.png" width="16" height="16" title="[% rss_title %]" alt="[% rss_alt %]" border="0" style="vertical-align: top">
+ </a>
+</p>
+
diff --git a/templates/web/base/around/around_index.html b/templates/web/base/around/around_index.html
new file mode 100644
index 000000000..087abf65f
--- /dev/null
+++ b/templates/web/base/around/around_index.html
@@ -0,0 +1,24 @@
+[% INCLUDE 'header.html', title => loc('Reporting a problem'), bodyclass = 'mappage' %]
+
+<form action="[% c.uri_for('/around') %]" method="get" name="mapForm" id="mapForm">
+ <div id="side-form">
+ <div id="report-a-problem-main">
+ [% INCLUDE 'around/postcode_form.html' %]
+
+ [% IF location_error %]
+ [% INCLUDE 'around/location_error.html' %]
+ [% END %]
+
+ [% IF possible_location_matches %]
+ <p>[% loc('We found more than one match for that location. We show up to ten matches, please try a different search if yours is not here.') %]</p>
+ <ul class="pc_alternatives">
+ [% FOREACH match IN possible_location_matches %]
+ <li><a href="/around?latitude=[% match.latitude | uri %];longitude=[% match.longitude | uri %]">[% match.address | html %]</a></li>
+ [% END %]
+ </ul>
+ [% END %]
+ </div>
+ </div>
+</form>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/around/around_map_list_items.html b/templates/web/base/around/around_map_list_items.html
new file mode 100644
index 000000000..da75561b5
--- /dev/null
+++ b/templates/web/base/around/around_map_list_items.html
@@ -0,0 +1,18 @@
+[% IF around_map.size %]
+ [% FOREACH p IN around_map %]
+
+ [% dist = tprintf("%.1f", (p.distance || 0) ) %]
+
+ <li>
+ <a href="[% c.uri_for('/report', p.problem.id ) %]">[% p.problem.title | html %]</a>
+ <small>[% prettify_dt( p.problem.confirmed, 1 ) %], [% dist %]km</small>
+ [% IF p.problem.is_fixed %]
+ <small>[% loc('(fixed)') %]</small>
+ [% ELSIF p.problem.is_closed %]
+ <small>[% loc('(closed)') %]</small>
+ [% END %]
+ </li>
+ [% END %]
+[% ELSE %]
+ <li>[% loc('No problems found.') %]</li>
+[% END %]
diff --git a/templates/web/base/around/display_location.html b/templates/web/base/around/display_location.html
new file mode 100755
index 000000000..c8c6935de
--- /dev/null
+++ b/templates/web/base/around/display_location.html
@@ -0,0 +1,110 @@
+[%
+
+ rss_alt = loc('RSS feed');
+ rss_title = loc('RSS feed of recent local problems');
+
+ rss_url
+ = pc
+ ? c.uri_for( "/rss/pc", pc )
+ : c.uri_for( "/rss/l/$short_latitude,$short_longitude" );
+
+ email_url = c.uri_for(
+ '/alert/list',
+ {
+ lat => short_latitude,
+ lon => short_longitude,
+ feed => "local:$short_latitude:$short_longitude",
+ }
+ );
+
+ url_skip = c.uri_for(
+ '/report/new',
+ {
+ pc => pc
+ latitude => short_latitude,
+ longitude => short_longitude,
+ skipped => 1,
+ }
+ );
+
+ PROCESS "maps/${map.type}.html";
+
+ SET rss = [ loc('Recent local problems, FixMyStreet'), rss_url ] IF c.cobrand.moniker != 'emptyhomes';
+ INCLUDE 'header.html',
+ title => loc('Viewing a location')
+ bodyclass => 'mappage',
+ robots => 'noindex,nofollow';
+
+ allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_body);
+%]
+
+[% IF allow_creation %]
+<form action="[% c.uri_for('/report/new') %]" method="post" name="mapForm" id="mapForm" enctype="multipart/form-data" class="validate">
+ [% IF c.req.params.map_override %]
+ <input type="hidden" name="map_override" value="[% c.req.params.map_override | html %]">
+ [% END %]
+ <input type="hidden" name="pc" value="[% pc | html %]">
+
+ <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% short_latitude | html %]">
+ <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% short_longitude | html %]">
+[% END %]
+
+ [% map_html %]
+
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ <p id='sub_map_links'>
+ [% IF c.cobrand.moniker == 'zurich' %]
+ <a class="hidden-nojs" id="map_layer_toggle" href="">Stadtplan</a>
+ [% END %]
+ [% IF c.req.params.no_pins %]
+ <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 0 } ) %]'>[% loc('Show pins') %]</a>
+ [% ELSE %]
+ <a id='hide_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => 1 } ) %]'>[% loc('Hide pins') %]</a>
+ [% END %]
+ [% IF c.cobrand.country == 'GB' || c.cobrand.country == 'NO' %]
+ <span class="hidden">|</span>
+ [% IF c.req.params.all_pins %]
+ <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => undef } ) %]'>[% loc('Hide old') %]</a>
+ [% ELSE %]
+ <a id='all_pins_link' rel='nofollow' href='[% c.uri_with( { no_pins => undef, all_pins => 1 } ) %]'>[% loc('Show old') %]</a>
+ [% END %]
+ [% END %]
+ </p>
+ [% END %]
+
+ </div>
+
+
+
+
+ <div id="side">
+
+ [% IF allow_creation %]
+ [% INCLUDE 'around/_report_banner.html' %]
+ [% TRY %][% INCLUDE 'around/extra_text.html' %][% CATCH file %][% END %]
+ [% END %]
+
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ [% INCLUDE 'around/_updates.html' %]
+
+ <section class="full-width">
+ [% INCLUDE "around/tabbed_lists.html" %]
+ </section>
+ [% END %]
+ </div>
+
+ [% IF allow_creation %]
+ <div style="display:none" id="side-form">
+ [% INCLUDE "report/new/fill_in_details_form.html"
+ js = 1,
+ report.used_map = 1
+ report.name = c.user.name
+ %]
+ </div>
+ [% END %]
+
+[% IF allow_creation %]
+</form>
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/around/location_error.html b/templates/web/base/around/location_error.html
new file mode 100644
index 000000000..9b907b64b
--- /dev/null
+++ b/templates/web/base/around/location_error.html
@@ -0,0 +1 @@
+<p class="error">[% location_error %]</p>
diff --git a/templates/web/base/around/on_map_list_items.html b/templates/web/base/around/on_map_list_items.html
new file mode 100644
index 000000000..70a071406
--- /dev/null
+++ b/templates/web/base/around/on_map_list_items.html
@@ -0,0 +1,15 @@
+[% IF on_map.size %]
+ [% FOREACH p IN on_map %]
+ <li>
+ <a href="[% c.uri_for('/report', p.id ) %]">[% p.title | html %]</a>
+ <small>[% prettify_dt( p.confirmed, 1 ) %]</small>
+ [% IF p.is_fixed %]
+ <small>[% loc('(fixed)') %]</small>
+ [% ELSIF p.is_closed %]
+ <small>[% loc('(closed)') %]</small>
+ [% END %]
+ </li>
+ [% END %]
+[% ELSE %]
+ <li>[% loc('No problems have been reported yet.') %]</li>
+[% END %]
diff --git a/templates/web/base/around/postcode_form.html b/templates/web/base/around/postcode_form.html
new file mode 100644
index 000000000..f58d7285d
--- /dev/null
+++ b/templates/web/base/around/postcode_form.html
@@ -0,0 +1,13 @@
+[%
+ question = c.cobrand.enter_postcode_text || loc('Enter a nearby street name and area');
+%]
+
+<form action="[% c.uri_for('/around') %]" method="get" name="postcodeForm" id="postcodeForm">
+ <label for="pc">[% question %]:</label>
+ <span><input type="text" name="pc" value="[% pc | html %]" id="pc" size="10" maxlength="200">
+ <input type="submit" value="[% loc('Go') %]" id="sub">
+ </span>
+ [% IF partial_token %]
+ <input type="hidden" name="partial" value="[% partial_token.token %]">
+ [% END %]
+</form>
diff --git a/templates/web/base/around/tabbed_lists.html b/templates/web/base/around/tabbed_lists.html
new file mode 100755
index 000000000..4ad7b35fc
--- /dev/null
+++ b/templates/web/base/around/tabbed_lists.html
@@ -0,0 +1,23 @@
+<div id="nearby_lists">
+
+ <h2>[% loc('Reports on and around the map') %]</h2>
+
+ <ul id="current">
+ [% INCLUDE "around/on_map_list_items.html" %]
+ </ul>
+
+ <h2>
+ [%
+ tprintf(
+ loc( 'Closest nearby problems <small>(within&nbsp;%skm)</small>' ),
+ distance
+ )
+ %]
+ </h2>
+
+ <ul id="current_near">
+ [% INCLUDE "around/around_map_list_items.html" %]
+ </ul>
+
+</div>
+
diff --git a/templates/web/base/auth/change_password.html b/templates/web/base/auth/change_password.html
new file mode 100644
index 000000000..c10560c3e
--- /dev/null
+++ b/templates/web/base/auth/change_password.html
@@ -0,0 +1,39 @@
+[% INCLUDE 'header.html', title = loc('Change Password') %]
+
+<h1>[% loc('Change Password') %]</h1>
+
+[% IF password_changed %]
+ <p id="fixed">[% loc('Your password has been changed') %]</p>
+[% END %]
+
+
+<form action="[% c.uri_for('change_password') %]" method="post" name="change_password" class="fieldset">
+
+ [% IF password_error;
+
+ errors = {
+ missing => loc('Please enter a password'),
+ mismatch => loc('The passwords do not match'),
+ other => loc('Please check the passwords and try again'),
+ };
+
+ loc_password_error = errors.$password_error || errors.other; %]
+ <div class="form-error">[% loc_password_error %]</div>
+ [% END %]
+
+ <div class="form-field">
+ <label for="new_password">[% loc('Password:') %]</label>
+ <input type="password" name="new_password" value="[% new_password | html %]">
+ </div>
+ <div class="form-field">
+ <label for="confirm">[% loc('Again:') %]</label>
+ <input type="password" name="confirm" value="[% confirm | html %]">
+ </div>
+ <div class="checkbox">
+ <input type="submit" value="[% loc('Change Password') %]">
+ </div>
+
+</form>
+
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/auth/general.html b/templates/web/base/auth/general.html
new file mode 100644
index 000000000..f5e2e423f
--- /dev/null
+++ b/templates/web/base/auth/general.html
@@ -0,0 +1,84 @@
+[% INCLUDE 'header.html', title = loc('Sign in or create an account') %]
+
+<h1>[% loc('Sign in') %]</h1>
+
+<form action="[% c.uri_for() %]" method="post" name="general_auth" class="validate">
+<input type="hidden" name="r" value="[% c.req.params.r | html %]">
+
+ [% 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 %]
+
+ [% 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 %]
+
+ <div class="form-field">
+ <label class="n" for="email">[% loc('Your email address:') %]</label>
+ <input type="email" class="required email" size="30" id="email" name="email" value="[% email | html %]">
+ </div>
+
+<div id="form_sign_in">
+ <h3>[% loc("Do you have a FixMyStreet password?") %]</h3>
+
+ <div id="form_sign_in_yes">
+
+ <p>
+ <label class="n" for="password_sign_in">[% loc('<strong>Yes</strong> I have a password') %]</label>
+ <input type="password" name="password_sign_in" id="password_sign_in" value="">
+ </p>
+
+ <p>
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="n" for="remember_me">
+ [% loc('Keep me signed in on this computer') %]
+ </label>
+ </p>
+
+ <p>
+ <input type="submit" name="sign_in" value="[% loc('Sign in') %]">
+ </p>
+
+ </div>
+ <div id="form_sign_in_no">
+
+ <p>[% loc('<strong>No</strong>, I do not, let me sign in by email:') %]</p>
+
+ <div class="fieldset">
+ <div class="form-field">
+ <label for="name">[% loc('Your name:') %]</label>
+ <input type="text" name="name" value="">
+ </div>
+
+ <div class="form-field">
+ <label for="password_register">[% loc('Enter a new password:') %]</label>
+ <input type="password" name="password_register" id="password_register" value="">
+ </div>
+ </div>
+
+ <p><small>Providing a name and password is optional, but doing so
+ will allow you to more easily report problems, leave updates and
+ manage your reports.</small></p>
+
+ <p>
+ <input type="submit" name="email_sign_in" value="[% loc('Sign in by email') %]">
+ </p>
+
+ </div>
+
+</div>
+
+</form>
+
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/auth/sign_out.html b/templates/web/base/auth/sign_out.html
new file mode 100644
index 000000000..571e13f9f
--- /dev/null
+++ b/templates/web/base/auth/sign_out.html
@@ -0,0 +1,7 @@
+[% INCLUDE 'header.html', title = loc('Sign out'), bodyclass = 'fullwidthpage' %]
+
+<h1>[% loc('You have been signed out') %]</h1>
+
+<p>[% tprintf( loc('Please feel free to <a href="%s">sign in again</a>, or go back to the <a href="/">front page</a>.'), c.uri_for('/auth') ) %]</p>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/auth/token.html b/templates/web/base/auth/token.html
new file mode 100644
index 000000000..361d4fbd5
--- /dev/null
+++ b/templates/web/base/auth/token.html
@@ -0,0 +1,26 @@
+[% INCLUDE 'header.html', title => loc('Confirm account') %]
+
+[% IF token_not_found %]
+
+<h1>[% loc('Error') %]</h1>
+
+<p>
+ [% loc('We have not been able to confirm your account - sorry.') %]
+ [% loc('This may be because the link is too old or already used, or the address was not copied correctly.') %]
+</p>
+
+[% ELSE %]
+
+<h1>[% loc('Please check your email') %]</h1>
+
+<p>[% loc("We have sent you an email containing a link to confirm your account.") %]</p>
+
+[% IF c.cobrand.moniker != 'zurich' %]
+<p>[% loc("The confirmation email <strong>may</strong> take a few minutes to arrive &mdash; <em>please</em> be patient.") %]</p>
+[% END %]
+
+<p>[% loc("If you use web-based email or have 'junk mail' filters, you may wish to check your bulk/spam mail folders: sometimes, our messages are marked that way.") %]</p>
+
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/common_header_tags.html b/templates/web/base/common_header_tags.html
new file mode 100644
index 000000000..cd6b4ab3a
--- /dev/null
+++ b/templates/web/base/common_header_tags.html
@@ -0,0 +1,41 @@
+[% USE date %][% USE Math %]
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+
+<meta name="cobrand" content="[% c.cobrand.moniker %]">
+
+<script type="text/javascript" src="[% start %]/js/validation_rules.js?[% Math.int( date.now / 3600 ) %]"></script>
+<script type="text/javascript" src="[% start %]/js/translation_strings.[% lang_code %].js?[% Math.int( date.now / 3600 ) %]"></script>
+
+<script type="text/javascript" src="[% start %]/jslib/jquery-1.7.2.min.js"></script>
+<script src="[% start %][% version('/js/jquery.validate.min.js') %]" type="text/javascript" charset="utf-8"></script>
+
+<script type="text/javascript" src="[% start %][% version('/js/geo.min.js') %]"></script>
+<script type="text/javascript" src="[% start %][% version('/js/fixmystreet.js') %]"></script>
+<script type="text/javascript" src="[% start %][% version(js_override || '/js/fixmystreet-old-box.js') %]"></script>
+
+[% IF admin %]
+ <script src="[% start %]/js/jquery-ui/js/jquery-ui-1.10.3.custom.min.js"></script>
+ <link rel="stylesheet" href="[% start %]/js/jquery-ui/css/smoothness/jquery-ui-1.10.3.custom.min.css" />
+ <script type="text/javascript" src="[% start %][% version('/js/fixmystreet-admin.js') %]"></script>
+[% END %]
+
+[% map_js %]
+
+[% IF category_extras_json && category_extras_json != '{}' %]
+<script type="text/javascript">
+ category_extras = [% category_extras_json %];
+</script>
+[% END %]
+
+[% IF robots %]
+ <meta name="robots" content="[% robots %]">
+[% ELSIF c.config.STAGING_SITE %]
+ <meta name="robots" content="noindex,nofollow">
+[% END %]
+
+[% INCLUDE 'header_rss.html' %]
+
+<title>
+ [% "$title :: " | html IF title %]
+ [% site_title || 'FixMyStreet' %]
+</title>
diff --git a/templates/web/base/contact/blurb.html b/templates/web/base/contact/blurb.html
new file mode 100644
index 000000000..22c9a3cef
--- /dev/null
+++ b/templates/web/base/contact/blurb.html
@@ -0,0 +1,9 @@
+<p>
+[% loc('Please do <strong>not</strong> report problems through this form; messages go to
+the team behind FixMyStreet, not a council. To report a problem,
+please <a href="/">go to the front page</a> and follow the instructions.') %]
+</p>
+
+<p>
+[% tprintf( loc("We'd love to hear what you think about this site. Just fill in the form, or send an email to <a href='mailto:%s'>%s</a>:"), contact_email, contact_email) %]
+</p>
diff --git a/templates/web/base/contact/index.html b/templates/web/base/contact/index.html
new file mode 100644
index 000000000..8789fd03e
--- /dev/null
+++ b/templates/web/base/contact/index.html
@@ -0,0 +1,101 @@
+[% INCLUDE 'header.html',
+ title = loc('Contact Us')
+ robots = 'noindex,nofollow'
+%]
+
+<h1>[% loc('Contact the team') %]</h1>
+
+<form method="post" action="/contact/submit" class="validate">
+
+[% INCLUDE 'errors.html' %]
+
+[% IF update %]
+
+ <p>
+ [% loc('You are reporting the following update for being abusive, containing personal information, or similar:') %]
+ </p>
+
+ <blockquote>
+ <p>
+ [% IF update.anonymous %]
+ [% 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 ) ) | html %]
+ [% END %]
+ </p>
+
+ <p>
+ [% update.text | html %]
+ </p>
+
+ </blockquote>
+ <input type="hidden" name="update_id" value="[% update.id %]">
+ <input type="hidden" name="id" value="[% update.problem_id %]">
+
+[% ELSIF problem %]
+ <p>
+ [% loc('You are reporting the following problem report for being abusive, containing personal information, or similar:') %]
+ </p>
+
+ <blockquote>
+ <h2>[% problem.title_safe | html %]</h2>
+
+ <p>
+ [% IF problem.anonymous %]
+ [% 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 ) ) | html %]
+ [% END %]
+ </p>
+
+ <p>
+ [% problem.detail | html %]
+ </p>
+
+ </blockquote>
+ <input type="hidden" name="id" value="[% problem.id %]">
+
+[% ELSE %]
+
+ [% INCLUDE 'contact/blurb.html' %]
+
+[% END %]
+
+[% IF field_errors.name %]
+ <div class="form-error">[% field_errors.name %]</div>
+[% END %]
+<div class="form-field">
+<label for="form_name">[% loc('Your name:') %]</label>
+<input type="text" class="required" name="name" id="form_name" value="[% form_name | html %]" size="30"></div>
+
+
+[% IF field_errors.em %]
+ <div class="form-error">[% field_errors.em %]</div>
+[% END %]
+<div class="form-field">
+<label for="form_email">[% loc('Your&nbsp;email:') %]</label>
+<input type="text" class="required email" name="em" id="form_email" value="[% em | html %]" size="30"></div>
+
+[% IF field_errors.subject %]
+ <div class="form-error">[% field_errors.subject %]</div>
+[% END %]
+<div class="form-field">
+<label for="form_subject">[% loc('Subject:') %]</label>
+<input type="text" class="required" name="subject" id="form_subject" value="[% subject | html %]" size="30"></div>
+
+[% INCLUDE 'contact/who.html' %]
+
+[% IF field_errors.message %]
+ <div class="form-error">[% field_errors.message %]</div>
+[% END %]
+<div class="form-field">
+<label for="form_message">[% loc('Message:') %]</label>
+
+<textarea class="required" name="message" id="form_message" rows="7" cols="50">[% message | html %]</textarea></div>
+<div class="checkbox"><input type="submit" value="[% loc('Post') %]"></div>
+
+</form>
+
+[% TRY %][% INCLUDE 'contact/address.html' %][% CATCH file %][% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/contact/submit.html b/templates/web/base/contact/submit.html
new file mode 100644
index 000000000..3845e9210
--- /dev/null
+++ b/templates/web/base/contact/submit.html
@@ -0,0 +1,20 @@
+[% INCLUDE 'header.html', title = loc('Contact Us') %]
+
+<h1>[% loc('Contact the team') %]</h1>
+
+[% IF success %]
+
+ <p>
+ [% loc("Thanks for your feedback. We'll get back to you as soon as we can!") %]
+ </p>
+ [% display_crosssell_advert( em, form_name, 'emailunvalidated', 1 ) %]
+
+[% ELSE %]
+
+ <p>
+ [% tprintf( loc('Failed to send message. Please try again, or <a href="mailto:%s">email us</a>.'), contact_email ) %]
+ </p>
+
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/contact/who.html b/templates/web/base/contact/who.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/contact/who.html
diff --git a/templates/web/base/dashboard/index.html b/templates/web/base/dashboard/index.html
new file mode 100644
index 000000000..b3e1e8426
--- /dev/null
+++ b/templates/web/base/dashboard/index.html
@@ -0,0 +1,172 @@
+[% extra_css = BLOCK %]
+ <link rel="stylesheet" href="[% version('/cobrands/fixmystreet/dashboard.css') %]">
+[% END %]
+
+[%
+ INCLUDE 'header.html'
+ title = loc('Dashboard')
+ robots = 'noindex, nofollow'
+ bodyclass = 'fullwidthpage'
+%]
+
+<form>
+
+<hgroup>
+ <h2>Reports, Statistics and Actions for</h2>
+ <h1>[% council.name %]</h1>
+</hgroup>
+
+<div class="filters">
+ [% IF c.cobrand.moniker != 'fixmybarangay' %]
+ <p>
+ <label for="ward">Ward:</label>
+ <select name="ward"><option value=''>All</option>
+ [% FOR w IN children.values.sort('name') %]
+ <option value="[% w.id %]"[% ' selected' IF w.id == ward %]>[% w.name %]</option>
+ [% END %]
+ </select>
+ </p>
+ [% END %]
+
+ <p>
+ <label for="category">Report category:</label>
+ <select name="category"><option value=''>All</option>
+ [% FOR cat_op IN category_options %]
+ <option value='[% cat_op | html %]'[% ' selected' IF category == cat_op %]>[% cat_op | html %]</option>
+ [% END %]
+ </select>
+ </p>
+
+ <p>
+ <input type="submit" value="Look up">
+ </p>
+
+ <br clear="all" />
+</div>
+
+
+<table width="100%" id="overview">
+ <tr>
+ <th>&nbsp;</th>
+ <th scope="col"><abbr title="Week To Date">WTD</abbr></th>
+ <th scope="col">Last 7 days</th>
+ <th scope="col">Last 4 weeks</th>
+ <th scope="col">YTD</th>
+ </tr>
+
+ [%
+ rows = {
+ '0' => [ "total", "Total reports received" ]
+ '1' => [ "fixed - council", "Council has marked as fixed" ]
+ '2' => [ "fixed_user", "User has marked as fixed" ]
+ };
+ FOR row IN rows %]
+ <tr id="[% row.value.0.replace('[^\w]+', '_' ) %]">
+ <th scope="row">[% row.value.1 %]</th>
+ <td>[% problems.wtd.${row.value.0} %]</td>
+ <td>[% problems.week.${row.value.0} %]</td>
+ <td>[% problems.weeks.${row.value.0} %]</td>
+ <td>[% problems.ytd.${row.value.0} %]</td>
+ </tr>
+ [% END %]
+
+ <tr class='subtotal' id="total_fixed">
+ <th scope="row">Total marked as fixed</th>
+ <td>[% problems.wtd.${"fixed - council"} + problems.wtd.fixed_user %]</td>
+ <td>[% problems.week.${"fixed - council"} + problems.week.fixed_user %]</td>
+ <td>[% problems.weeks.${"fixed - council"} + problems.weeks.fixed_user %]</td>
+ <td>[% problems.ytd.${"fixed - council"} + problems.ytd.fixed_user %]</td>
+ </tr>
+
+ [%
+ rows = {
+ '0' => [ "in progress", "Council has marked as in progress" ]
+ '1' => [ "action scheduled", "Council has marked as planned" ]
+ '2' => [ "investigating", "Council has marked as investigating" ]
+ '3' => [ "closed", "Council has marked as closed" ]
+ };
+ wtd = 0, week = 0, weeks = 0, ytd = 0;
+ FOR row IN rows %]
+ <tr id="[% row.value.0.replace('[^\w]+', '_' ) %]">
+ <th scope="row">[% row.value.1 %]</th>
+ <td>[% problems.wtd.${row.value.0} %]</td>
+ <td>[% problems.week.${row.value.0} %]</td>
+ <td>[% problems.weeks.${row.value.0} %]</td>
+ <td>[% problems.ytd.${row.value.0} %]</td>
+ </tr>
+ [% END %]
+
+ <tr class='subtotal' id="marked">
+ <th scope="row">Total marked</th>
+ <td>[% problems.wtd.${"in progress"} + problems.wtd.${"action scheduled"} +
+ problems.wtd.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.week.${"in progress"} + problems.week.${"action scheduled"} +
+ problems.week.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.weeks.${"in progress"} + problems.weeks.${"action scheduled"} +
+ problems.weeks.investigating + problems.wtd.closed %]</td>
+ <td>[% problems.ytd.${"in progress"} + problems.ytd.${"action scheduled"} +
+ problems.ytd.investigating + problems.wtd.closed %]</td>
+ </tr>
+
+ <tr id="avg_fixed">
+ <th scope="row">Average time to council marking fixed (days)</th>
+ <td>[% problems.wtd.time_to_fix %]</td>
+ <td>[% problems.week.time_to_fix %]</td>
+ <td>[% problems.weeks.time_to_fix %]</td>
+ <td>[% problems.ytd.time_to_fix %]</td>
+ </tr>
+
+ <tr id="avg_marked">
+ <th scope="row">Average time to first council state change (days)</th>
+ <td>[% problems.wtd.time_to_mark %]</td>
+ <td>[% problems.week.time_to_mark %]</td>
+ <td>[% problems.weeks.time_to_mark %]</td>
+ <td>[% problems.ytd.time_to_mark %]</td>
+ </tr>
+
+ <tr class='subtotal' id="not_marked">
+ <th scope="row">Total not marked</th>
+ <td>[% problems.wtd.not_marked %]</td>
+ <td>[% problems.week.not_marked %]</td>
+ <td>[% problems.weeks.not_marked %]</td>
+ <td>[% problems.ytd.not_marked %]</td>
+ </tr>
+
+</table>
+
+<h2>Reports</h2>
+
+ </select>
+<p>Report state: <select name="state">
+<option value=''>All</option>
+ [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
+ loc('Investigating')], ['action scheduled', loc('Planned')], ['in progress',
+ loc('In Progress')], ['closed', loc('Closed')], ['fixed', loc('Fixed')] ] %]
+ <option [% 'selected ' IF state.0 == q_state %] value="[% state.0 %]">[% state.1 %]</option>
+ [% END %]
+</select>
+<input type="submit" value="Look up">
+<a class="export_as_csv" href="[% c.req.uri_with({ export => 1 }) %]">Export as CSV</a>
+
+<table width="100%" id="reports">
+ <tr>
+ <th scope="col">Less than 7 days old</th>
+ <th scope="col">7-14 days old</th>
+ <th scope="col">14-30 days old</th>
+ </tr>
+ <tr>
+ <td width="34%"><ul>[% INCLUDE list, list = lists.1 %]</ul></td>
+ <td width="33%"><ul>[% INCLUDE list, list = lists.2 %]</ul></td>
+ <td width="33%"><ul>[% INCLUDE list, list = lists.3 %]</ul></td>
+ </tr>
+</table>
+
+</form>
+
+[% INCLUDE 'footer.html' %]
+
+[% BLOCK list %]
+[% FOR p IN list %]
+<li><a href="/report/[% p.id %]">[% p.title | html %]</a> <date>[% p.confirmed.dmy('/') %]</date></li>
+[% END %]
+[% END %]
diff --git a/templates/web/base/debug_footer.html b/templates/web/base/debug_footer.html
new file mode 100644
index 000000000..a1b7fc155
--- /dev/null
+++ b/templates/web/base/debug_footer.html
@@ -0,0 +1,40 @@
+[% IF c.config.STAGING_SITE and c.config.SHOW_DEBUG %]
+
+<hr style="clear: both;">
+
+<ul>
+ <li>cobrand.moniker: [% c.cobrand.moniker %]</li>
+ <li>additional_template_paths: [% additional_template_paths.join(', ') || '--empty--' %]</li>
+ <li>lang_code: [% lang_code %]</li>
+ <li>user.id: [% c.user.id || '--not logged in--' %]</li>
+</ul>
+
+<style type="text/css">
+ #overrides_form {
+ font-size: 80%;
+ }
+ #overrides_form label {
+ float: left;
+ text-align: right;
+ padding-right: 0.5em;
+ width: 12em;
+ }
+
+</style>
+
+<!-- Use a post so that we don't clutter up the url -->
+<form action="" method="post" id="overrides_form" name="overrides_form">
+
+ <label for="_override_clear_all">Clear all overrides:</label>
+ <input type="checkbox" name="_override_clear_all" id="_override_clear_all" value="1"><br>
+
+ [% FOREACH k IN ['cobrand_moniker', 'lang'] %]
+ <label for="override_[% k %]">[% k %]:</label>
+ <input type="text" name="_override_[% k %]" id="override_[% k %]" value="[% c.get_override(k)%]"><br>
+ [% END %]
+
+ <label>&nbsp;</label><input type="submit" value="Change overrides">
+</form>
+
+[% END %]
+
diff --git a/templates/web/base/debug_header.html b/templates/web/base/debug_header.html
new file mode 100644
index 000000000..92ccbc357
--- /dev/null
+++ b/templates/web/base/debug_header.html
@@ -0,0 +1,5 @@
+[% IF c.config.STAGING_SITE and c.config.SHOW_DEBUG %]
+ <p class="dev-site-notice">
+ [% loc("This is a developer site; things might break at any time, and the database will be periodically deleted.") %]
+ </p>
+[% END %]
diff --git a/templates/web/base/email_sent.html b/templates/web/base/email_sent.html
new file mode 100644
index 000000000..9afddf2bd
--- /dev/null
+++ b/templates/web/base/email_sent.html
@@ -0,0 +1,34 @@
+[% INCLUDE 'header.html', title = loc('Create a report') %]
+
+<h1>[% loc("Nearly Done! Now check your email...") %]</h1>
+
+[% IF c.cobrand.moniker != 'zurich' %]
+ <p>[% loc("The confirmation email <strong>may</strong> take a few minutes to arrive &mdash; <em>please</em> be patient.") %]</p>
+[% END %]
+
+<p>[% loc("If you use web-based email or have 'junk mail' filters, you may wish to check your bulk/spam mail folders: sometimes, our messages are marked that way.") %]</p>
+
+[% IF c.cobrand.moniker != 'zurich' %]
+ <p>
+ [% loc("You must now click the link in the email we've just sent you.") %]
+ [% IF email_type == 'problem' %]
+ [% loc("If you do not, your problem will not be posted.") %]
+ [% ELSIF email_type == 'update' %]
+ [% loc("If you do not, your update will not be posted.") %]
+ [% ELSIF email_type == 'alert' %]
+ [% loc("If you do not, your alert will not be activated.") %]
+ [% END %]
+ </p>
+
+ <p>
+ [% IF email_type == 'problem' %]
+ [% loc("(Don't worry &mdash; we'll hang on to your problem report while you're checking your email.)") %]
+ [% ELSIF email_type == 'update' %]
+ [% loc("(Don't worry &mdash; we'll hang on to your update while you're checking your email.)") %]
+ [% ELSIF email_type == 'alert' %]
+ [% loc("(Don't worry &mdash; we'll hang on to your alert while you're checking your email.)") %]
+ [% END %]
+ </p>
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/errors.html b/templates/web/base/errors.html
new file mode 100644
index 000000000..e0f484ba5
--- /dev/null
+++ b/templates/web/base/errors.html
@@ -0,0 +1,5 @@
+[% FOREACH error IN errors %]
+ [% '<ul class="error">' IF loop.first %]
+ <li>[% error %]</li>
+ [% '</ul>' IF loop.last %]
+[% END %]
diff --git a/templates/web/base/errors/generic.html b/templates/web/base/errors/generic.html
new file mode 100755
index 000000000..12aa8e170
--- /dev/null
+++ b/templates/web/base/errors/generic.html
@@ -0,0 +1,8 @@
+[% INCLUDE 'header.html', title = loc('Error') %]
+
+<h1>[% loc('Error') %]</h1>
+
+<p>[% message %]</p>
+
+[% INCLUDE 'footer.html' %]
+
diff --git a/templates/web/base/errors/page_error_404_not_found.html b/templates/web/base/errors/page_error_404_not_found.html
new file mode 100644
index 000000000..77db18e89
--- /dev/null
+++ b/templates/web/base/errors/page_error_404_not_found.html
@@ -0,0 +1,20 @@
+[% INCLUDE 'header.html', title => loc('Page Not Found') %]
+
+<h1>[%loc('Page Not Found') %]</h1>
+
+[% IF error_msg %]
+ <p class="error">[% error_msg | html %]</p>
+[% END %]
+
+<p>
+ [%
+ tprintf(
+ loc("The requested URL '%s' was not found on this server"),
+ c.req.uri
+ )
+ %]
+</p>
+
+[% # FIXME - add more helpful suggestions to this page %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/faq/faq-en-gb.html b/templates/web/base/faq/faq-en-gb.html
new file mode 100755
index 000000000..57f346d31
--- /dev/null
+++ b/templates/web/base/faq/faq-en-gb.html
@@ -0,0 +1,198 @@
+[% INCLUDE 'header.html', title => loc('Frequently Asked Questions') %]
+
+<h1>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
+ [% IF c.cobrand.moniker != 'southampton' %]
+ <li>Unlit lampposts
+ [% END %]
+ <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[% IF c.cobrand.moniker != 'southampton' %], and
+then together lobby the council to fix it, or fix it directly yourselves[% END %].</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 will already work on your mobile phone, adapting to
+ the size of your screen automatically. Using an app has some advantages, though
+ &mdash; for example, you can create a report even when you have no network
+ connection.
+ <ul>
+ <li>
+ <a href="https://itunes.apple.com/gb/app/fixmystreet/id297456545">FixMyStreet app for iPhone</a>
+ <li>
+ <a href="https://play.google.com/store/apps/details?id=org.mysociety.FixMyStreet">FixMyStreet app for Android</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>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="https://www.mysociety.org/services/fixmystreet-for-councils/">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="privacy"></a>Privacy Questions</h2>
+ <dl>
+ <dt>Who gets to see my email address?</dt>
+ <dd>If you submit a problem, we pass on your details, and details
+of the problem, to the council contact or contacts responsible for the
+area where you located the problem. Other than the council, who obviously get your
+email address, only people we authorise to view the FixMyStreet administration interface
+will be able to see your email address and they will never use it for anything other than
+to help administer FixMyStreet. Similarly with email addresses from updates. We will never give or sell your email address to anyone else,
+unless we are obliged to by law. Your name will not be published anywhere unless you let us.</dd>
+ <dt>Will you send nasty, brutish spam to my email address?</dt>
+ <dd>Never. We will email you if someone leaves an update on a
+problem you&rsquo;ve reported, and send you a questionnaire email four weeks
+after you submit a problem, asking for a status update; we&rsquo;ll only ever
+send you emails in relation to your problem.</dd>
+ </dl>
+ <h2>Organisation Questions</h2>
+ <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.
+</dd>
+<dt>I&rsquo;d prefer code in a different language?</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>
+</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>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/footer.html b/templates/web/base/footer.html
new file mode 100644
index 000000000..a58a3e696
--- /dev/null
+++ b/templates/web/base/footer.html
@@ -0,0 +1,35 @@
+ </div><!-- #mysociety .container -->
+
+ <div id="navigation" class="container" role="navigation">
+ <div class="spacer"></div>
+ <ul id="site-nav" class="nav">
+ <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 == '/my' %]span[% ELSE %]a href="/my"[% END
+ %]>[% loc("Your reports") %]</[% c.req.uri.path == '/my' ? 'span' : '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 == '/alert' %]span[% ELSE %]a href="/alert[% pc ? '/list?pc=' : '' %][% pc | uri %]"[% END
+ %]>[% loc("Local alerts") %]</[% c.req.uri.path == '/alert' ? '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>
+
+ </div>
+
+</div></div></div><!-- wrappers -->
+
+<div id="footer">
+
+ <p><a href="/contact">[% loc("Contact FixMyStreet") | replace(' ', '&nbsp;') %]</a></p>
+
+ <p>[% loc('Are you a <strong>developer</strong>? Would you like to contribute to FixMyStreet?') %]
+ [% loc('Our code is open source and <a href="http://github.com/mysociety/fixmystreet">available on GitHub</a>.') %]
+ </p>
+
+</div>
+
+[% INCLUDE 'debug_footer.html' %]
+
+</body>
+</html>
diff --git a/templates/web/base/front/international_banner.html b/templates/web/base/front/international_banner.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/front/international_banner.html
diff --git a/templates/web/base/front/stats.html b/templates/web/base/front/stats.html
new file mode 100644
index 000000000..5367f1118
--- /dev/null
+++ b/templates/web/base/front/stats.html
@@ -0,0 +1,43 @@
+[%
+ USE Comma;
+ # Note - if we want to i18n the commas we should try
+ # 'Template::Plugin::Number::Format'
+%]
+
+[%
+ stats = c.cobrand.front_stats_data();
+
+ new_text =
+ stats.recency == '1 week'
+ ? nget(
+ "<big>%s</big> report in past week",
+ "<big>%s</big> reports in past week",
+ stats.new
+ )
+ : nget(
+ "<big>%s</big> report recently",
+ "<big>%s</big> reports recently",
+ stats.new
+ );
+
+ fixed_text = nget(
+ "<big>%s</big> fixed in past month",
+ "<big>%s</big> fixed in past month",
+ stats.fixed
+ );
+
+ updates_text = nget(
+ "<big>%s</big> update on reports",
+ "<big>%s</big> updates on reports",
+ stats.updates
+ );
+
+%]
+
+<div id="front_stats">
+ <div>[% tprintf( new_text, stats.new ) | comma %]</div>
+ <div>[% tprintf( fixed_text, stats.fixed ) | comma %]</div>
+ [% IF c.cobrand.moniker != 'zurich' %]
+ <div>[% tprintf( updates_text, stats.updates ) | comma %]</div>
+ [% END %]
+</div>
diff --git a/templates/web/base/header.html b/templates/web/base/header.html
new file mode 100644
index 000000000..e6362a449
--- /dev/null
+++ b/templates/web/base/header.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<!--[if lt IE 7]><html class="no-js ie6 oldie" lang="[% lang_code %]"><![endif]-->
+<!--[if IE 7]> <html class="no-js ie7 oldie" lang="[% lang_code %]"><![endif]-->
+<!--[if IE 8]> <html class="no-js ie8 oldie" lang="[% lang_code %]"><![endif]-->
+<!--[if gt IE 8]><!--><html class="no-js" lang="[% lang_code %]"><!--<![endif]-->
+ <head>
+ <meta name="viewport" content="initial-scale=1.0">
+ <meta name="apple-mobile-web-app-capable" content="yes">
+ <meta name="apple-mobile-web-app-status-bar-style" content="black">
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
+ <meta name="HandHeldFriendly" content="true">
+ <meta name="mobileoptimized" content="0">
+
+ <link rel="stylesheet" href="[% version('/css/core.css') %]">
+
+ [% INCLUDE 'common_header_tags.html' %]
+
+ </head>
+ <body>
+
+<div id="wrapper"><div id="wrapper2"><div id="wrapper3">
+
+ [% IF NOT title AND NOT c.req.path %]<h1 id="header" role="banner">[% ELSE %]<div id="header" role="banner"><a href="/">[% END
+ %][% loc('FixMyStreet') %]
+ [%- IF NOT title AND NOT c.req.path %]</h1>[% ELSE %]</a></div>[% END %]
+
+ <ul id="meta">
+ [% IF c.user_exists %]
+ <li>[% tprintf(loc('Signed in as %s'), c.user.name || c.user.email) %]
+ <li class="last"><a href="/auth/sign_out">[% loc('Sign out') %]</a></li>
+ [% ELSE %]
+ <li>&nbsp;</li>
+ [% END %]
+ </ul>
+
+ <div id="mysociety" class="container" role="main">
+
+ [% INCLUDE 'debug_header.html' %]
diff --git a/templates/web/base/header_logo.html b/templates/web/base/header_logo.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/header_logo.html
diff --git a/templates/web/base/header_opengraph.html b/templates/web/base/header_opengraph.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/header_opengraph.html
diff --git a/templates/web/base/header_rss.html b/templates/web/base/header_rss.html
new file mode 100644
index 000000000..b93a2e7fc
--- /dev/null
+++ b/templates/web/base/header_rss.html
@@ -0,0 +1,3 @@
+[% IF rss %]
+ <link rel="alternate" type="application/rss+xml" title="[% rss.0 %]" href="[% rss.1 %]">
+[% END %]
diff --git a/templates/web/base/index-steps.html b/templates/web/base/index-steps.html
new file mode 100644
index 000000000..431791c20
--- /dev/null
+++ b/templates/web/base/index-steps.html
@@ -0,0 +1,42 @@
+<h2>[% loc('How to report a problem') %]</h2>
+
+<ol class="big-numbers">
+[% IF c.cobrand.moniker == 'fixmybarangay' %]
+ <li>Text <span class="promo-big">FMB LUZ</span> or <span class="promo-big">FMB BSN</span> followed by your report to
+ <ul id="promo-list">
+ <li>
+ <span class="promo-bigger">391-FMB</span> (391362) SMART short code
+ </li>
+ <li>
+ <span class="promo-bigger">0908&nbsp;896&nbsp;8278</span> for all networks
+ </li>
+ </ul>
+ <div class="promo-example">
+ For example:<br/>
+ <div>
+ FMB LUZ Busted streetlamp, P. Cabantan St., Pole # 12345, near Sto. Antonio Chapel
+ </div>
+ </div>
+ </li>
+ <li>Or visit the Barangay Center in person</li>
+ <li>Staff? <a href="/auth">Sign in</a> and click on the map!
+[% ELSE %]
+ <li>[% question %]</li>
+ <li>[% loc('Locate the problem on a map of the area') %]</li>
+ <li>[% loc('Enter details of the problem') %]</li>
+ [% IF c.cobrand.is_council %]
+ <li>Confirm the report and [% c.cobrand.council_name %] will investigate</li>
+ [% ELSIF c.cobrand.moniker == 'zurich' %]
+ [% ELSE %]
+ <li>[% loc('We send it to the council on your behalf') %]</li>
+ [% END %]
+[% END %]
+</ol>
+
+[% IF c.cobrand.moniker != 'emptyhomes' %]
+<section class="full-width">
+[% INCLUDE "front/stats.html" %]
+[% TRY %][% INCLUDE "front/tips.html" %][% CATCH file %][% END %]
+</section>
+[% END %]
+
diff --git a/templates/web/base/index.html b/templates/web/base/index.html
new file mode 100644
index 000000000..37bdd8c1e
--- /dev/null
+++ b/templates/web/base/index.html
@@ -0,0 +1,60 @@
+[% INCLUDE 'header.html', title = '' %]
+
+[% IF error %]
+ <p class="error">[% error %]</p>
+[% END %]
+
+<p id="expl">
+ [%
+ subhead
+ = c.cobrand.moniker == 'southampton'
+ ? ''
+ : loc('(like graffiti, fly tipping, broken paving slabs, or street lighting)');
+ %]
+ <strong>[% loc('Report, view, or discuss local problems') %]</strong>
+ [% IF subhead != ' ' %]
+ <small>[% subhead %]</small>
+ [% END %]
+</p>
+
+[% TRY %][% INCLUDE 'front/news.html' %][% CATCH file %][% END %]
+
+[% PROCESS 'around/postcode_form.html' %]
+
+<div id="front_intro">
+ [% INCLUDE 'index-steps.html' %]
+</div>
+
+[%
+ recent_photos = c.cobrand.recent_photos('front', 3);
+ probs = c.cobrand.recent();
+%]
+
+[% IF probs.size || recent_photos.size %]
+<div id="front_recent">
+ <h2>[% loc('Recently reported problems') %]</h2>
+ [% IF recent_photos.size %]
+ <p id="front_photos">
+ [% FOREACH p IN recent_photos;
+ photo = p.get_photo_params;
+ %]
+ <a href="/report/[% p.id %]"><img border="0" height="100"
+ src="[% photo.url_tn %]" alt="[% p.title | html %]" title="[% p.title | html %]"></a>
+ [% END %]
+ </p>
+ [% END %]
+
+ [% IF probs.size %]
+ <ul id="nearby_lists">
+ [% FOREACH p IN probs %]
+ <li>
+ <a href="/report/[% p.id %]">[% p.title | html %]</a>
+ <small>[% prettify_dt( p.confirmed, 1 ) %]</small>
+ </li>
+ [% END %]
+ </ul>
+ [% END %]
+</div>
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/js/translation_strings.html b/templates/web/base/js/translation_strings.html
new file mode 100644
index 000000000..a14443b71
--- /dev/null
+++ b/templates/web/base/js/translation_strings.html
@@ -0,0 +1,48 @@
+ translation_strings = {
+ update: '[% loc('Please enter a message') | replace("'", "\\'") %]',
+ title: '[% loc('Please enter a subject') | replace("'", "\\'") %]',
+ detail: '[% loc('Please enter some details') | replace("'", "\\'") %]',
+ name: {
+ required: '[% loc('Please enter your name') | replace("'", "\\'") %]',
+ validName: '[% loc('Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below') | replace("'", "\\'") %]'
+ },
+ category: '[% loc('Please choose a category') | replace("'", "\\'") %]',
+ rznvy: {
+ required: '[% loc('Please enter your email') | replace("'", "\\'") %]',
+ email: '[% loc('Please enter a valid email') | replace("'", "\\'") %]'
+ },
+ email: {
+ required: '[% loc('Please enter your email') | replace("'", "\\'") %]',
+ email: '[% loc('Please enter a valid email') | replace("'", "\\'") %]'
+ },
+ password_sign_in: {
+ required: '[% loc('Please enter a password') | replace("'", "\\'") %]'
+ },
+ phone: {
+ required: '[% loc('Please enter your phone number') | replace("'", "\\'") %]'
+ },
+ fms_extra_title: '[% loc('Please enter your title') | replace("'", "\\'") %]',
+ first_name: '[% loc('Please enter your first name') | replace("'", "\\'") %]',
+ last_name: '[% loc('Please enter your second name') | replace("'", "\\'") %]',
+ geolocate: '[% loc('or locate me automatically') | replace("'", "\\'") %]',
+ right_place: '[% loc('Right place?') | replace("'", "\\'") %]',
+ try_again: '[% loc('Try again') | replace("'", "\\'") %]',
+ place_pin_on_map: '[% loc('Place pin on map') | replace("'", "\\'") %]',
+ home: '[% loc('Home') | replace("'", "\\'") %]',
+ back: '[% loc('Back') | replace("'", "\\'") %]',
+ how_to_send: '[% loc('How to send successful reports') | replace("'", "\\'") %]',
+ more_details: '[% loc('Details') | replace("'", "\\'") %]',
+
+ geolocation_declined: '[% loc('You declined; please fill in the box above') | replace("'", "\\'") %]',
+ geolocation_no_position: '[% loc('Could not look up location') | replace("'", "\\'") %]',
+ geolocation_no_result: '[% loc('No result returned') | replace("'", "\\'") %]',
+ geolocation_unknown: '[% loc('Unknown error') | replace("'", "\\'") %]',
+
+ reporting_a_problem: '[% loc('Reporting a problem') | replace("'", "\\'") %]',
+ ok: '[% loc('OK') | replace("'", "\\'") %]',
+ map: '[% loc('MAP') | replace("'", "\\'") %]',
+
+ permalink: '[% loc('Permalink') | replace("'", "\\'") %]',
+
+ report_problem_heading: '[% loc('Click map to report a problem') | replace("'", "\\'") %]'
+ };
diff --git a/templates/web/base/js/validation_rules.html b/templates/web/base/js/validation_rules.html
new file mode 100644
index 000000000..409d0971f
--- /dev/null
+++ b/templates/web/base/js/validation_rules.html
@@ -0,0 +1,7 @@
+ validation_rules = {
+ title: { required: true },
+ detail: { required: true },
+ email: { required: true },
+ update: { required: true },
+ rznvy: { required: true }
+ };
diff --git a/templates/web/base/maps/fms.html b/templates/web/base/maps/fms.html
new file mode 100644
index 000000000..1cdfc0b35
--- /dev/null
+++ b/templates/web/base/maps/fms.html
@@ -0,0 +1,15 @@
+[% map_js = BLOCK %]
+<!-- <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&mkt=en-GB"></script> -->
+<script type="text/javascript" src="[% version('/js/OpenLayers.fixmystreet.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenLayers.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-bing-ol.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+<!--[if lte IE 6]>
+ <link rel="stylesheet" href="/js/OpenLayers-2.13.1/theme/default/ie6-style.css" type="text/css">
+<![endif]-->
+[% END %]
+
+[% map_html = BLOCK %]
+[% INCLUDE maps/openlayers.html %]
+[% END %]
+
diff --git a/templates/web/base/maps/google-ol.html b/templates/web/base/maps/google-ol.html
new file mode 100644
index 000000000..35c046b55
--- /dev/null
+++ b/templates/web/base/maps/google-ol.html
@@ -0,0 +1,15 @@
+[% map_js = BLOCK %]
+<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
+<script type="text/javascript" src="[% version('/js/OpenLayers.fixmystreet.google.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenLayers.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-google-ol.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+<!--[if lte IE 6]>
+ <link rel="stylesheet" href="/jslib/OpenLayers-2.10/theme/default/ie6-style.css" type="text/css" />
+<![endif]-->
+[% END %]
+
+[% map_html = BLOCK %]
+[% INCLUDE maps/openlayers.html %]
+[% END %]
+
diff --git a/templates/web/base/maps/google.html b/templates/web/base/maps/google.html
new file mode 100644
index 000000000..741edec40
--- /dev/null
+++ b/templates/web/base/maps/google.html
@@ -0,0 +1,35 @@
+[% map_js = BLOCK %]
+<style>
+#map_box img {
+ max-width: none;
+}
+#map_box {
+ color: #000;
+}
+</style>
+<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
+<script type="text/javascript" src="[% version('/js/map-google.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+[% END %]
+
+[% map_html = BLOCK %]
+<script type="text/javascript">
+var fixmystreet = {
+ 'page': '[% page %]',
+ 'area': [ [% map.area.join(',') %] ],
+ 'all_pins': '[% all_pins %]',
+ 'latitude': [% map.latitude %],
+ 'longitude': [% map.longitude %],
+[% IF map.any_zoom -%]
+ 'zoomToBounds': 1,
+[%- END %]
+[% IF map.zoom -%]
+ 'zoom': [% map.zoom %],
+[%- END %]
+ 'pins': [% INCLUDE maps/pins_js.html %]
+}
+</script>
+<div id="map_box">
+ [% pre_map %]
+ <div id="map"></div>
+[% END %]
diff --git a/templates/web/base/maps/mapquest-attribution.html b/templates/web/base/maps/mapquest-attribution.html
new file mode 100644
index 000000000..8ca4ea650
--- /dev/null
+++ b/templates/web/base/maps/mapquest-attribution.html
@@ -0,0 +1,14 @@
+[% map_js = BLOCK %]
+<script type="text/javascript" src="[% version('/js/OpenLayers.fixmystreet.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenLayers.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenStreetMap.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+<!--[if lte IE 6]>
+ <link rel="stylesheet" href="/jslib/OpenLayers-2.10/theme/default/ie6-style.css" type="text/css" />
+<![endif]-->
+[% END %]
+
+[% map_html = BLOCK %]
+[% INCLUDE maps/openlayers.html %]
+<div class="olControlAttribution" style="position: absolute; z-index: 1005;">Data, imagery and map information provided by <a href="http://www.mapquest.com/">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png" />, <a href="http://openstreetmap.org/">Open Street Map</a> and contributors, <a href="http://opendatacommons.org/licenses/odbl/">ODbL</a></div>
+[% END %]
diff --git a/templates/web/base/maps/openlayers.html b/templates/web/base/maps/openlayers.html
new file mode 100644
index 000000000..7967d4480
--- /dev/null
+++ b/templates/web/base/maps/openlayers.html
@@ -0,0 +1,91 @@
+[% IF map.clickable %]
+ [% map.img_type = 'input type="image"' %]
+[% ELSE %]
+ [% map.img_type = 'img' %]
+[% END %]
+
+<input type="hidden" name="zoom" value="[% map.zoom %]">
+<script type="text/javascript">
+var fixmystreet = {
+ 'page': '[% page %]',
+ 'area': [ [% map.area.join(',') %] ],
+ 'all_pins': '[% all_pins %]',
+ 'latitude': [% map.latitude %],
+ 'longitude': [% map.longitude %],
+[% IF map.any_zoom -%]
+ 'zoomToBounds': 1,
+[%- END %]
+[% IF map.zoom -%]
+ 'zoom': [% map.zoom %],
+[%- END %]
+ 'pin_prefix': '[% c.cobrand.path_to_pin_icons %]',
+ 'numZoomLevels': [% map.numZoomLevels %],
+ 'zoomOffset': [% map.zoomOffset %],
+ 'map_type': [% map.map_type %],
+ 'pins': [% INCLUDE maps/pins_js.html %]
+}
+</script>
+<div id="map_box">
+ [% pre_map %]
+ <div id="map"><noscript>
+ <div id="drag"><[% map.img_type %]
+ alt="NW map tile" id="t2.2"
+ name="tile_[% map.x_tile - 1 %].[% map.y_tile - 1 %]"
+ src="[% map.tiles.0 %]"
+ style="top:0; left:0;"><[% map.img_type %]
+ alt="NE map tile" id="t2.3"
+ name="tile_[% map.x_tile %].[% map.y_tile - 1 %]"
+ src="[% map.tiles.1 %]"
+ style="top:0px; left:256px;"><br><[% map.img_type %]
+ alt="SW map tile" id="t3.2"
+ name="tile_[% map.x_tile - 1 %].[% map.y_tile %]"
+ src="[% map.tiles.2 %]"
+ style="top:256px; left:0;"><[% map.img_type %]
+ alt="SE map tile" id="t3.3"
+ name="tile_[% map.x_tile %].[% map.y_tile %]"
+ src="[% map.tiles.3 %]"
+ style="top:256px; left:256px;"></div>
+ <div id="pins">[% FOR pin IN map.pins %][% INCLUDE pin %][% END %]</div>
+ [% INCLUDE compass %]
+ </noscript></div>
+ [% IF map.copyright %]
+ <p id="copyright">[% map.copyright %]</p>
+ [% END %]
+
+
+[% BLOCK compass %]
+[%
+ north = c.uri_with( { lat = map.compass.north.0, lon = map.compass.north.1, zoom = map.zoom } )
+ south = c.uri_with( { lat = map.compass.south.0, lon = map.compass.south.1, zoom = map.zoom } )
+ east = c.uri_with( { lat = map.compass.east.0, lon = map.compass.east.1, zoom = map.zoom } )
+ west = c.uri_with( { lat = map.compass.west.0, lon = map.compass.west.1, zoom = map.zoom } )
+ world = c.uri_with( { zoom = 0 } );
+ SET zoom_in = c.uri_with( { lat = map.latitude, lon = map.longitude, zoom = map.zoom + 1 } ) IF map.zoom < map.numZoomLevels - 1;
+ SET zoom_out = c.uri_with( { lat = map.latitude, lon = map.longitude, zoom = map.zoom - 1 } ) IF map.zoom > 0;
+ SET zoom_in = '#' IF map.zoom >= map.numZoomLevels - 1;
+ SET zoom_out = '#' IF map.zoom <= 0;
+%]
+<div style="position: absolute; left: 4px; top: 4px; z-index: 1007;" class="olControlPanZoom olControlNoSelect" unselectable="on">
+ <div style="position: absolute; left: 13px; top: 4px; width: 18px; height: 18px;"><a rel="nofollow" href="[% north %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/north-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 4px; top: 22px; width: 18px; height: 18px;"><a rel="nofollow" href="[% west %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/west-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 22px; top: 22px; width: 18px; height: 18px;"><a rel="nofollow" href="[% east %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/east-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 13px; top: 40px; width: 18px; height: 18px;"><a rel="nofollow" href="[% south %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/south-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 13px; top: 63px; width: 18px; height: 18px;"><a rel="nofollow" href="[% zoom_in %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/zoom-plus-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 13px; top: 81px; width: 18px; height: 18px;"><a rel="nofollow" href="[% world %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/zoom-world-mini.png" border="0"></a></div>
+ <div style="position: absolute; left: 13px; top: 99px; width: 18px; height: 18px;"><a rel="nofollow" href="[% zoom_out %]"><img style="position: relative; width: 18px; height: 18px;" src="/js/OpenLayers-2.13.1/img/zoom-minus-mini.png" border="0"></a></div>
+</div>
+[% END %]
+
+
+[% BLOCK pin %]
+
+[% IF pin.id %]
+<a title="[% pin.title | html %]" href="[% c.uri_for('/report/' _ pin.id) %]">
+[%- END -%]
+<img border="0" class="pin" src="[% c.uri_for( c.cobrand.path_to_pin_icons _ 'pin-' _ pin.colour _ '.png') %]"
+ alt="[% loc('Problem') %]" style="top:[% pin.py - 64 %]px; left:[% pin.px - 24 %]px; position: absolute;">
+[%- IF pin.id -%]
+</a>
+[% END %]
+
+[% END %]
diff --git a/templates/web/base/maps/osm-streetview.html b/templates/web/base/maps/osm-streetview.html
new file mode 100644
index 000000000..dff6a0c0f
--- /dev/null
+++ b/templates/web/base/maps/osm-streetview.html
@@ -0,0 +1,13 @@
+[% map_js = BLOCK %]
+<script type="text/javascript" src="[% version('/js/OpenLayers.fixmystreet.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenLayers.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-streetview.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+<!--[if lte IE 6]>
+ <link rel="stylesheet" href="/js/OpenLayers-2.13.1/theme/default/ie6-style.css" type="text/css">
+<![endif]-->
+[% END %]
+
+[% map_html = BLOCK %]
+[% INCLUDE maps/openlayers.html %]
+[% END %]
diff --git a/templates/web/base/maps/osm.html b/templates/web/base/maps/osm.html
new file mode 100644
index 000000000..ce08e179a
--- /dev/null
+++ b/templates/web/base/maps/osm.html
@@ -0,0 +1,14 @@
+[% map_js = BLOCK %]
+<script type="text/javascript" src="[% version('/js/OpenLayers.fixmystreet.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenLayers.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/map-OpenStreetMap.js') %]"></script>
+<script type="text/javascript" src="[% version('/js/jquery.ba-hashchange.min.js') %]"></script>
+<!--[if lte IE 6]>
+ <link rel="stylesheet" href="/js/OpenLayers-2.13.1/theme/default/ie6-style.css" type="text/css">
+<![endif]-->
+[% END %]
+
+[% map_html = BLOCK %]
+[% INCLUDE maps/openlayers.html %]
+<div class="olControlAttribution" style="position: absolute; z-index: 1006;">&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors</div>
+[% END %]
diff --git a/templates/web/base/maps/pins_js.html b/templates/web/base/maps/pins_js.html
new file mode 100644
index 000000000..d9c6b3531
--- /dev/null
+++ b/templates/web/base/maps/pins_js.html
@@ -0,0 +1,4 @@
+[ [% FOR pin IN map.pins -%]
+ [ [% pin.latitude %], [% pin.longitude %], '[% pin.colour %]', '[% pin.id %]', "[% pin.title | escape_js %]", '[% pin.type %]' ]
+ [%- IF !loop.last %],[% END %]
+[% END %] ]
diff --git a/templates/web/base/my/my.html b/templates/web/base/my/my.html
new file mode 100644
index 000000000..33b2cc6a4
--- /dev/null
+++ b/templates/web/base/my/my.html
@@ -0,0 +1,88 @@
+[%
+ PROCESS "maps/${map.type}.html" IF problems.size;
+ INCLUDE 'header.html', title = loc('Your Reports'), bodyclass = 'mappage'
+%]
+
+[% IF problems.size %]
+ [% map_html %]
+ </div>
+ <div id="side">
+[% ELSE %]
+ <div id="skipped-map">
+[% END %]
+
+<h1>[% loc('Your Reports') %]</h1>
+
+<p><a href="/auth/change_password">[% loc('Change password') %]</a></p>
+
+[% IF ! has_content %]
+[% tprintf( loc('You haven&rsquo;t created any reports yet. <a href="%s">Report a problem now.</a>'),
+ c.uri_for('/') ) %]
+[% END %]
+
+[% INCLUDE 'pagination.html',
+ pager = problems_pager,
+ param = 'p'
+%]
+
+[% FOREACH p = problems.confirmed %]
+ [% IF loop.first %]<h2>[% loc('Open reports') %]</h2>[% END %]
+ [% INCLUDE problem %]
+[% END %]
+
+[% FOREACH p = problems.fixed %]
+ [% IF loop.first %]<h2>[% loc('Fixed reports') %]</h2>[% END %]
+ [% INCLUDE problem %]
+[% END %]
+
+[% FOREACH p = problems.closed %]
+ [% IF loop.first %]<h2>[% loc('Closed reports') %]</h2>[% END %]
+ [% INCLUDE problem %]
+[% END %]
+
+[%# FOREACH p = problems.unconfirmed;
+ IF loop.first;
+ '<h2>' _ loc('Unconfirmed reports') _ '</h2>';
+ END;
+ INCLUDE problem;
+END %]
+
+[% FOREACH u IN updates %]
+ [% IF loop.first %]
+ <h2>[% loc('Your updates') %]</h2>
+ [% INCLUDE 'pagination.html',
+ pager = updates_pager,
+ param = 'u'
+ %]
+ <ul class="issue-list full-width">
+ [% 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, 'date' ) ) %]
+ </em>
+ </li>
+ [% "</ul>" IF loop.last %]
+[% END %]
+
+</div>
+
+[% INCLUDE 'footer.html' %]
+
+[% BLOCK problem %]
+ [% "<ul class='issue-list-a full-width'>" IF loop.first %]
+
+ <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, 'date' ), p.body(c) ) %]
+ [% ELSE %]
+ [% tprintf( loc("Reported %s"), prettify_dt( p.confirmed, 'date' ) ) %]
+ [% END %]
+ </em>
+ </li>
+
+ [% "</ul>" IF loop.last %]
+[% END %]
+
diff --git a/templates/web/base/open311/index.html b/templates/web/base/open311/index.html
new file mode 100644
index 000000000..aa77a8381
--- /dev/null
+++ b/templates/web/base/open311/index.html
@@ -0,0 +1,216 @@
+[% INCLUDE 'header.html', title = 'Open311', bodyclass = 'twothirdswidthpage' %]
+
+<div class="sticky-sidebar">
+ <aside>
+ <ul class="plain-list">
+ <li><a href="/faq">Frequently Asked Questions</a></li>
+ <li><a href="/faq#practical">Practical Questions</a></li>
+ <li><a href="/faq#organisation">Organisation Questions</a></li>
+ <li><a href="/privacy">Privacy and cookies</a></li>
+ <li><a href="/contact">Contact FixMyStreet</a></li>
+ </ul>
+ </aside>
+</div>
+
+<h1>FixMyStreet support for Open311</h1>
+
+<p>FixMyStreet supports Open311 both as a <a href="#client">client</a> (sending
+reports made on the site to an external service via the Open311 protocol), and
+partly as a <a href="#server">server</a> (returning reports made on the site when
+queried via the Open311 protocol).</p>
+
+<dl id="client">
+
+<dt>What is Open311?</dt>
+
+<dd>
+<p>In a nutshell, it's an international open standard that allows services to
+'talk to' council systems.</p>
+<p>As channels of communication diversify, it has become more and more
+important that council systems can recognise and accept reports from a variety
+of sources. For example, reports may come in via Twitter, SMS, email, services
+like FixMyStreet, and the council's own website.</p>
+</dd>
+
+<dt>Where can I find out more?</dt>
+
+<dd>
+<p>Open311 isn't as widely known as it deserves to be, so we wrote a
+<a href="http://www.mysociety.org/2013/01/10/open311-introduced/">short
+series of blog posts</a> to explain the basics. And you can find out lots more at
+<a href="http://open311.org/">open311.org</a>.</p>
+</dd>
+
+<dt>Why does it matter?</dt>
+
+<dd>
+<p>If you oversee problem reports at a council, you will of course be concerned
+about future-proofing your communication channels in an easy and economical way
+&ndash; Open311 gives you that assurance.</p>
+
+[% IF c.cobrand.moniker == 'fixmystreet' %]
+<p>You may be interested to know about <a
+href="http://www.google.com/url?q=http%3A%2F%2Fwww.mysociety.org%2Ffor-councils%2Ffixmystreet%2F&sa=D&sntz=1&usg=AFQjCNHo4eT2yOopyZ-39zz16jC-Faa5gQ">FixMyStreet
+for Councils</a>, our hosted service which sits seamlessly on your council
+website.</p>
+
+<p>We can integrate it with any council back-end system, but if you use
+Open311, we charge less. That's how much we believe it's the sane way forward
+for council problem-reporting systems.</p>
+[% END %]
+
+<dt>Any questions?</dt>
+
+<dd>
+<p>We're always happy to talk. Just <a href="/contact">drop us a line</a>.</p>
+</dd>
+
+</dl>
+
+<hr>
+
+<h2 id="server">[% loc('Open311 API for the mySociety FixMyStreet server') %]</h2>
+
+[% IF error %]
+<p>[% tprintf( loc('Note: <strong>%s</strong>'), error ) %]</p>
+[% END %]
+
+<p>[% loc('At the moment only searching for and looking at reports work.') %]</p>
+<p>[% loc('This API implementation is work in progress and not yet stabilized. It will change without warnings in the future.') %]</p>
+
+<ul>
+<li><a rel="nofollow" href="http://www.open311.org/">[% loc('Open311 initiative web page') %]</a></li>
+<li><a rel="nofollow" href="http://wiki.open311.org/GeoReport_v2">[% loc('Open311 specification') %]</a></li>
+</ul>
+
+<p>[% tprintf( loc('At most %d requests are returned in each query. The returned requests are ordered by requested_datetime, so to get all requests, do several searches with rolling start_date and end_date.'), c.config.RSS_LIMIT ) %]</p>
+
+<p>[% loc('The following Open311 v2 attributes are returned for each request: service_request_id, description, lat, long, media_url, status, requested_datetime, updated_datetime, service_code and service_name.') %]</p>
+
+<p>[% loc('In addition, the following attributes that are not part of the Open311 v2 specification are returned: agency_sent_datetime, title (also returned as part of description), interface_used, comment_count, requestor_name (only present if requestor allowed the name to be shown on this site).') %]</p>
+
+<p>[% loc('The Open311 v2 attribute agency_responsible is used to list the administrations that received the problem report, which is not quite the way the attribute is defined in the Open311 v2 specification.') %]</p>
+
+<p>[% tprintf( loc('With request searches, it is also possible to search for agency_responsible to limit the requests to those sent to a single administration. The search term is the administration ID provided by <a href="%s">MaPit</a>.'), c.config.MAPIT_URL ) %]</p>
+
+<p>[% loc('Examples:') %]</p>
+
+<ul>
+
+[% jurisdiction_id = 'fiksgatami.no' %]
+[% examples = [
+ {
+ url = c.cobrand.base_url _ "/open311/v2/discovery.xml?jurisdiction_id=$jurisdiction_id",
+ info = 'discovery information',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/services.xml?jurisdiction_id=$jurisdiction_id",
+ info = 'list of services provided',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/services.xml?jurisdiction_id=$jurisdiction_id&lat=60&long=11",
+ info = 'list of services provided for WGS84 coordinate latitude 60 longitude 11',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/requests/1.xml?jurisdiction_id=$jurisdiction_id",
+ info = 'Request number 1',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/requests.xml?jurisdiction_id=$jurisdiction_id&status=open&agency_responsible=1601&end_date=2011-03-10",
+ info = 'All open requests reported before 2011-03-10 to Trondheim (id 1601)',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/requests.xml?jurisdiction_id=$jurisdiction_id&status=open&agency_responsible=219|220",
+ info = 'All open requests in Asker (id 220) and Bærum (id 219)',
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/requests.xml?jurisdiction_id=$jurisdiction_id&service_code=Vannforsyning",
+ info = "All requests with the category 'Vannforsyning'",
+ },
+ {
+ url = c.cobrand.base_url _ "/open311/v2/requests.xml?jurisdiction_id=$jurisdiction_id&status=closed",
+ info = 'All closed requests',
+ },
+] %]
+[% FOREACH examples %]
+ <li><a href="[% url %]">[% info %]</a>
+ [% IF url.match('/requests.xml') %]
+ [ <a href="http://maps.google.com/?q=[% url.replace('.xml', '.rss') | uri %]">[% loc('GeoRSS on Google Maps') %]</a> ]
+ [% END %]
+ <br>[% url | html %]</li>
+[% END %]
+
+</ul>
+
+<h2>Searching</h2>
+
+<p>The following search parameters can be used:</p>
+
+<dl>
+
+<dt>service_request_id</dt>
+<dd>Search for numeric ID of specific request.
+ Using this is identical to asking for a individual request using
+ the /requests/number.format URL.</dd>
+<dt>service_code</dt>
+<dd>Search for the given category / service type string.</dd>
+
+<dt>status</dt>
+<dd>Search for open or closed (fixed) requests.</dd>
+
+<dt>start_date<dt>
+<dd>Only return requests with requested_datetime set after or at the
+ date and time specified. The format is YYYY-MM-DDTHH:MM:SS+TZ:TZ.</dd>
+
+<dt>end_date<dt>
+<dd>Only return requests with requested_datetime set before the date
+ and time specified. Same format as start_date.</dd>
+
+<dt>agency_responsible</dt>
+<dd>ID of government body receiving the request. Several IDs can be
+ specified with | as a separator.</dd>
+
+<dt>interface_used<dt>
+<dd>Name / identifier of interface used.</dd>
+
+<dt>has_photo<dt>
+<dd>Search for entries with or without photos. Use value 'true' to
+only get requests created with images, and 'false' to get those
+created without images.</dd>
+
+<dt>max_requests</dt>
+<dd>Max number of requests to return from the search. If it is larger
+than the site specific max_requests value specified in the discovery
+call, the value provided is ignored.</dd>
+
+<dl>
+
+<p>The search result might look like this:</p>
+
+<pre>[% "
+ <requests>
+ <request>
+ <agency_responsible>
+ <recipient>Statens vegvesen region øst</recipient>
+ <recipient>Oslo</recipient>
+ </agency_responsible>
+ <agency_sent_datetime>2011-04-23T10:28:55+02:00</agency_sent_datetime>
+ <description>Mangler brustein: Det støver veldig på tørre dager. Her burde det vært brustein.</description>
+ <detail>Det støver veldig på tørre dager. Her burde det vært brustein.</detail>
+ <interface_used>Web interface</interface_used>
+ <lat>59.916848</lat>
+ <long>10.728148</long>
+ <requested_datetime>2011-04-23T09:32:36+02:00</requested_datetime>
+ <requestor_name>Petter Reinholdtsen</requestor_name>
+ <service_code>Annet</service_code>
+ <service_name>Annet</service_name>
+ <service_request_id>1</service_request_id>
+ <status>open</status>
+ <title>Mangler brustein</title>
+ <updated_datetime>2011-04-23T10:28:55+02:00</updated_datetime>
+ </request>
+ </requests>
+" | html %]</pre>
+
+[% INCLUDE 'footer.html' %]
+
diff --git a/templates/web/base/pagination.html b/templates/web/base/pagination.html
new file mode 100644
index 000000000..63180b600
--- /dev/null
+++ b/templates/web/base/pagination.html
@@ -0,0 +1,19 @@
+[% IF pager.last_page > 1 %]
+[% IF NOT admin %]
+<section class="full-width">
+[% END %]
+ <p class="pagination">
+ [% IF pager.previous_page %]
+ <a class="prev" href="[% c.req.uri_with({ $param => pager.previous_page }) %][% '#' _ hash IF hash %]">[% loc('Previous') %]</a>
+ [% END %]
+
+ [% tprintf( loc('%d to %d of %d'), pager.first, pager.last, pager.total_entries ) %]
+
+ [% IF pager.next_page %]
+ <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/base/questionnaire/completed-open.html b/templates/web/base/questionnaire/completed-open.html
new file mode 100644
index 000000000..c860b7341
--- /dev/null
+++ b/templates/web/base/questionnaire/completed-open.html
@@ -0,0 +1,11 @@
+[% IF c.cobrand.is_council %]
+<p style="font-size: 150%">
+Thank you very much for filling in our questionnaire.
+</p>
+[% ELSE %]
+[% loc('<p style="font-size:150%">We&rsquo;re sorry to hear that. We have two
+suggestions: why not try writing to your local representatives or, if
+it&rsquo;s a problem that could be fixed by local people working together, why
+not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>?
+</p>') %]
+[% END %]
diff --git a/templates/web/base/questionnaire/completed.html b/templates/web/base/questionnaire/completed.html
new file mode 100644
index 000000000..4d848a63c
--- /dev/null
+++ b/templates/web/base/questionnaire/completed.html
@@ -0,0 +1,28 @@
+[%
+ INCLUDE 'header.html', title = loc('Questionnaire')
+%]
+
+[% advert_outcome = 1 %]
+
+[% IF been_fixed == 'Unknown' %]
+
+[% loc('<p>Thank you very much for filling in our questionnaire; if you
+get some more information about the status of your problem, please come back to the
+site and leave an update.</p>') %]
+
+[% ELSIF new_state == 'confirmed' OR (!new_state AND problem.is_open) OR (!new_state AND problem.is_closed) %]
+
+[% INCLUDE 'questionnaire/completed-open.html' %]
+[% advert_outcome = 0 %]
+
+[% ELSIF been_fixed == 'Yes' %]
+
+[% loc('<p style="font-size:150%">Thank you very much for filling in our questionnaire; glad to hear it&rsquo;s been fixed.</p>') %]
+
+[% END %]
+
+[% IF advert_outcome %]
+ [% display_crosssell_advert( problem.user.email, problem.name, 'council', problem.bodies_str ) %]
+[% END %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/questionnaire/creator_fixed.html b/templates/web/base/questionnaire/creator_fixed.html
new file mode 100644
index 000000000..5b6d1254a
--- /dev/null
+++ b/templates/web/base/questionnaire/creator_fixed.html
@@ -0,0 +1,23 @@
+[% INCLUDE 'header.html', title = loc('Confirmation') %]
+
+<form method="post" action="/questionnaire/submit" id="questionnaire">
+<input type="hidden" name="problem" value="[% problem_id | html %]">
+
+[% INCLUDE 'errors.html' %]
+
+<p>
+[% loc("Thanks, glad to hear it's been fixed! Could we just ask if you have ever reported a problem to a council before?") %]
+</p>
+
+<p align="center">
+<input type="radio" name="reported" id="reported_yes" value="Yes"[% ' checked' IF reported == 'Yes' %]>
+<label class="inline" for="reported_yes">[% loc('Yes') %]</label>
+<input type="radio" name="reported" id="reported_no" value="No"[% ' checked' IF reported == 'No' %]>
+<label class="inline" for="reported_no">[% loc('No') %]</label>
+</p>
+
+<p><input type="submit" name="submit" value="[% loc('Submit') %]"></p>
+
+</form>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/questionnaire/index.html b/templates/web/base/questionnaire/index.html
new file mode 100644
index 000000000..6783bca57
--- /dev/null
+++ b/templates/web/base/questionnaire/index.html
@@ -0,0 +1,123 @@
+[%
+ pre_map = INCLUDE 'report/_main.html';
+ PROCESS "maps/${map.type}.html";
+ INCLUDE 'header.html', title = loc('Questionnaire')
+%]
+
+[% map_html %]
+
+[% INCLUDE 'report/updates.html' %]
+
+</div>
+<div id="side">
+
+<h1>[% loc('Questionnaire') %]</h1>
+
+<form method="post" action="/questionnaire/submit" id="questionnaire"
+[%- IF c.cobrand.allow_photo_upload -%]
+ enctype="multipart/form-data"
+[%- END -%]
+>
+
+<input type="hidden" name="token" value="[% token | html %]">
+
+[% IF c.cobrand.moniker == 'emptyhomes' %]
+[% IF num_questionnaire == 1 %]
+[% loc('<p>Getting empty homes back into use can be difficult. You shouldn&rsquo;t expect
+the property to be back into use yet. But a good council will have started work
+and should have reported what they have done on the website. If you are not
+satisfied with progress or information from the council, now is the right time
+to say. You may also want to try contacting some other people who may be able
+to help. For advice on how to do this and other useful information please
+go to <a href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p>
+') %]
+[% ELSE %]
+[% loc('<p>Getting empty homes back into use can be difficult, but by now a good council
+will have made a lot of progress and reported what they have done on the
+website. Even so properties can remain empty for many months if the owner is
+unwilling or the property is in very poor repair. If nothing has happened or
+you are not satisfied with the progress the council is making, now is the right
+time to say so. We think it&rsquo;s a good idea to contact some other people who
+may be able to help or put pressure on the council For advice on how to do
+this and other useful information please go to <a
+href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p>
+') %]
+[% END %]
+[% END %]
+
+<p>
+[% loc('The details of your problem are available on the right hand side of this page.') %]
+[% loc('Please take a look at the updates that have been left.') IF updates %]
+</p>
+
+[% IF errors %]
+<ul class="error">
+<li>[% errors.join("</li>\n<li>") %]</li>
+</ul>
+[% END %]
+
+<p>
+[% loc('An update marked this problem as fixed.') IF problem.is_fixed %]
+[% loc('Has this problem been fixed?') %]
+</p>
+
+<p>
+<input type="radio" name="been_fixed" id="been_fixed_yes" value="Yes"[% ' checked' IF been_fixed == 'Yes' %]>
+<label for="been_fixed_yes">[% loc('Yes') %]</label>
+<input type="radio" name="been_fixed" id="been_fixed_no" value="No"[% ' checked' IF been_fixed == 'No' %]>
+<label for="been_fixed_no">[% loc('No') %]</label>
+<input type="radio" name="been_fixed" id="been_fixed_unknown" value="Unknown"[% ' checked' IF been_fixed == 'Unknown' %]>
+<label for="been_fixed_unknown">[% loc('Don&rsquo;t know') %]</label>
+</p>
+
+[% UNLESS answered_ever_reported %]
+<p>[% loc('Have you ever reported a problem to a council before, or is this your first time?') %]</p>
+<p>
+<input type="radio" name="reported" id="reported_yes" value="Yes"[% ' checked' IF reported == 'Yes' %]>
+<label for="reported_yes">[% loc('Reported before') %]</label>
+<input type="radio" name="reported" id="reported_no" value="No"[% ' checked' IF reported == 'No' %]>
+<label for="reported_no">[% loc('First time') %]</label>
+</p>
+[% END %]
+
+[% IF c.cobrand.moniker == 'southampton' %]
+<p>Add a public update (please note it will not be sent to the council)</p>
+[% ELSE %]
+<p>[% loc('If you wish to leave a public update on the problem, please enter it here
+(please note it will not be sent to the council). For example, what was
+your experience of getting the problem fixed?') %]</p>
+[% END %]
+
+<p><textarea name="update" style="max-width:90%" rows="7" cols="30">[% update | html %]</textarea></p>
+
+[% IF c.cobrand.allow_photo_upload %]
+<div id="fileupload_normalUI">
+ [% IF upload_fileid %]
+ <p>[% loc('You have already attached a photo to this report, attaching another one will replace it.') %]</p>
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ [% END %]
+ <label for="form_photo">[% loc('Photo:') %]</label>
+ <input type="file" name="photo" id="form_photo">
+</div>
+[% END %]
+
+[% IF c.cobrand.moniker != 'emptyhomes' %]
+<div id="another_qn">
+ <p>[% loc('Would you like to receive another questionnaire in 4 weeks, reminding you to check the status?') %]</p>
+ <p>
+ <input type="radio" name="another" id="another_yes" value="Yes"[% ' checked' IF another == 'Yes' %]>
+ <label for="another_yes">[% loc('Yes') %]</label>
+ <input type="radio" name="another" id="another_no" value="No"[% ' checked' IF another == 'No' %]>
+ <label for="another_no">[% loc('No') %]</label>
+ </p>
+</div>
+[% END %]
+
+<p><input type="submit" name="submit" value="[% loc('Submit questionnaire') %]"></p>
+
+</form>
+
+</div>
+
+[% INCLUDE 'footer.html' %]
+
diff --git a/templates/web/base/report/_council_sent_info.html b/templates/web/base/report/_council_sent_info.html
new file mode 100644
index 000000000..958562dc2
--- /dev/null
+++ b/templates/web/base/report/_council_sent_info.html
@@ -0,0 +1,5 @@
+[% IF problem.whensent || problem.can_display_external_id %]
+ <small class="council_sent_info"><br>
+ [% problem.processed_summary_string(c) %]
+ </small>
+[% END %]
diff --git a/templates/web/base/report/_main.html b/templates/web/base/report/_main.html
new file mode 100644
index 000000000..0124052c0
--- /dev/null
+++ b/templates/web/base/report/_main.html
@@ -0,0 +1,23 @@
+<div class="problem-header cf">
+ <h1>[% problem.title | html %]</h1>
+
+ <p><em>
+ [% problem.meta_line(c) | html %]
+ [%- IF !problem.used_map AND c.cobrand.moniker != 'emptyhomes' %]; <strong>[% loc('there is no pin shown as the user did not use the map') %]</strong>[% END %]
+ [% IF problem.bodies_str %]
+ [% INCLUDE 'report/_council_sent_info.html' %]
+ [% ELSE %]
+ <br><small>[% loc('Not reported to council') %]</small>
+ [% END %]
+ </em></p>
+ [% INCLUDE 'report/_support.html' %]
+
+ [% IF c.cobrand.moniker == 'southampton' %]
+ [% add_links( problem.detail ) | html_para %]
+ [% INCLUDE 'report/photo.html' object=problem %]
+ [% ELSE %]
+ [% INCLUDE 'report/photo.html' object=problem %]
+ [% add_links( problem.detail ) | html_para %]
+ [% END %]
+
+</div>
diff --git a/templates/web/base/report/_support.html b/templates/web/base/report/_support.html
new file mode 100644
index 000000000..3e372ba69
--- /dev/null
+++ b/templates/web/base/report/_support.html
@@ -0,0 +1,17 @@
+[% IF c.cobrand.can_support_problems %]
+[%
+ IF !problem.interest_count;
+ SET text = loc('No supporters');
+ ELSE;
+ SET text = tprintf( nget( "%d supporter", "%d supporters", problem.interest_count ), problem.interest_count );
+ END;
+%]
+
+ [% IF c.user AND c.user.from_body %]
+ <form action="[% c.uri_for( '/report/support' ) %]">
+ <p id="supporter"><small>[% text %] <input type="hidden" name="id" value="[% problem.id %]"><input type="submit" class="green-btn" value="Add support"></small></p>
+ </form>
+ [% ELSE %]
+ <p id="supporter"><small>[% text %]</small></p>
+ [% END %]
+[% END %]
diff --git a/templates/web/base/report/banner.html b/templates/web/base/report/banner.html
new file mode 100644
index 000000000..bd7798d79
--- /dev/null
+++ b/templates/web/base/report/banner.html
@@ -0,0 +1,22 @@
+[% USE date %]
+[% BLOCK banner %]
+<p class="banner" id="[% id %]">
+ [% text %]
+</p>
+[% END %]
+
+[% 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 %]
+ [% INCLUDE banner, id = 'fixed', text = loc('This problem has been fixed') %]
+[% END %]
+[% IF problem.is_closed %]
+ [% INCLUDE banner, id = 'closed', text = loc('This problem has been closed') %]
+[% END %]
+[% states = [ 'investigating', 'in progress', 'planned', 'action scheduled' ];
+ IF states.grep(problem.state).size %]
+ [% INCLUDE banner, id = 'progress', text = loc('This problem is in progress') %]
+[% END %]
+
+
diff --git a/templates/web/base/report/display.html b/templates/web/base/report/display.html
new file mode 100644
index 000000000..fd7580ac1
--- /dev/null
+++ b/templates/web/base/report/display.html
@@ -0,0 +1,56 @@
+[%
+ PROCESS "maps/${map.type}.html";
+
+ problem_title = problem.title_safe _ ' - ' _ loc('Viewing a problem');
+ SET rss = [ loc('Updates to this problem, FixMyStreet'), "/rss/$problem.id" ] IF c.cobrand.moniker != 'emptyhomes';
+ SET robots = 'index, nofollow';
+ SET robots = 'noindex, nofollow' IF c.cobrand.moniker == 'emptyhomes';
+ INCLUDE 'header.html'
+ title = problem_title
+%]
+
+[% IF c.cobrand.moniker != 'emptyhomes' %]
+ [% map_html %]
+ </div>
+[% END %]
+
+<div id="side">
+
+[% INCLUDE 'report/banner.html' %]
+[% INCLUDE 'report/_main.html' %]
+
+<p align="right">
+ <small>
+ <a rel="nofollow" href="[% c.uri_for( '/contact', { id => problem.id } ) %]">[% loc('Offensive? Unsuitable? Tell us' ) %]</a>
+ </small>
+</p>
+
+[% IF c.cobrand.moniker != 'emptyhomes' %]
+<p style="padding-bottom: 0.5em; border-bottom: dotted 1px #999999;" align="right">
+ <a href="[% c.uri_for( '/around', { lat => short_latitude, lon => short_longitude } ) %]">[% loc( 'More problems nearby' ) %]</a>
+</p>
+
+<div id="alert_links">
+ <a rel="nofollow" id="email_alert" href="[% c.uri_for( '/alert/subscribe', { id => problem.id } ) %]">[% loc('Email me updates' ) %]</a>
+
+ <form action="[% c.uri_for( '/alert/subscribe' ) %]" method="post" id="email_alert_box">
+ <p>[% loc('Receive email when updates are left on this problem.' ) %]</p>
+ <label class="n" for="alert_rznvy">[% loc('Email:') %]</label>
+ <input type="email" name="rznvy" id="alert_rznvy" value="[% email | html %]" size="30">
+ <input type="hidden" name="id" value="[% problem.id %]">
+ <input type="hidden" name="type" value="updates">
+ <input type="submit" value="[% loc('Subscribe') %]">
+ </form>
+ &nbsp;
+ <a href="[% c.uri_for( '/rss', problem.id ) %]">
+ <img src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% loc('RSS feed of updates to this problem' ) %]" border="0" style="vertical-align: middle">
+ </a>
+</div>
+
+[% INCLUDE 'report/updates.html' %]
+[% INCLUDE 'report/update-form.html' %]
+[% END %]
+
+</div>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/report/new/category.html b/templates/web/base/report/new/category.html
new file mode 100644
index 000000000..ee47adc9e
--- /dev/null
+++ b/templates/web/base/report/new/category.html
@@ -0,0 +1,20 @@
+[% FILTER collapse %]
+[% IF category_options.size %]
+ [% IF category;
+ category = category | lower;
+ END; %]
+ <label for='form_category' id="form_category_label">
+ [%- IF c.cobrand.moniker == 'emptyhomes' %]
+ [%- loc('Property type:') %]
+ [%- ELSE %]
+ [%- loc('Category') %]
+ [%- END -%]</label>
+ <select name='category' id='form_category'[% ' onchange="form_category_onchange()"' IF category_extras.size %]>
+ [% FOREACH cat_op IN category_options %]
+ [% cat_op_lc = cat_op | lower %]
+ <option value='[% cat_op | html %]'[% ' selected' IF report.category == cat_op || category == cat_op_lc || (category_options.size == 2 AND loop.last) -%]
+ >[% IF loop.first %][% cat_op %][% ELSE %][% cat_op | html %][% END %]</option>
+ [% END %]
+ </select>
+[% END %]
+[% END -%]
diff --git a/templates/web/base/report/new/category_extras.html b/templates/web/base/report/new/category_extras.html
new file mode 100644
index 000000000..928b61041
--- /dev/null
+++ b/templates/web/base/report/new/category_extras.html
@@ -0,0 +1,26 @@
+<div id="category_meta">
+ [%- IF report_meta %]
+ [%- category = report.category %]
+ <h4>Additional Information</h4>
+ [%- FOR meta IN category_extras.$category %]
+ [%- meta_name = meta.code -%]
+
+[% IF field_errors.$meta_name %]
+ <div class='form-error'>[% field_errors.$meta_name %]</div>
+[% END -%]
+
+ <div class="form-field">
+ <label for="form_[% meta_name %]">[% meta.description _ ':' %]</label>
+ [% IF meta.exists('values') %]
+ <select name="[% meta_name %]" id="form_[% meta_name %]"[% meta.required == 'true' ? ' required' : '' %]>
+ [% FOR option IN meta.values.value.value %]
+ <option value="[% option.key.0 %]"[% IF option.key.0 == report_meta.$meta_name.value %] selected[% END %]>[% option.name.0 %]</option>
+ [% END %]
+ </select>
+ [% ELSE %]
+ <input type="text" value="[% report_meta.$meta_name | html %]" name="[% meta_name %]" id="form_[% meta_name %]"[% meta.required == 'true' ? ' required' : '' %]>
+ [% END %]
+ </div>
+ [%- END %]
+ [%- END %]
+</div>
diff --git a/templates/web/base/report/new/councils_extra_text.html b/templates/web/base/report/new/councils_extra_text.html
new file mode 100644
index 000000000..1088b9f8b
--- /dev/null
+++ b/templates/web/base/report/new/councils_extra_text.html
@@ -0,0 +1 @@
+[% loc('The subject and details of the problem will be public, plus your name if you give us permission.') %]
diff --git a/templates/web/base/report/new/councils_text.html b/templates/web/base/report/new/councils_text.html
new file mode 100644
index 000000000..f526beb28
--- /dev/null
+++ b/templates/web/base/report/new/councils_text.html
@@ -0,0 +1,9 @@
+[% FILTER collapse %]
+[% IF bodies_to_list.size == 0 %]
+ [% PROCESS 'report/new/councils_text_none.html' %]
+[% ELSIF bodies_to_list.size == bodies.size %]
+ [% PROCESS 'report/new/councils_text_all.html' %]
+[% ELSE %]
+ [% PROCESS 'report/new/councils_text_some.html' %]
+[% END %]
+[% END -%]
diff --git a/templates/web/base/report/new/councils_text_all.html b/templates/web/base/report/new/councils_text_all.html
new file mode 100644
index 000000000..e9a008e90
--- /dev/null
+++ b/templates/web/base/report/new/councils_text_all.html
@@ -0,0 +1,27 @@
+[%# XXX The below type checking is assuming that a body ID can be used to look up a mapit type. %]
+<p>
+[% IF bodies_to_list.0 != 2489 && bodies_to_list.0 != 2482 && all_areas.${bodies_to_list.0}.type == 'LBO' %]
+[%
+ tprintf(
+ loc('All the information you provide here will be sent to <strong>%s</strong> or a relevant local body such as <strong>TfL</strong>, via the London Report-It system.'),
+ all_body_names.join( '</strong>' _ loc(' or ') _ '<strong>' )
+ );
+%]
+[% ELSIF all_areas.${bodies_to_list.0}.type == 'LGD' %]
+[%
+ tprintf(
+ loc('All the information you provide here will be sent to <strong>%s</strong> or <strong>Roads Service</strong>.'),
+ all_body_names.join( '</strong>' _ loc(' or ') _ '<strong>' )
+ );
+%]
+[% ELSE %]
+[%
+ tprintf(
+ loc('All the information you provide here will be sent to <strong>%s</strong>.'),
+ all_body_names.join( '</strong>' _ loc(' or ') _ '<strong>' )
+ );
+%]
+[% END %]
+
+[% INCLUDE 'report/new/councils_extra_text.html' %]
+</p>
diff --git a/templates/web/base/report/new/councils_text_none.html b/templates/web/base/report/new/councils_text_none.html
new file mode 100644
index 000000000..9293c03a7
--- /dev/null
+++ b/templates/web/base/report/new/councils_text_none.html
@@ -0,0 +1,28 @@
+<p>[%
+ nget(
+ "We do not yet have details for the council that covers this location.",
+ "We do not yet have details for the councils that cover this location.",
+ missing_details_bodies.size || all_areas.size
+ );
+%]
+[%
+ loc("If you submit a problem here the subject and details of the problem will be public, but the problem will <strong>not</strong> be reported to the council.");
+%]
+[% IF c.cobrand.moniker == 'fixamingata' AND all_body_names.size == 1 %]
+[%
+ tprintf(
+ "Du kan istället kontakta %s via <a href='%s'>deras webbsida</a>.",
+ all_body_names.first, all_body_urls.first);
+%]
+[% ELSE %]
+[%
+ tprintf(
+ loc("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."),
+ missing_details_body_names.join( loc(' or ') ) || all_area_names.join( loc(' or ') ),
+ c.cobrand.contact_email,
+ c.cobrand.contact_email
+ );
+
+%]
+[% END %]
+</p>
diff --git a/templates/web/base/report/new/councils_text_some.html b/templates/web/base/report/new/councils_text_some.html
new file mode 100644
index 000000000..8d4768612
--- /dev/null
+++ b/templates/web/base/report/new/councils_text_some.html
@@ -0,0 +1,28 @@
+<p>
+[% loc('All the information you provide here will be sent to') %]
+
+[% FOREACH body_id IN bodies_to_list %]
+ [% loc( ' or ') IF ! loop.first %]
+ <strong>[% bodies.$body_id.name %]</strong>
+ [%- '.' IF loop.last %]
+[% END %]
+
+[%
+ loc('The subject and details of the problem will be public, plus your name if you give us permission.');
+%]
+[%
+ nget(
+ "We do <strong>not</strong> yet have details for the other council that covers this location.",
+ "We do <strong>not</strong> yet have details for the other councils that cover this location.",
+ missing_details_bodies.size
+ );
+%]
+[%
+ tprintf(
+ loc("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."),
+ missing_details_body_names.join( loc(' or ') ),
+ c.cobrand.contact_email,
+ c.cobrand.contact_email
+ );
+%]
+</p>
diff --git a/templates/web/base/report/new/extra_name.html b/templates/web/base/report/new/extra_name.html
new file mode 100644
index 000000000..dede1000c
--- /dev/null
+++ b/templates/web/base/report/new/extra_name.html
@@ -0,0 +1,18 @@
+[% IF extra_name_info %]
+<label for="form_fms_extra_title">Title</label>
+[% IF field_errors.fms_extra_title %]
+ <p class='form-error'>[% field_errors.fms_extra_title %]</p>
+[% END %]
+[% title = '' %]
+[% IF fms_extra_title %][% title = fms_extra_title | upper %]
+[% ELSIF c.user && c.user.title %][% title = c.user.title | upper %][% END %]
+<select class="form-focus-trigger required" id="form_fms_extra_title"
+ name="fms_extra_title">
+ <option></option>
+ <option value="MR"[% ' selected' IF title == 'MR' %]>Mr</option>
+ <option value="MISS"[% ' selected' IF title == 'MISS' %]>Miss</option>
+ <option value="MRS"[% ' selected' IF title == 'MRS' %]>Mrs</option>
+ <option value="MS"[% ' selected' IF title == 'MS' %]>Ms</option>
+ <option value="DR"[% ' selected' IF title == 'DR' %]>Dr</option>
+</select>
+[% END %]
diff --git a/templates/web/base/report/new/fill_in_details.html b/templates/web/base/report/new/fill_in_details.html
new file mode 100644
index 000000000..22d1ee739
--- /dev/null
+++ b/templates/web/base/report/new/fill_in_details.html
@@ -0,0 +1,35 @@
+[%
+ PROCESS "maps/${map.type}.html" IF report.used_map;
+ INCLUDE 'header.html', title => loc('Reporting a problem')
+%]
+
+[% IF report.used_map %]
+<form action="[% c.uri_for('/report/new') %]" method="post" name="mapForm" id="mapForm"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %] class="validate">
+[% IF c.req.params.map_override %]
+<input type="hidden" name="map_override" value="[% c.req.params.map_override | html %]">
+[% END %]
+<input type="hidden" name="pc" value="[% pc | html %]">
+[% ELSE %]
+<form action="[% c.uri_for('/report/new') %]" method="post" name="mapSkippedForm"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %] class="validate">
+<input type="hidden" name="pc" value="[% pc | html %]">
+<input type="hidden" name="skipped" value="1">
+[% END %]
+
+<input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% short_latitude | html %]">
+<input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% short_longitude | html %]">
+
+[% IF report.used_map %]
+ [% map_html %]
+ </div>
+ <div id="side">
+[% ELSE %]
+ <div id="skipped-map">
+[% END %]
+
+[% PROCESS 'report/new/fill_in_details_form.html' %]
+
+</div>
+</form>
+
+[% INCLUDE 'footer.html' %]
+
diff --git a/templates/web/base/report/new/fill_in_details_form.html b/templates/web/base/report/new/fill_in_details_form.html
new file mode 100644
index 000000000..5eff4e147
--- /dev/null
+++ b/templates/web/base/report/new/fill_in_details_form.html
@@ -0,0 +1,220 @@
+<h1>[% loc('Reporting a problem') %]</h1>
+
+[% IF report.used_map %]
+ [% IF partial_token %]
+ <p id="unknown">[% loc('Please note your report has <strong>not yet been sent</strong>. Choose a category and add further information below, then submit.') %]</p>
+ [% END %]
+<p>[% loc('You have located the problem at the point marked with a green pin on the map. If this is not the correct location, simply click on the map again. ') %]</p>
+[% END %]
+
+[% IF js %]
+ <p id="councils_text">[%
+ tprintf(
+ loc('All the information you provide here will be sent to <strong>%s</strong>.'),
+ loc('the local council')
+ );
+ %]
+ [% loc('The subject and details of the problem will be public, plus your name if you give us permission.') %]
+ </p>
+[% ELSE %]
+ [% PROCESS 'report/new/councils_text.html' %]
+[% END %]
+
+<p>
+[% IF report.used_map %]
+ [% INCLUDE 'report/new/fill_in_details_text.html' %]
+[% ELSE %]
+ [% loc('Please fill in the form below with details of the problem, and describe the location as precisely as possible in the details box.') %]
+[% END %]
+</p>
+
+[% INCLUDE 'errors.html' %]
+
+<div id="problem_form">
+
+[% INCLUDE 'report/new/form_heading.html' %]
+
+<div class="fieldset">
+
+
+
+
+
+[% IF field_errors.bodies %]
+ <div class='form-error'>[% field_errors.bodies %]</div>
+[% END %]
+
+[% IF field_errors.title %]
+ <div class='form-error'>[% field_errors.title %]</div>
+[% END %]
+
+<div class="form-field">
+ <label for="form_title">[% loc('Subject:') %]</label>
+ <input type="text" value="[% report.title | html %]" name="title" id="form_title" size="25" required>
+</div>
+
+[% IF field_errors.detail %]
+ <div class='form-error'>[% field_errors.detail %]</div>
+[% END %]
+
+<div class="form-field">
+ <label for="form_detail">[% loc('Details:') %]</label>
+ <textarea name="detail" id="form_detail" rows="7" cols="26" required>[% report.detail | html %]</textarea>
+</div>
+
+[% IF js %]
+ <div class="form-field" id="form_category_row">
+ <label for="form_category">[% loc('Category:') %]</label>
+ <select name="category" id="form_category" required><option>[% loc('Loading...') %]</option></select>
+ </div>
+[% ELSE %]
+ [% IF category_options.size %]
+ [% IF field_errors.category %]
+ <div class='form-error'>[% field_errors.category %]</div>
+ [% END %]
+
+ <div class="form-field">
+ [% PROCESS "report/new/category.html" %]
+ </div>
+ [% END %]
+[% END %]
+
+[%- IF category_extras %]
+[% PROCESS "report/new/category_extras.html" %]
+[%- END %]
+
+[% IF c.cobrand.allow_photo_upload %]
+ [% IF field_errors.photo %]
+ <div class='form-error'>[% field_errors.photo %]</div>
+ [% END %]
+
+ <div class='form-field'>
+ [% IF upload_fileid || report.photo %]
+ <p>[% loc('You have already attached a photo to this report, attaching another one will replace it.') %]</p>
+ [% IF upload_fileid %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]" />
+ [% END %]
+ [% IF report.photo %]
+ <img align="right" src="/photo/[% report.id %].jpeg" hspace="5">
+ [% END %]
+ [% END %]
+
+ <label for="form_photo">[% loc('Photo:') %]</label>
+ <input type="file" name="photo" id="form_photo" style="width:20em">
+ </div>
+[% END %]
+
+[% IF c.user_exists %]
+
+ [% INCLUDE name_phone %]
+
+ [% INCLUDE 'report/new/notes.html' %]
+
+ <p id="problem_submit">
+ <input type="submit" value="[% loc('Submit') %]">
+ </p>
+
+[% ELSE %]
+
+ [% IF field_errors.email %]
+ <div class='form-error'>[% field_errors.email %]</div>
+ [% END %]
+
+ <div class="form-field">
+ <label for="form_email">[% loc('Your email:') %]</label>
+ <input type="email" value="[% report.user.email | html %]" name="email" id="form_email" size="25" required>
+ </div>
+
+[% INCLUDE 'report/new/notes.html' %]
+
+<div id="form_sign_in">
+ <h3>[% loc("Now to submit your report&hellip; do you have a FixMyStreet password?") %]</h3>
+
+ <div id="form_sign_in_yes">
+
+ [% IF field_errors.password %]
+ <div class='form-error'>[% field_errors.password %]</div>
+ [% END %]
+
+ <div class="form-field">
+ <label class="n" for="password_sign_in">[% loc('<strong>Yes</strong> I have a password') %]</label>
+ <input type="password" name="password_sign_in" id="password_sign_in" value="" size="25">
+ </div>
+
+ <div class="fieldset">
+
+ <p>
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="n" for="remember_me">
+ [% loc('Keep me signed in on this computer') %]
+ </label>
+ </p>
+
+ <p>
+ <input type="submit" id="submit_sign_in" name="submit_sign_in" value="[% loc('Submit') %]">
+ </p>
+
+ </div>
+
+ </div>
+ <div id="form_sign_in_no">
+
+ <p>[% loc('<strong>No</strong>, let me confirm my report by email:') %]</p>
+
+ <div class="fieldset">
+
+ [% INCLUDE name_phone %]
+
+ <div class="form-field">
+ <label for="password_register">[% loc('Enter a new password:') %]</label>
+ <input type="password" name="password_register" id="password_register" value="" size="25">
+ </div>
+
+ <p style="clear:both"><small>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</small></p>
+
+ <p>
+ <input type="submit" id="submit_register" name="submit_register" value="[% loc('Submit') %]">
+ </p>
+
+ </div>
+
+ </div>
+
+</div>
+
+[% END %]
+
+[% IF partial_token %]
+ <input type="hidden" name="partial" value="[% partial_token.token %]">
+[% END %]
+
+<input type="hidden" name="submit_problem" value="1">
+
+</div>
+</div>
+
+
+[% BLOCK name_phone %]
+ [% IF field_errors.name %]
+ <div class='form-error'>[% field_errors.name %]</div>
+ [% END %]
+
+ <div class="form-field">
+ <label for="form_name">[% loc('Your name:') %]</label>
+ <input type="text" class="validName" value="[% report.name | html %]" name="name" id="form_name" size="25">
+ </div>
+
+ <div class="checkbox">
+ [%# if there is nothing in the name field then set check box as default on form %]
+ <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF report.anonymous==0 OR (c.cobrand.default_show_name AND report.anonymous=='') %]>
+ <label for="form_may_show_name">[% loc('Show my name publicly') %]</label>
+ <br><small>[% loc('(we never show your email address or phone number)') %]</small>
+ </div>
+
+ <div>
+ <label for="form_phone">[% loc('Phone:') %]</label>
+ <input type="text" value="[% report.user.phone | html %]" name="phone" id="form_phone" size="15">
+ <small>[% loc('(optional)') %]</small>
+ </div>
+[% END %]
+
diff --git a/templates/web/base/report/new/fill_in_details_text.html b/templates/web/base/report/new/fill_in_details_text.html
new file mode 100644
index 000000000..5d9716915
--- /dev/null
+++ b/templates/web/base/report/new/fill_in_details_text.html
@@ -0,0 +1,13 @@
+[%
+ IF area_ids_to_list.size != 0;
+ loc('Please fill in details of the problem below. The council won\'t be able
+to help unless you leave as much detail as you can, so please describe the exact location of
+the problem (e.g. on a wall), what it is, how long it has been there, a description (and a
+photo of the problem if you have one), etc.');
+ IF category_extras;
+ ' ' _ loc('Some categories may require additional information.');
+ END;
+ ELSE;
+ loc('Please fill in details of the problem below.');
+ END;
+%]
diff --git a/templates/web/base/report/new/form_heading.html b/templates/web/base/report/new/form_heading.html
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/templates/web/base/report/new/form_heading.html
diff --git a/templates/web/base/report/new/notes.html b/templates/web/base/report/new/notes.html
new file mode 100644
index 000000000..68408acc7
--- /dev/null
+++ b/templates/web/base/report/new/notes.html
@@ -0,0 +1,11 @@
+<p style="clear:both">[% loc("Please note:") %]</p>
+
+<ul>
+
+ <li>[% loc("We will only use your personal information in accordance with our <a href=\"/faq#privacy\">privacy policy.</a>") %]</li>
+ <li>[% loc("Please be polite, concise and to the point.") %]</li>
+ <li>[% loc("Please do not be abusive&nbsp;&mdash; abusing your council devalues the service for all users.") %]</li>
+ <li>[% loc("Writing your message entirely in block capitals makes it hard to read, as does a lack of punctuation.") %]</li>
+ <li>[% loc("Remember that FixMyStreet is primarily for reporting physical problems that can be fixed. If your problem is not appropriate for submission via this site remember that you can contact your council directly using their own website.") %]</li>
+
+</ul>
diff --git a/templates/web/base/report/new/report_import.html b/templates/web/base/report/new/report_import.html
new file mode 100644
index 000000000..7aa105afe
--- /dev/null
+++ b/templates/web/base/report/new/report_import.html
@@ -0,0 +1,92 @@
+[% INCLUDE 'header.html', title => 'External import' %]
+
+<h1>External import</h1>
+
+<p>You may inject problem reports into FixMyStreet programatically using this
+simple interface. Upon receipt, an email will be sent to the address given,
+with a link the user must click in order to check the details of their report,
+add any other information they wish, and then submit to the council.
+
+<p>This interface returns a plain text response; either <samp>SUCCESS</samp> if
+the report has been successfully received, or if not, a list of errors, one per
+line each starting with <samp>ERROR:</samp>.
+
+<p>You may submit the following information by POST to this URL
+(i.e. <samp>[% c.uri_for('/import') %]</samp> ):</p>
+
+<style type="text/css" media="screen">
+ input {
+ /* Hide the form elements - they are just here for simpler testing */
+ display: none;
+ }
+</style>
+
+<form method="POST" action="/import" enctype="multipart/form-data">
+
+<dl>
+ <dt>service</dt>
+ <dd>
+ <em>Required</em>.
+ Name of application/service using this interface.
+ <input type="text" name="service" />
+ </dd>
+
+ <dt>id</dt>
+ <dd>
+ Unique ID of a user/device, for possible future use.<br>
+ <small>(e.g. used by Flickr import to know which accounts to look at)</small>
+ <input type="text" name="id" />
+ </dd>
+
+ <dt>subject</dt>
+ <dd>
+ <em>Required</em>. Subject of problem report.
+ <input type="text" name="subject" />
+ </dd>
+
+ <dt>detail</dt>
+ <dd>
+ Main body and details of problem report.
+ <input type="text" name="detail" />
+ </dd>
+
+ <dt>name</dt>
+ <dd>
+ <em>Required</em>. Name of problem reporter.
+ <input type="text" name="name" />
+ </dd>
+
+ <dt>email</dt>
+ <dd>
+ <em>Required</em>. Email address of problem reporter.
+ <input type="text" name="email" />
+ </dd>
+
+ <dt>phone</dt>
+ <dd>
+ Telephone number of problem reporter.
+ <input type="text" name="phone" />
+ </dd>
+
+ <dt>easting / northing</dt>
+ <dt>lat / lon</dt>
+ <dd>
+ Location of problem report. You can either supply eastings/northings, or WGS84 latitude/longitude.
+ <input type="text" name="easting" />
+ <input type="text" name="northing" />
+ <input type="text" name="lat" />
+ <input type="text" name="lon" />
+ </dd>
+
+ <dt>photo</dt>
+ <dd>
+ Photo of problem (JPEG only).
+ <input type="file" name="photo" />
+ </dd>
+</dl>
+
+<input type="submit" />
+
+</form>
+
+[% INCLUDE 'footer.html' %] \ No newline at end of file
diff --git a/templates/web/base/report/photo.html b/templates/web/base/report/photo.html
new file mode 100644
index 000000000..c463c34c4
--- /dev/null
+++ b/templates/web/base/report/photo.html
@@ -0,0 +1,8 @@
+[% IF c.cobrand.allow_photo_display(object) && object.photo %]
+[% photo = object.get_photo_params %]
+<div class="update-img">
+ [% IF photo.url_full %]<a href="[% photo.url_full %]" rel="fancy">[% END
+ %]<img alt="Photo of this report" [% IF photo.height %]height="[% photo.height %]" width="[% photo.width %]"[% END %] src="[% photo.url %]">
+ [%- IF photo.url_full %]<span>zoom</span></a>[% END %]
+</div>
+[% END %]
diff --git a/templates/web/base/report/update-form.html b/templates/web/base/report/update-form.html
new file mode 100644
index 000000000..50bc2906c
--- /dev/null
+++ b/templates/web/base/report/update-form.html
@@ -0,0 +1,165 @@
+<div id="update_form">
+
+ <h2>[% loc( 'Provide an update') %]</h2>
+
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ <p>
+ <small>[% loc( 'Please note that updates are not sent to the council. If you leave your name it will be public. Your information will only be used in accordance with our <a href="/faq#privacy">privacy policy</a>' ) %]</small>
+ </p>
+ [% END %]
+
+ [% INCLUDE 'errors.html' %]
+
+ <form method="post" action="[% c.uri_for( '/report/update' ) %]" name="updateForm" class="fieldset validate"[% IF c.cobrand.allow_photo_upload %] enctype="multipart/form-data"[% END %]>
+
+ <input type="hidden" name="submit_update" value="1">
+ <input type="hidden" name="id" value="[% problem.id | html %]">
+
+ [% IF field_errors.update %]
+ <div class='form-error'>[% field_errors.update %]</div>
+ [% END %]
+ <div class="form-field">
+ <label for="form_update">[% loc( 'Update:' ) %]</label>
+ <textarea name="update" id="form_update" rows="7" cols="30" required>[% update.text | html %]</textarea>
+ </div>
+
+ [% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %]
+ <div class="form-field">
+ <label for="form_state">[% loc( 'State:' ) %]</label>
+ <select name="state" id="form_state">
+ [% FOREACH state IN [ ['confirmed', loc('Open')], ['investigating',
+ loc('Investigating')], ['action scheduled', loc('Action Scheduled')],
+ ['in progress', loc('In Progress')], ['duplicate', loc('Duplicate')],
+ ['unable to fix', loc('Unable to fix')], ['not responsible', loc('Not Responsible')],
+ ['fixed', loc('Fixed')] ] %]
+ <option [% 'selected ' IF state.0 == problem.state %] value="[% state.0 %]">[% state.1 %]</option>
+ [% END %]
+ </select>
+ </div>
+ [% ELSE %]
+ [% IF problem.is_fixed AND c.user_exists AND c.user.id == problem.user_id %]
+ <div class="checkbox">
+ <input type="checkbox" name="reopen" id="form_reopen" value="1"[% ' checked' IF update.mark_open %]>
+ <label class="inline" for="form_reopen">[% loc('This problem has not been fixed') %]</label>
+ </div>
+ [% ELSIF !problem.is_fixed %]
+ <div class="checkbox">
+ <input type="checkbox" name="fixed" id="form_fixed" value="1"[% ' checked' IF update.mark_fixed %]>
+ <label class="inline" for="form_fixed">[% loc('This problem has been fixed') %]</label>
+ </div>
+ [% END %]
+ [% END %]
+
+ [% IF c.cobrand.allow_photo_upload %]
+ [% IF field_errors.photo %]
+ <div class='form-error'>[% field_errors.photo %]</div>
+ [% END %]
+ <div id="fileupload_normalUI">
+ [% IF upload_fileid %]
+ <p>[% loc('You have already attached a photo to this update, attaching another one will replace it.') %]</p>
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ [% END %]
+ <label for="form_photo">[% loc('Photo:') %]</label>
+ <input type="file" name="photo" id="form_photo" style="width:20em">
+ </div>
+ [% END %]
+
+[% IF c.user_exists %]
+
+ [% INCLUDE name %]
+
+ <div class="checkbox">
+ <input type="submit" id="update_post" value="[% loc('Post') %]">
+ </div>
+
+[% ELSE %]
+
+ [% IF field_errors.email %]
+ <div class='form-error'>[% field_errors.email %]</div>
+ [% END %]
+ <div class="form-field">
+ <label for="form_rznvy">[% loc('Your email:' ) %]</label>
+ <input type="email" name="rznvy" id="form_rznvy" value="[% update.user.email | html %]" size="30" required>
+ </div>
+
+<div id="form_sign_in">
+ <h3>[% loc("Now to submit your update&hellip; do you have a FixMyStreet password?") %]</h3>
+
+ <div id="form_sign_in_yes">
+
+ [% IF field_errors.password %]
+ <div class='form-error'>[% field_errors.password %]</div>
+ [% END %]
+
+ <p>
+ <label class="n" for="password_sign_in">[% loc('<strong>Yes</strong> I have a password') %]</label>
+ <input type="password" name="password_sign_in" id="password_sign_in" value="" size="25">
+ </p>
+
+ <div class="fieldset">
+
+ <p>
+ <input type="checkbox" id="remember_me" name="remember_me" value='1'[% ' checked' IF remember_me %]>
+ <label class="n" for="remember_me">
+ [% loc('Keep me signed in on this computer') %]
+ </label>
+ </p>
+
+ <p>
+ <input type="submit" name="submit_sign_in" id="submit_sign_in" value="[% loc('Post') %]">
+ </p>
+
+ </div>
+
+ </div>
+ <div id="form_sign_in_no">
+
+ <p>[% loc('<strong>No</strong>, let me confirm my update by email:') %]</p>
+
+ <div class="fieldset">
+
+ [% INCLUDE name %]
+
+ <div class="form-field">
+ <label for="password_register">[% loc('Enter a new password:') %]</label>
+ <input type="password" name="password_register" id="password_register" value="" size="25">
+ </div>
+
+ <p style="clear:both"><small>[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]</small></p>
+
+ <p>
+ <input type="submit" name="submit_register" id="submit_register" value="[% loc('Post') %]">
+ </p>
+
+ </div>
+
+ </div>
+
+</div>
+
+[% END %]
+
+ </form>
+</div>
+
+[% BLOCK name %]
+ [% IF field_errors.name %]
+ <div class='form-error'>[% field_errors.name %]</div>
+ [% END %]
+
+ <div>
+ <label for="form_name">[% loc('Your name:') %]</label>
+ <input type="text" name="name" id="form_name" value="[% update.name || c.user.name | html %]" size="25">
+ </div>
+
+ <div class="checkbox">
+ <input type="checkbox" name="may_show_name" id="form_may_show_name" value="1"[% ' checked' IF update.anonymous==0 OR (c.cobrand.default_show_name AND update.anonymous=='') %]>
+ <label for="form_may_show_name">[% loc('Show my name publicly') %]</label>
+ <small>[% loc('(we never show your email)') %]</small>
+ </div>
+
+ <div class="checkbox">
+ <input type="checkbox" name="add_alert" id="form_add_alert" value="1"[% ' checked' IF add_alert %]>
+ <label class="inline" for="form_add_alert">[% loc( 'Alert me to future updates' ) %]</label>
+ </div>
+[% END %]
diff --git a/templates/web/base/report/update.html b/templates/web/base/report/update.html
new file mode 100644
index 000000000..048968eae
--- /dev/null
+++ b/templates/web/base/report/update.html
@@ -0,0 +1,22 @@
+[% IF loop.first %]
+<div id="updates">
+ <h2 class="problem-update-list-header">[% loc('Updates') %]</h2>
+[% END %]
+ <div><div class="problem-update"><p><a name="update_[% update.id %]"></a><em>
+ [% INCLUDE meta_line %]
+ </em></p></div>
+[% IF NOT update.whenanswered %]
+ <div class="update-text">
+ [% add_links( update.text ) | html_para %]
+
+ [% INCLUDE 'report/photo.html' object=update %]
+
+ [% IF c.cobrand.allow_update_reporting %]
+ <p align="right">
+ <small><a rel="nofollow" class="unsuitable-problem" href="[% c.uri_for( '/contact', { id => update.problem_id, update_id => update.id } ) %]">[% loc('Offensive? Unsuitable? Tell us') %]</a></small>
+ </p>
+ [% END %]
+ </div>
+[% END %]
+ </div>
+[% '</div>' IF loop.last %]
diff --git a/templates/web/base/report/updates.html b/templates/web/base/report/updates.html
new file mode 100644
index 000000000..b0a015f03
--- /dev/null
+++ b/templates/web/base/report/updates.html
@@ -0,0 +1,64 @@
+[% global.last_state = '' %]
+[% FOREACH update IN updates %]
+[% INCLUDE 'report/update.html' %]
+[% END %]
+
+[% BLOCK meta_line %]
+
+ [% IF update.whenanswered %]
+ [%# A questionnaire update, currently saying report is still open %]
+ [% 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 ) ) -%]
+ [%- 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 ) ) -%]
+ [%- ELSE %]
+ [% 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 %]
+ [%- IF update.mark_open %][% update_state = loc( 'reopened' ) %][% END %]
+ [%- IF !update_state && update.problem_state %]
+ [%- state = update.meta_problem_state %]
+ [%- IF c.cobrand.moniker == 'bromley' OR problem.bodies_str == '2482' %]
+ [%- SET update_state = 'marked as no further action' IF state == 'unable to fix' %]
+ [%- SET update_state = 'marked as third party responsibility' IF state == 'not responsible' %]
+ [%- END %]
+ [%- END %]
+ [%- IF !update_state && update.problem_state %]
+ [%- IF state == 'confirmed' AND global.last_state != '' %]
+ [%- update_state = loc( 'reopened' ) %]
+ [%- ELSIF state == 'investigating' %]
+ [%- update_state = loc( 'marked as investigating' ) %]
+ [%- ELSIF state == 'planned' %]
+ [%- update_state = loc( 'marked as planned' ) %]
+ [%- ELSIF state == 'in progress' %]
+ [%- update_state = loc( 'marked as in progress' ) %]
+ [%- ELSIF state == 'action scheduled' %]
+ [%- update_state = loc( 'marked as action scheduled' ) %]
+ [%- ELSIF state == 'closed' %]
+ [%- update_state = loc( 'marked as closed' ) %]
+ [%- ELSIF state == 'fixed' %]
+ [%- update_state = loc( 'marked as fixed' ) %]
+ [%- ELSIF state == 'unable to fix' %]
+ [%- update_state = loc( 'marked as unable to fix' ) %]
+ [%- ELSIF state == 'not responsible' %]
+ [%- update_state = loc( "marked as not the council's responsibility" ) %]
+ [%- ELSIF state == 'duplicate' %]
+ [%- update_state = loc( 'marked as a duplicate report' ) %]
+ [%- ELSIF state == 'internal referral' %]
+ [%- update_state = loc( 'marked as an internal referral' ) %]
+ [%- END %]
+ [%- END %]
+ [%- ", " _ update_state IF update_state != global.last_state %]
+ [%- global.last_state = update_state %]
+[% END %]
diff --git a/templates/web/base/report_created.html b/templates/web/base/report_created.html
new file mode 100644
index 000000000..81083654b
--- /dev/null
+++ b/templates/web/base/report_created.html
@@ -0,0 +1,9 @@
+[% INCLUDE 'header.html', title => loc('Report created') %]
+
+<h1>[% loc("Report created") %]</h1>
+
+<p>
+[% loc('Your report has been created and will shortly be sent.') %]
+</p>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/reports/_list-entry.html b/templates/web/base/reports/_list-entry.html
new file mode 100755
index 000000000..445a5315f
--- /dev/null
+++ b/templates/web/base/reports/_list-entry.html
@@ -0,0 +1,6 @@
+<li><a href="[% c.uri_for('/report/' _ problem.id) %]">[% problem.title | html %]</a>
+ [% IF problem.bodies_str_ids.size > 1 %] <small>[% loc('(sent to both)') %]</small> [% END %]
+ [% IF c.cobrand.moniker != 'emptyhomes' %]
+ [% IF problem.bodies_str_ids.size == 0 %] <small>[% loc('(not sent to council)') %]</small> [% END %]
+ [% END %]
+</li>
diff --git a/templates/web/base/reports/_rss.html b/templates/web/base/reports/_rss.html
new file mode 100644
index 000000000..9756f131d
--- /dev/null
+++ b/templates/web/base/reports/_rss.html
@@ -0,0 +1,2 @@
+<p><a href="[% rss_url %]"><img align="right" src="/i/feed.png" width="16" height="16" title="[% loc('RSS feed') %]" alt="[% tprintf(loc('RSS feed of problems in this %s'), thing) %]" border="0" hspace="4"></a>
+
diff --git a/templates/web/base/reports/_ward-list.html b/templates/web/base/reports/_ward-list.html
new file mode 100755
index 000000000..e78ac7d90
--- /dev/null
+++ b/templates/web/base/reports/_ward-list.html
@@ -0,0 +1,9 @@
+[% IF location == 'before' AND children.size %]
+<h2 style="clear:right">[% ward_text %]</h2>
+<p>[% loc('Follow a ward link to view only reports within that ward.') %]</p>
+<ul>
+[% FOR child IN children.values.sort('name') %]
+<li><a href="[% child.url %]">[% child.name %]</a></li>
+[% END %]
+</ul>
+[% END %]
diff --git a/templates/web/base/reports/body.html b/templates/web/base/reports/body.html
new file mode 100755
index 000000000..1b6a3a157
--- /dev/null
+++ b/templates/web/base/reports/body.html
@@ -0,0 +1,111 @@
+[% IF ward %]
+ [% name = "$ward.name, $body.name"
+ thing = loc('ward')
+ %]
+[% ELSE %]
+ [% name = body.name
+ thing = loc('council')
+ %]
+[% END %]
+
+[% IF c.cobrand.moniker == 'oxfordshire' %]
+ [% ward_text = 'View reports by division' %]
+[% ELSIF c.cobrand.is_council %]
+ [% ward_text = loc( 'View reports by ward' ) %]
+[% ELSE %]
+ [% ward_text = loc( 'Wards of this council' ) %]
+[% END %]
+
+[%
+ PROCESS "maps/${map.type}.html";
+ INCLUDE 'header.html',
+ title = tprintf(loc('%s - Summary reports'), name)
+ bodyclass = 'mappage'
+ rss = [ tprintf(loc('Problems within %s, FixMyStreet'), name), rss_url ]
+%]
+
+[% map_html %]
+
+[% INCLUDE 'reports/_ward-list.html', location = 'before' %]
+
+</div>
+<div id="side">
+
+<h1 id="reports_heading">
+ [% IF ward %]
+ [% ward.name %]<span>, </span><a href="[% body_url %]">[% body.name %]</a>
+ [% ELSE %]
+ [% body.name %]
+ [% END %]
+</h1>
+
+[% IF c.cobrand.moniker == 'hart' %]
+ [% INCLUDE '_hart_hants_note.html' %]
+[% END %]
+
+[% IF NOT body.areas.size AND c.cobrand.country == 'GB' %]
+ <p id="unknown" class="alert">This council no longer exists.
+ [% IF council.name.match('Penwith|Kerrier|Carrick|Restormel|Caradon|North Cornwall') %]
+ Its area is now covered by <a href="/reports/Cornwall">Cornwall Council</a>.
+ [% ELSIF council.name.match('Durham|Easington|Sedgefield|Teesdale|Wear Valley|Derwentside|Chester le Street') %]
+ Its area is now covered by <a href="/reports/Durham+County">Durham County Council</a>.
+ [% ELSIF council.name.match('Blyth Valley|Wansbeck|Castle Morpeth|Tynedale|Alnwick|Berwick upon Tweed') %]
+ Its area is now covered by <a href="/reports/Northumberland">Northumberland County Council</a>.
+ [% ELSIF council.name.match('North Shropshire|Oswestry|Shrewsbury and Atcham|South Shropshire|Bridgnorth') %]
+ Its area is now covered by <a href="/reports/Shropshire">Shropshire Council</a>.
+ [% ELSIF council.name.match('Salisbury|West Wiltshire|Kennet|North Wiltshire') %]
+ Its area is now covered by <a href="/reports/Wiltshire">Wiltshire Council</a>.
+ [% ELSIF council.name.match('Ellesmere Port and Neston|Vale Royal|Chester') %]
+ Its area is now covered by <a href="/reports/Cheshire+West+and+Chester">Cheshire West and Chester Council</a>.
+ [% ELSIF council.name.match('Macclesfield|Congleton|Crewe and Nantwich') %]
+ Its area is now covered by <a href="/reports/Cheshire+East">Cheshire East Council</a>.
+ [% ELSIF council.name.match('Mid Bedfordshire|South Bedfordshire') %]
+ Its area is now covered by <a href="/reports/Central+Bedfordshire">Central Bedfordshire Council</a>.
+ [% ELSIF council.name.match('Cheshire') %]
+ Its area is now covered by <a href="/reports/Cheshire+West+and+Chester">Cheshire West and Chester Council</a> or
+ <a href="/reports/Cheshire+East">Cheshire East Council</a>.
+ [% ELSIF council.name.match('Bedfordshire') %]
+ Its area is now covered by <a href="/reports/Bedford">Bedford Borough Council</a> or
+ <a href="/reports/Central+Bedfordshire">Central Bedfordshire Council</a>.
+ [% END %]
+ </p>
+[% ELSE %]
+ [% INCLUDE 'reports/_rss.html' %]
+[% END %]
+
+[% TRY %][% INCLUDE 'reports/cobrand_stats.html' %][% CATCH file %][% END %]
+
+[% INCLUDE 'reports/_ward-list.html', location = 'after' %]
+
+[% IF c.cobrand.moniker == 'fixmystreet' %]
+<p class="promo">
+ FixMyStreet is now available for local council websites.
+ <a href="https://www.mysociety.org/services/fixmystreet-for-councils/">Find&nbsp;out&nbsp;more</a>.
+</p>
+[% END %]
+
+[% INCLUDE 'pagination.html', param = 'p' %]
+
+<section class="full-width">
+ [% INCLUDE column
+ problems = problems.${body.id}
+ %]
+</section>
+
+[% INCLUDE 'pagination.html', param = 'p' %]
+
+</div>
+[% INCLUDE 'footer.html' %]
+
+[% BLOCK column %]
+[% IF problems %]
+
+<ul class="issue-list-a">
+[% FOREACH problem IN problems %]
+ [% INCLUDE 'reports/_list-entry.html' %]
+[% END %]
+</ul>
+
+[% END %]
+[% END %]
+
diff --git a/templates/web/base/reports/index.html b/templates/web/base/reports/index.html
new file mode 100755
index 000000000..1e4130a37
--- /dev/null
+++ b/templates/web/base/reports/index.html
@@ -0,0 +1,42 @@
+[% INCLUDE 'header.html', title = loc('Summary reports'), bodyclass => 'fullwidthpage' %]
+
+<h1>[% loc('All Reports') %]</h1>
+
+<div class="intro">
+<p>
+[% loc('This is a summary of all reports on this site; select a particular council to see the reports sent there.') %]
+[% loc('Greyed-out lines are councils that no longer exist.') %]
+</p>
+</div>
+
+<table cellpadding="3" cellspacing="1" border="0" class="nicetable">
+<thead>
+<tr>
+<th class="title">[% loc('Name') %]</th>
+<th class="data">[% loc('New <br>problems') %]</th>
+<th class="data">[% loc('Older <br>problems') %]</th>
+<th class="data">[% loc('Old / unknown <br>problems') %]</th>
+<th class="data">[% loc('Recently <br>fixed') %]</th>
+<th class="data">[% loc('Older <br>fixed') %]</th>
+</tr>
+</thead>
+
+<tbody>
+[% FOREACH body IN bodies %]
+<tr align="center"
+[%- IF NOT body.areas.size %] class="gone"
+[%- ELSIF ! (loop.count % 2) %] class="a"
+[%- END %]>
+<td class="title"><a href="[% body.url(c) %]">[% body.name %]</a></td>
+<td class="data">[% IF open.${body.id}.new %]<a href="[% body.url(c, { t => 'new' }) %]">[% open.${body.id}.new %]</a>[% ELSE %]0[% END %]</td>
+<td class="data">[% IF open.${body.id}.older %]<a href="[% body.url(c, { t => 'older' }) %]">[% open.${body.id}.older %]</a>[% ELSE %]0[% END %]</td>
+<td class="data">[% IF open.${body.id}.unknown %]<a href="[% body.url(c, { t => 'unknown' }) %]">[% open.${body.id}.unknown %]</a>[% ELSE %]0[% END %]</td>
+<td class="data">[% IF fixed.${body.id}.new %]<a href="[% body.url(c, { t => 'fixed' }) %]">[% fixed.${body.id}.new %]</a>[% ELSE %]0[% END %]</td>
+<td class="data">[% IF fixed.${body.id}.old %]<a href="[% body.url(c, { t => 'older_fixed' }) %]">[% fixed.${body.id}.old %]</a>[% ELSE %]0[% END %]</td>
+</tr>
+[% TRY %][% PROCESS "reports/_extras.html" %][% CATCH file %][% END %]
+[% END %]
+</tbody>
+</table>
+
+[% INCLUDE 'footer.html', pagefooter = 'yes' %]
diff --git a/templates/web/base/reports/ward.html b/templates/web/base/reports/ward.html
new file mode 100755
index 000000000..4b2ea29a5
--- /dev/null
+++ b/templates/web/base/reports/ward.html
@@ -0,0 +1 @@
+[% INCLUDE reports/body.html %]
diff --git a/templates/web/base/static/about-en-gb.html b/templates/web/base/static/about-en-gb.html
new file mode 100644
index 000000000..9c319f051
--- /dev/null
+++ b/templates/web/base/static/about-en-gb.html
@@ -0,0 +1,9 @@
+[% INCLUDE 'header.html', title => loc('About us') %]
+
+<h1>[% loc('About us') %]</h1>
+
+<h2>FixMyStreet.com</h2>
+
+[%# FIXME - put in blurb here %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/static/iphone.html b/templates/web/base/static/iphone.html
new file mode 100755
index 000000000..8f7992713
--- /dev/null
+++ b/templates/web/base/static/iphone.html
@@ -0,0 +1,52 @@
+[% INCLUDE header.html
+ title = 'FixMyStreet for iPhone screenshots'
+%]
+
+<h1>iPhone simulator simulator</h1>
+
+[%
+ SET screens = [
+ [ "iphone-1start.png", 'Click the image to progress through the flow of using the iPhone FixMyStreet application.
+ <br>When launched, the user&rsquo;s location automatically gets fetched&hellip;' ],
+ [ "iphone-2locfound.png", 'They want to take a photo.' ],
+ [ "iphone-pickpicture1.png", 'The simulator doesn&rsquo;t have a camera, so we&rsquo;re taken to the photo albums. Let&rsquo;s pick Hawaii.' ],
+ [ "iphone-pickpicture2.png", 'That red clouds photo looks nice.' ],
+ [ "iphone-pickpicture3.png", 'After any moving or scaling we want, we select the photo.' ],
+ [ "iphone-3picture.png", 'Okay, now we need to edit the summary of the report.' ],
+ [ "iphone-editsummary.png", 'Enter some text.' ],
+ [ "iphone-editsummary2.png", 'And done.' ],
+ [ "iphone-4subject.png", 'I haven&rsquo;t entered all my details yet, so that&rsquo;s next.' ],
+ [ "iphone-5details.png", 'Your details are remembered so you only have to enter them once.' ],
+ [ "iphone-6emailkeyboard.png", 'The iPhone has different keyboards, this is the email one.' ],
+ [ "iphone-5details.png", 'Right, we need to enter a name.' ],
+ [ "iphone-editname.png", 'Slightly different keyboard to the email one.' ],
+ [ "iphone-detailsdone.png", 'Okay, details entered.' ],
+ [ "iphone-allready.png", 'That&rsquo;s everything, hit Report!' ],
+ [ "iphone-7uploading.png", 'Uploading&hellip;' ],
+ [ "iphone-8response.png", 'The simulator always thinks it&rsquo;s in the US, which FixMyStreet won&rsquo;t like very much.' ],
+ [ "iphone-allready.png", 'Ah well, let&rsquo;s read the About page instead' ],
+ [ "iphone-9about.png", 'Donate? :)' ],
+];
+%]
+
+<script type="text/javascript">
+document.write('<style type="text/css">.vv { display: none; }</style>');
+function show(a) {
+ if (a==[% screens.size %]) b = 1;
+ else b = a+1;
+ document.getElementById('d' + a).style.display='none';
+ document.getElementById('d' + b).style.display='block';
+}
+</script>
+
+[% FOR screen IN screens %]
+
+ <div id='d[% loop.count %]'[% " class='vv'" IF NOT loop.first %]>
+ <p>[% screen.1 %]</p>
+ <p align='center'><a onclick='show([% loop.count %]);return false' href='#d[% loop.count + 1 %]'><img src='[% screen.0 %]' width=414 border=0 height=770></a></p>
+ </div>
+
+[% END %]
+
+[% INCLUDE footer.html %]
+
diff --git a/templates/web/base/static/posters.html b/templates/web/base/static/posters.html
new file mode 100644
index 000000000..fc5202319
--- /dev/null
+++ b/templates/web/base/static/posters.html
@@ -0,0 +1,43 @@
+[% INCLUDE header.html
+ title = 'Publicity material'
+%]
+
+[%
+ badge = '<a href="https://www.fixmystreet.com/"> <img align="left" hspace="5" src="https://www.fixmystreet.com/i/fms-badge.jpeg" alt="FixMyStreet - report, view or discuss local problems" border="0"></a>'
+%]
+
+<h1>Publicity Material</h1>
+
+<div style='float:left; width:50%'>
+ <p>Copy and paste the text below to add this badge to your site:</p>
+ [% badge %]
+ <textarea onclick="this.select()" cols=37 rows=5>[% badge | html %]</textarea>
+ <p><small>(thanks to Lincolnshire Council for the image)</small></p>
+</div>
+
+<div style='float:right; width:47%'>
+ <p>Here are some posters and flyers you can use to publicise FixMyStreet:</p>
+ <img hspace="5" src="/posters/poster.png" alt='Example poster'>
+ <h2>Posters</h2>
+ <ul>
+ <li><a href='/posters/fixmystreet-poster-a4.pdf'>A4, colour</a>
+ <li><a href='/posters/fixmystreet-poster-a4-bw.pdf'>A4, black and white</a>
+ <li><a href='/posters/fixmystreet-poster-a4-bw-low-ink.pdf'>A4, black and white, low ink</a>
+ <li><a href='/posters/fixmystreet-poster-a4-bw-outlined.pdf'>A4, black and white, outlined</a>
+ </ul>
+ <h2>Posters with tags</h2>
+ <ul>
+ <li><a href='/posters/fixmystreet-poster-tags.pdf'>A4, colour</a>
+ <li><a href='/posters/fixmystreet-poster-tags-bw.pdf'>A4, black and white</a>
+ <li><a href='/posters/fixmystreet-poster-tags-bw-low-ink.pdf'>A4, black and white, low ink</a>
+ <li><a href='/posters/fixmystreet-poster-tags-only.pdf'>A4, tags only</a>
+ </ul>
+ <h2>Flyers</h2>
+ <ul>
+ <li><a href='/posters/fixmystreet-flyers-colour.pdf'>4 x A6, colour</a>
+ <li><a href='/posters/fixmystreet-flyers-bw-outlined.pdf'>4 x A6, black and white, outlined</a>
+ <li><a href='/posters/fixmystreet-flyers-bw-low-ink.pdf'>4 x A6, black and white, low ink</a>
+ </ul>
+</div>
+
+[% INCLUDE footer.html %]
diff --git a/templates/web/base/tokens/abuse.html b/templates/web/base/tokens/abuse.html
new file mode 100644
index 000000000..d1b952621
--- /dev/null
+++ b/templates/web/base/tokens/abuse.html
@@ -0,0 +1,7 @@
+[% INCLUDE 'header.html', title => loc('Error') %]
+
+<h1>[% loc('Error') %]</h1>
+
+<p>[% loc('Sorry, there has been an error confirming your problem.') %]</p>
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/tokens/confirm_alert.html b/templates/web/base/tokens/confirm_alert.html
new file mode 100644
index 000000000..d23a658ec
--- /dev/null
+++ b/templates/web/base/tokens/confirm_alert.html
@@ -0,0 +1,17 @@
+[% INCLUDE 'header.html', title => loc('Local RSS feeds and email alerts') %]
+
+<h1>[% loc('Local RSS feeds and email alerts') %]</h1>
+
+<p>
+[% IF confirm_type == 'subscribe' %]
+ [% loc('You have successfully confirmed your alert.') %]
+[% ELSIF confirm_type == 'unsubscribe' %]
+ [% loc('You have successfully deleted your alert.') %]
+[% ELSIF confirm_type == 'created' %]
+ [% loc('You have successfully created your alert.') %]
+[% END %]
+</p>
+
+[% display_crosssell_advert( alert.user.email, alert.user.name ) %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/tokens/confirm_problem.html b/templates/web/base/tokens/confirm_problem.html
new file mode 100644
index 000000000..723d515e1
--- /dev/null
+++ b/templates/web/base/tokens/confirm_problem.html
@@ -0,0 +1,31 @@
+[% INCLUDE 'header.html', title = loc('Confirmation') %]
+
+<h1>[% loc('Confirmation') %]</h1>
+
+<p class="confirmed">
+[% IF c.cobrand.is_council %]
+Thank you. You have successfully confirmed your report
+and this will now be investigated by the council.
+You can <a href="[% c.cobrand.base_url_for_report( problem ) %][% problem.url %]">view the problem on this site</a>.
+</p>
+
+<p>Your reference for this problem is [% problem.id %], please quote it in any enquiries.
+[% ELSE %]
+[%
+ loc('You have successfully confirmed your problem');
+ IF problem.bodies_str;
+ loc(' and <strong>we will now send it to the council</strong>');
+ END; %].
+[%
+ tprintf(
+ loc( 'You can <a href="%s%s">view the problem on this site</a>.' ),
+ c.cobrand.base_url_for_report( problem ),
+ problem.url
+ );
+%]
+[% END %]
+</p>
+
+[% display_crosssell_advert( problem.user.email, problem.name ) %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/tokens/confirm_update.html b/templates/web/base/tokens/confirm_update.html
new file mode 100644
index 000000000..56f04e12a
--- /dev/null
+++ b/templates/web/base/tokens/confirm_update.html
@@ -0,0 +1,20 @@
+[% INCLUDE 'header.html', title => loc('Confirmation') %]
+
+<h1>[% loc('Confirmation') %]</h1>
+
+<p class="confirmed">
+[% IF creator_fixed %]
+[%
+ tprintf(loc('Thank you &mdash; you can <a href="%s">view your updated problem</a> on the site.'), c.uri_for( '/report', problem_id ) );
+%]
+[% ELSE %]
+[%
+ tprintf( loc('You have successfully confirmed your update and you can now <a href="%s">view it on the site</a>.'), c.uri_for( '/report',
+ update.problem.id ) _ '#update_' _ update.id );
+%]
+[% END %]
+</p>
+
+[% display_crosssell_advert( update.user.email, update.name ) %]
+
+[% INCLUDE 'footer.html' %]
diff --git a/templates/web/base/tokens/error.html b/templates/web/base/tokens/error.html
new file mode 100644
index 000000000..e3fa6c170
--- /dev/null
+++ b/templates/web/base/tokens/error.html
@@ -0,0 +1,9 @@
+[% INCLUDE 'header.html', title => loc('Error') %]
+
+<h1>[% loc('Error') %]</h1>
+
+[% contact_url = c.uri_for('/contact'); %]
+
+<p>[% tprintf( loc('Thank you for trying to confirm your update or problem. We seem to have an error ourselves though, so <a href="%s">please let us know what went on</a> and we\'ll look into it.'), contact_url ) %]</p>
+
+[% INCLUDE 'footer.html' %]