corporate: Add contact support page.

This commit is contained in:
Eeshan Garg 2021-09-29 13:51:55 -04:00 committed by Tim Abbott
parent c750d0e404
commit 763b3c27d6
13 changed files with 228 additions and 9 deletions

15
corporate/lib/support.py Normal file
View File

@ -0,0 +1,15 @@
from urllib.parse import urlencode, urljoin, urlunsplit
from django.conf import settings
from django.urls import reverse
from zerver.models import Realm, get_realm
def get_support_url(realm: Realm) -> str:
support_realm_uri = get_realm(settings.STAFF_SUBDOMAIN).uri
support_url = urljoin(
support_realm_uri,
urlunsplit(("", "", reverse("support"), urlencode({"q": realm.string_id}), "")),
)
return support_url

View File

@ -1487,6 +1487,41 @@ class StripeTest(StripeTestCase):
self.assert_json_success(response)
def test_support_request(self) -> None:
user = self.example_user("hamlet")
self.assertIsNone(get_customer_by_realm(user.realm))
self.login_user(user)
result = self.client_get("/support/")
self.assertEqual(result.status_code, 200)
self.assert_in_success_response(["Contact support"], result)
data = {
"request_subject": "Not getting messages.",
"request_message": "Running into this weird issue.",
}
result = self.client_post("/support/", data)
self.assert_in_success_response(["Thanks for getting in touch with us!"], result)
from django.core.mail import outbox
self.assert_length(outbox, 1)
for message in outbox:
self.assert_length(message.to, 1)
self.assertEqual(message.to[0], "desdemona+admin@zulip.com")
self.assertEqual(message.subject, "Support request for zulip")
self.assertEqual(message.reply_to, ["hamlet@zulip.com"])
self.assertEqual(self.email_envelope_from(message), settings.NOREPLY_EMAIL_ADDRESS)
self.assertIn("Zulip Support <noreply-", self.email_display_from(message))
self.assertIn("Requested by: King Hamlet (Member)", message.body)
self.assertIn(
"Support URL: http://zulip.testserver/activity/support?q=zulip", message.body
)
self.assertIn("Subject: Not getting messages.", message.body)
self.assertIn("Message:\nRunning into this weird issue", message.body)
def test_request_sponsorship(self) -> None:
user = self.example_user("hamlet")
self.assertIsNone(get_customer_by_realm(user.realm))

View File

@ -5,6 +5,7 @@ from django.urls import path
from django.views.generic import TemplateView
from corporate.views.billing_page import billing_home, replace_payment_source, update_plan
from corporate.views.support import support_request
from corporate.views.upgrade import initial_upgrade, sponsorship, upgrade
from zerver.lib.rest import rest_path
@ -16,6 +17,7 @@ i18n_urlpatterns: Any = [
# Billing
path("billing/", billing_home),
path("upgrade/", initial_upgrade, name="initial_upgrade"),
path("support/", support_request),
]
v1_api_and_json_patterns = [

View File

@ -0,0 +1,58 @@
from django import forms
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from corporate.lib.support import get_support_url
from zerver.decorator import zulip_login_required
from zerver.lib.request import has_request_variables
from zerver.lib.send_email import FromAddress, send_email
class SupportRequestForm(forms.Form):
# We use the same subject length requirement as GitHub's
# contact support form.
MAX_SUBJECT_LENGTH = 50
request_subject = forms.CharField(max_length=MAX_SUBJECT_LENGTH)
request_message = forms.CharField(widget=forms.Textarea)
@zulip_login_required
@has_request_variables
def support_request(request: HttpRequest) -> HttpResponse:
user = request.user
assert user.is_authenticated
context = {
"email": user.delivery_email,
"realm_name": user.realm.name,
"MAX_SUBJECT_LENGTH": SupportRequestForm.MAX_SUBJECT_LENGTH,
}
if request.POST:
post_data = request.POST.copy()
form = SupportRequestForm(post_data)
if form.is_valid():
email_context = {
"requested_by": user.full_name,
"realm_string_id": user.realm.string_id,
"request_subject": form.cleaned_data["request_subject"],
"request_message": form.cleaned_data["request_message"],
"support_url": get_support_url(user.realm),
"user_role": user.get_role_name(),
}
send_email(
"zerver/emails/support_request",
to_emails=[FromAddress.SUPPORT],
from_name="Zulip Support",
from_address=FromAddress.tokenized_no_reply_address(),
reply_to_email=user.delivery_email,
context=email_context,
)
response = render(request, "corporate/support_request_thanks.html", context=context)
return response
response = render(request, "corporate/support_request.html", context=context)
return response

View File

@ -1,7 +1,6 @@
import logging
from decimal import Decimal
from typing import Any, Dict, Optional
from urllib.parse import urlencode, urljoin, urlunsplit
from django import forms
from django.conf import settings
@ -24,6 +23,7 @@ from corporate.lib.stripe import (
update_sponsorship_status,
validate_licenses,
)
from corporate.lib.support import get_support_url
from corporate.models import (
CustomerPlan,
ZulipSponsorshipRequest,
@ -37,7 +37,7 @@ from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success
from zerver.lib.send_email import FromAddress, send_email
from zerver.lib.validator import check_bool, check_int, check_string_in
from zerver.models import Realm, UserProfile, get_org_type_display_name, get_realm
from zerver.models import Realm, UserProfile, get_org_type_display_name
billing_logger = logging.getLogger("corporate.stripe")
@ -221,12 +221,7 @@ def sponsorship(
requested_by = user.full_name
user_role = user.get_role_name()
support_realm_uri = get_realm(settings.STAFF_SUBDOMAIN).uri
support_url = urljoin(
support_realm_uri,
urlunsplit(("", "", reverse("support"), urlencode({"q": realm.string_id}), "")),
)
support_url = get_support_url(realm)
post_data = request.POST.copy()
# We need to do this because the field name in the template

View File

@ -286,6 +286,10 @@ html {
text-align: center;
}
.thanks-page div {
text-align: center;
}
.lead {
font-weight: bold;
}

View File

@ -417,6 +417,7 @@ html {
input[type="text"],
input[type="email"],
input[type="password"],
textarea,
select {
padding: 10px 32px 10px 12px;
margin: 25px 0 5px;
@ -815,6 +816,16 @@ button#register_auth_button_gitlab {
margin-left: 2px;
}
}
&.support-form-field {
width: 450px;
input,
textarea {
width: 400px;
font-size: 1rem;
}
}
}
& [for="realm_in_root_domain"] {
@ -831,6 +842,12 @@ button#register_auth_button_gitlab {
border-radius: 4px;
}
.support-submit-button {
margin-top: 20px;
margin-bottom: 5px;
width: 450px;
}
.register-button .loader {
display: none;
vertical-align: top;
@ -868,7 +885,9 @@ button#register_auth_button_gitlab {
}
}
#id_email {
#id_email,
#support_from,
#support_realm {
font-weight: normal;
margin: 2px;
padding-top: 25px;

View File

@ -0,0 +1,43 @@
{% extends "zerver/portico_signup.html" %}
{% block portico_content %}
<div class="register-account flex full-page">
<div class="center-block new-style">
<div class="pitch">
<h1>{{ _('Contact support') }}</h1>
</div>
<form method="post" class="form-horizontal white-box" id="registration">
{{ csrf_input }}
<fieldset class="support-request">
<div class="input-box no-validation support-form-field">
<label for="support_from" class="inline-block label-title">{{ _('From') }}</label>
<div id="support_from">{{ email }}</div>
</div>
<div class="input-box no-validation support-form-field">
<label for="support_realm" class="inline-block label-title">{{ _('Organization') }}</label>
<div id="support_realm">{{ realm_name }}</div>
</div>
<div class="input-box support-form-field">
<label for="request_subject" class="inline-block label-title">{{ _('Subject') }}</label>
<input id="request_subject" class="required" type="text" name="request_subject" maxlength="{{ MAX_SUBJECT_LENGTH }}" required />
</div>
<div class="input-box support-form-field">
<label for="request_message" class="inline-block label-title">{{ _('Message') }}</label>
<textarea id="request_message" name="request_message" cols="100" rows="5" required></textarea>
</div>
<div class="register-button-box">
<button class="register-button support-submit-button" type="submit">
<span>{{ _('Submit') }}</span>
<object class="loader" type="image/svg+xml" data="/static/images/loader-white.svg"></object>
</button>
</div>
</fieldset>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% extends "zerver/portico.html" %}
{% block portico_content %}
<div class="flex full-page thanks-page">
<div class="center-block new-style">
<h1>Thanks for contacting us!</h1>
<p>We will be in touch with you soon.</p>
<p>
You can find answers to frequently asked questions in the
<a href="/help/">Zulip help center</a>.
</p>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends "zerver/emails/email_base_messages.html" %}
{% block content %}
<b>Support URL</b>: <a href="{{ support_url }}">{{ support_url }}</a>
<br /><br />
<b>Subject</b>: {{ request_subject }}
<br /><br />
<b>Message</b>:
<br />
{{ request_message }}
<br /><br />
<b>Requested by</b>: {{ requested_by }} ({{ user_role }})
{% endblock %}

View File

@ -0,0 +1 @@
Support request for {{ realm_string_id }}

View File

@ -0,0 +1,8 @@
Support URL: {{ support_url }}
Subject: {{ request_subject }}
Message:
{{ request_message }}
Requested by: {{ requested_by }} ({{ user_role }})

View File

@ -547,6 +547,9 @@ html_rules: List["Rule"] = [
"templates/zerver/email.html",
"zerver/tests/fixtures/email",
"templates/zerver/for-companies.html",
"templates/corporate/support_request.html",
"templates/corporate/support_request_thanks.html",
"templates/zerver/emails/support_request.html",
},
"exclude_pattern": "email subject",
"description": "avoid subject in templates",