Add a tour for users new to broadcast services

This is an initial, prototype-quality attempt at introducing some kind
of tour for users new to broadcasting. A lot of the users we’re speaking
to don’t have a good concept of what broadcasting means, which is
causing usability problems down the line.

We did a similar thing in the early days of Notify to explain the
concept of message templates and personalisation.
This commit is contained in:
Chris Hill-Scott
2020-08-03 13:37:34 +01:00
parent b2b58ec044
commit 19b42e3331
16 changed files with 3400 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

File diff suppressed because one or more lines are too long

View File

@@ -78,6 +78,11 @@
box-shadow: inset 0 -1em 1.6em 0 rgba(0, 0, 0, 0.05);
border: 0;
&-no-fixed-height {
height: auto;
min-height: 425px;
}
.heading-medium {
@include core-24;
}
@@ -98,6 +103,18 @@
}
ul {
@include core-24;
color: $white;
margin-bottom: govuk-spacing(5);
}
li {
margin-bottom: govuk-spacing(3);
list-style-type: disc;
margin-left: govuk-spacing(6);
}
a {
font-weight: bold;
@@ -123,6 +140,10 @@
}
}
img {
width: 100%;
height: auto;
}
.greyed-out-step {
opacity: 0.6;

View File

@@ -19,6 +19,17 @@ from app.models.broadcast_message import BroadcastMessage, BroadcastMessages
from app.utils import service_has_permission, user_has_permissions
@main.route('/services/<uuid:service_id>/broadcast-tour/<int:step_index>')
@user_has_permissions()
@service_has_permission('broadcast')
def broadcast_tour(service_id, step_index):
if step_index not in (1, 2, 3):
abort(404)
return render_template(
f'views/broadcast/tour/{step_index}.html'
)
@main.route('/services/<uuid:service_id>/broadcast-dashboard')
@user_has_permissions()
@service_has_permission('broadcast')

View File

@@ -40,6 +40,9 @@ def accept_invite(token):
if invited_user.status == 'accepted':
session.pop('invited_user', None)
service = Service.from_id(invited_user.service)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=invited_user.service))
session['invited_user'] = invited_user.serialize()
@@ -66,6 +69,8 @@ def accept_invite(token):
permissions=invited_user.permissions,
folder_permissions=invited_user.folder_permissions,
)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=service.id))
else:
return redirect(url_for('main.register_from_invite'))

View File

@@ -15,6 +15,7 @@ from notifications_utils.url_safe_token import check_token
from app import user_api_client
from app.main import main
from app.main.forms import TwoFactorForm
from app.models.service import Service
from app.models.user import InvitedUser, User
from app.utils import redirect_to_sign_in
@@ -77,6 +78,9 @@ def activate_user(user_id):
invited_user = session.get('invited_user')
if invited_user:
service_id = _add_invited_user_to_service(invited_user)
service = Service.from_id(service_id)
if service.has_permission('broadcast'):
return redirect(url_for('main.broadcast_tour', service_id=service.id, step_index=1))
return redirect(url_for('main.service_dashboard', service_id=service_id))
invited_org_user = session.get('invited_org_user')

View File

@@ -352,6 +352,7 @@ class HeaderNavigation(Navigation):
'old_guest_list',
'who_can_use_notify',
'who_its_for',
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'broadcast',
@@ -375,6 +376,7 @@ class MainNavigation(Navigation):
mapping = {
'dashboard': {
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'conversation',
@@ -702,6 +704,7 @@ class CaseworkNavigation(Navigation):
mapping = {
'dashboard': {
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
},
@@ -1330,6 +1333,7 @@ class OrgNavigation(Navigation):
'old_guest_list',
'who_can_use_notify',
'who_its_for',
'broadcast_tour',
'broadcast_dashboard',
'broadcast_dashboard_updates',
'broadcast',

View File

@@ -10,6 +10,14 @@
<h1 class="govuk-visually-hidden">Dashboard</h1>
{% if current_user.has_permissions('manage_templates') and not current_service.all_templates %}
<nav class="govuk-!-margin-top-2 govuk-!-margin-bottom-6">
<a class="govuk-link govuk-link--no-visited-state pill-separate-item govuk-!-padding-top-4 govuk-!-padding-bottom-4 govuk-!-font-weight-bold" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
Start by creating a template
</a>
</nav>
{% endif %}
<h2 class="heading-medium govuk-!-margin-bottom-2">Live broadcasts</h2>
{{ ajax_block(

View File

@@ -0,0 +1,41 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 1
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
Youve been invited to use GOV.UK Notify to broadcast alerts
</h1>
<ul>
<li>
Broadcasting is a new technology for alerting members of the
public
</li>
<li>
It should be used when theres an imminent risk to life
</li>
</ul>
<p class="govuk-body heading-medium">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".broadcast_tour", service_id=current_service.id, step_index=2) }}'>
Find out how it works
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/1.png') }}" alt="">
<link rel="preload" href="{{ asset_url('images/broadcast-tour/2.png') }}" as="image">
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,44 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 2
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
A broadcast will alert every phone in an area
</h1>
<ul>
<li>
The alert will appear even if the phones screen is locked
</li>
<li>
The phone will play an alarm sound even if its set to silent
</li>
<li>
Any phone that enters the area while the broadcast is live will
get the alert
</li>
</ul>
<p class="govuk-body heading-medium govuk-!-margin-bottom-6">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".broadcast_tour", service_id=current_service.id, step_index=3) }}'>
How to try it out
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/2.png') }}" alt="">
<link rel="preload" href="{{ asset_url('images/broadcast-tour/3.png') }}" as="image">
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,43 @@
{% from "components/banner.html" import banner_wrapper %}
{% extends "admin_template.html" %}
{% block per_page_title %}
Step 3
{% endblock %}
{% set mainClasses = "govuk-!-padding-top-0 govuk-!-padding-bottom-0" %}
{% block content %}
<div class="banner-tour banner-tour-no-fixed-height govuk-!-margin-top-0">
<div class="govuk-grid-row">
<div class="govuk-grid-column-one-half">
<h1 class="heading-medium">
You have a trial account
</h1>
<ul>
<li>
Theres no risk of triggering a real, live broadcast
</li>
<li>
Get familiar with the system now, so youre ready to use it if
theres an emergency
</li>
<li>
When youre ready, apply for a live account
</li>
</ul>
<p class="govuk-body heading-medium">
<a class="govuk-link govuk-link--no-visited-state" href='{{ url_for(".service_dashboard", service_id=current_service.id) }}'>
Continue to dashboard
</a>
</p>
</div>
<div class="govuk-grid-column-one-half">
<img src="{{ asset_url('images/broadcast-tour/3.png') }}" alt="">
</div>
</div>
</div>
{% endblock %}