diff --git a/opentech/apply/users/forms.py b/opentech/apply/users/forms.py
index 174d827ba6d736dc059fe951ec9699256df9506c..0f75721f16eae0393031fef5bd344ef3dbea1c76 100644
--- a/opentech/apply/users/forms.py
+++ b/opentech/apply/users/forms.py
@@ -1,8 +1,12 @@
 from django import forms
+from django.contrib.auth import get_user_model
 
 from wagtail.users.forms import UserEditForm, UserCreationForm
 
 
+User = get_user_model()
+
+
 class CustomUserAdminFormBase():
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
@@ -18,3 +22,9 @@ class CustomUserEditForm(CustomUserAdminFormBase, UserEditForm):
 
 class CustomUserCreationForm(CustomUserAdminFormBase, UserCreationForm):
     pass
+
+
+class ProfileForm(forms.ModelForm):
+    class Meta:
+        model = User
+        fields = ['full_name', 'email']
diff --git a/opentech/apply/users/templates/users/account.html b/opentech/apply/users/templates/users/account.html
index 6064bb0670e7036fa21cc62cf863226cace4d7d0..3177476547d1df21cd0c82c377be0603ca29504c 100644
--- a/opentech/apply/users/templates/users/account.html
+++ b/opentech/apply/users/templates/users/account.html
@@ -11,11 +11,25 @@
     </div>
 </div>
 
+<div class="wrapper wrapper--large wrapper--inner-space-medium">
+    <h3>Profile</h3>
+    <form action="" method="post" class="form">
+        {% csrf_token %}
+        {% for field in form %}
+            {% include "funds/includes/field.html" %}
+        {% endfor %}
+        <button class="button button--primary" type="submit">{% trans "Update Profile" %}</button>
+    </form>
+</div>
+
 <div class="wrapper wrapper--large wrapper--inner-space-medium">
     {% if show_change_password and user.has_usable_password and not backends.associated %}
-        <a href="{% url 'users:password_change' %}">{% trans "Change password" %}</a>
+        <h3>Change password</h3>
+        <a class="button button--primary" href="{% url 'users:password_change' %}">{% trans "Update password" %}</a>
     {% endif %}
+</div>
 
+<div class="wrapper wrapper--large wrapper--inner-space-medium">
     {% if swappable %}
         <form action="{% url 'users:become' %}" method="post" class="form">
             {% csrf_token %}
diff --git a/opentech/apply/users/urls.py b/opentech/apply/users/urls.py
index 30dc4c0206e371f3a82583da74df77f43d446070..ddb5fb2634500e85f9f4382dba4354aabbaf32ef 100644
--- a/opentech/apply/users/urls.py
+++ b/opentech/apply/users/urls.py
@@ -2,13 +2,13 @@ from django.urls import path
 from django.contrib.auth import views as auth_views
 from django.urls import reverse_lazy
 
-from opentech.apply.users.views import account, become, oauth, ActivationView, create_password
+from opentech.apply.users.views import AccountView, become, oauth, ActivationView, create_password
 
 
 app_name = 'users'
 
 urlpatterns = [
-    path('', account, name='account'),
+    path('', AccountView.as_view(), name='account'),
     path('become/', become, name='become'),
     path(
         'login/',
diff --git a/opentech/apply/users/views.py b/opentech/apply/users/views.py
index 7669165d9879dc243b4c841f0bd2cf1bc2493671..8f8e3dab59ca43446f461283062957c5c640f132 100644
--- a/opentech/apply/users/views.py
+++ b/opentech/apply/users/views.py
@@ -6,8 +6,10 @@ from django.contrib.auth.tokens import PasswordResetTokenGenerator
 from django.shortcuts import redirect, render
 from django.template.response import TemplateResponse
 from django.urls import reverse_lazy
+from django.utils.decorators import method_decorator
 from django.utils.encoding import force_text
 from django.utils.http import urlsafe_base64_decode
+from django.views.generic import UpdateView
 from django.views.generic.base import TemplateView
 
 from hijack.views import login_with_id
@@ -15,22 +17,36 @@ from hijack.views import login_with_id
 from wagtail.admin.views.account import password_management_enabled
 
 from .decorators import require_oauth_whitelist
+from .forms import ProfileForm
+
 
 User = get_user_model()
 
 
-@login_required(login_url=reverse_lazy('users:login'))
-def account(request):
-    """Account page placeholder view"""
-    if request.user.is_superuser:
-        swappable = User.objects.filter(is_active=True, is_superuser=False)
-    else:
-        swappable = []
+@method_decorator(login_required, name='dispatch')
+class AccountView(UpdateView):
+    form_class = ProfileForm
+    template_name = 'users/account.html'
 
-    return render(request, 'users/account.html', {
-        'show_change_password': password_management_enabled() and request.user.has_usable_password(),
-        'swappable': swappable,
-    })
+    def get_object(self):
+        return self.request.user
+
+    def get_success_url(self,):
+        return reverse_lazy('users:account')
+
+    def get_context_data(self, **kwargs):
+        if self.request.user.is_superuser:
+            swappable = User.objects.filter(is_active=True, is_superuser=False)
+        else:
+            swappable = []
+
+        show_change_password = password_management_enabled() and self.request.user.has_usable_password(),
+
+        return super().get_context_data(
+            swappable=swappable,
+            show_change_password=show_change_password,
+            **kwargs,
+        )
 
 
 @login_required(login_url=reverse_lazy('users:login'))