mirror of https://github.com/zulip/zulip.git
demo_request: Add form for user to request a demo.
This sends an email to us after user fills out and sends the form.
This commit is contained in:
parent
0ab7233ffa
commit
263d1ae38e
|
@ -2344,6 +2344,37 @@ class StripeTest(StripeTestCase):
|
|||
response,
|
||||
)
|
||||
|
||||
def test_demo_request(self) -> None:
|
||||
result = self.client_get("/request-demo/")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
self.assert_in_success_response(["Request a demo"], result)
|
||||
|
||||
data = {
|
||||
"full_name": "King Hamlet",
|
||||
"email": "test@zulip.com",
|
||||
"role": "Manager",
|
||||
"organization_name": "Zulip",
|
||||
"organization_type": "Business",
|
||||
"organization_website": "https://example.com",
|
||||
"expected_user_count": "10 (2 unpaid members)",
|
||||
"message": "Need help!",
|
||||
}
|
||||
result = self.client_post("/request-demo/", data)
|
||||
self.assert_in_success_response(["Thanks for contacting 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, "Demo request for Zulip")
|
||||
self.assertEqual(message.reply_to, ["test@zulip.com"])
|
||||
self.assertEqual(self.email_envelope_from(message), settings.NOREPLY_EMAIL_ADDRESS)
|
||||
self.assertIn("Zulip demo request <noreply-", self.email_display_from(message))
|
||||
self.assertIn("Full name: King Hamlet", message.body)
|
||||
|
||||
def test_support_request(self) -> None:
|
||||
user = self.example_user("hamlet")
|
||||
self.assertIsNone(get_customer_by_realm(user.realm))
|
||||
|
|
|
@ -68,7 +68,7 @@ from corporate.views.sponsorship import (
|
|||
sponsorship,
|
||||
sponsorship_page,
|
||||
)
|
||||
from corporate.views.support import remote_servers_support, support, support_request
|
||||
from corporate.views.support import demo_request, remote_servers_support, support, support_request
|
||||
from corporate.views.upgrade import (
|
||||
remote_realm_upgrade,
|
||||
remote_realm_upgrade_page,
|
||||
|
@ -94,6 +94,7 @@ i18n_urlpatterns: Any = [
|
|||
path("sponsorship/", sponsorship_page, name="sponsorship_request"),
|
||||
path("upgrade/", upgrade_page, name="upgrade_page"),
|
||||
path("support/", support_request),
|
||||
path("request-demo/", demo_request),
|
||||
path("billing/event_status/", event_status_page, name="event_status_page"),
|
||||
path("stripe/webhook/", stripe_webhook, name="stripe_webhook"),
|
||||
# Server admin (user_profile.is_staff) visible stats pages
|
||||
|
|
|
@ -95,6 +95,21 @@ class SupportRequestForm(forms.Form):
|
|||
request_message = forms.CharField(widget=forms.Textarea)
|
||||
|
||||
|
||||
class DemoRequestForm(forms.Form):
|
||||
MAX_INPUT_LENGTH = 50
|
||||
SORTED_ORG_TYPE_NAMES = sorted(
|
||||
([org_type["name"] for org_type in Realm.ORG_TYPES.values() if not org_type["hidden"]]),
|
||||
)
|
||||
full_name = forms.CharField(max_length=MAX_INPUT_LENGTH)
|
||||
email = forms.EmailField()
|
||||
role = forms.CharField(max_length=MAX_INPUT_LENGTH)
|
||||
organization_name = forms.CharField(max_length=MAX_INPUT_LENGTH)
|
||||
organization_type = forms.CharField()
|
||||
organization_website = forms.URLField(required=True)
|
||||
expected_user_count = forms.CharField(max_length=MAX_INPUT_LENGTH)
|
||||
message = forms.CharField(widget=forms.Textarea)
|
||||
|
||||
|
||||
@zulip_login_required
|
||||
@has_request_variables
|
||||
def support_request(request: HttpRequest) -> HttpResponse:
|
||||
|
@ -139,6 +154,47 @@ def support_request(request: HttpRequest) -> HttpResponse:
|
|||
return response
|
||||
|
||||
|
||||
@has_request_variables
|
||||
def demo_request(request: HttpRequest) -> HttpResponse:
|
||||
context = {
|
||||
"MAX_INPUT_LENGTH": DemoRequestForm.MAX_INPUT_LENGTH,
|
||||
"SORTED_ORG_TYPE_NAMES": DemoRequestForm.SORTED_ORG_TYPE_NAMES,
|
||||
}
|
||||
|
||||
if request.POST:
|
||||
post_data = request.POST.copy()
|
||||
form = DemoRequestForm(post_data)
|
||||
|
||||
if form.is_valid():
|
||||
email_context = {
|
||||
"full_name": form.cleaned_data["full_name"],
|
||||
"email": form.cleaned_data["email"],
|
||||
"role": form.cleaned_data["role"],
|
||||
"organization_name": form.cleaned_data["organization_name"],
|
||||
"organization_type": form.cleaned_data["organization_type"],
|
||||
"organization_website": form.cleaned_data["organization_website"],
|
||||
"expected_user_count": form.cleaned_data["expected_user_count"],
|
||||
"message": form.cleaned_data["message"],
|
||||
}
|
||||
# Sent to the server's support team, so this email is not user-facing.
|
||||
send_email(
|
||||
"zerver/emails/demo_request",
|
||||
to_emails=[FromAddress.SUPPORT],
|
||||
from_name="Zulip demo request",
|
||||
from_address=FromAddress.tokenized_no_reply_address(),
|
||||
reply_to_email=email_context["email"],
|
||||
context=email_context,
|
||||
)
|
||||
|
||||
response = render(
|
||||
request, "corporate/support/support_request_thanks.html", context=context
|
||||
)
|
||||
return response
|
||||
|
||||
response = render(request, "corporate/support/demo_request.html", context=context)
|
||||
return response
|
||||
|
||||
|
||||
def get_plan_type_string(plan_type: int) -> str:
|
||||
return {
|
||||
Realm.PLAN_TYPE_SELF_HOSTED: "Self-hosted",
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
{% 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>Request a demo</h1>
|
||||
</div>
|
||||
|
||||
<form method="post" class="white-box" id="registration">
|
||||
{{ csrf_input }}
|
||||
|
||||
<fieldset class="support-request">
|
||||
<div class="input-box support-form-field">
|
||||
<label for="full_name" class="inline-block label-title">Full name</label>
|
||||
<input class="required" type="text" name="full_name" maxlength="{{ MAX_INPUT_LENGTH }}" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="email" class="inline-block label-title">Email</label>
|
||||
<input class="required" type="email" name="email" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="role" class="inline-block label-title">Your role</label>
|
||||
<input class="required" type="text" name="role" maxlength="{{ MAX_INPUT_LENGTH }}" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="organization_name" class="inline-block label-title">Organization name</label>
|
||||
<input class="required" type="text" name="organization_name" maxlength="{{ MAX_INPUT_LENGTH }}" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="organization_type" class="inline-block label-title">Organization type</label>
|
||||
<select name="organization_type" class="required">
|
||||
{% for org_type in SORTED_ORG_TYPE_NAMES %}
|
||||
<option
|
||||
value="{{ org_type }}">
|
||||
{{ org_type }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="organization_website" class="inline-block label-title">Organization website</label>
|
||||
<input class="required" type="url" name="organization_website" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="expected_user_count" class="inline-block label-title">Expected number of users (approximate range)</label>
|
||||
<input class="required" type="text" name="expected_user_count" maxlength="{{ MAX_INPUT_LENGTH }}" required />
|
||||
</div>
|
||||
<div class="input-box support-form-field">
|
||||
<label for="message" class="inline-block label-title">How can we help?</label>
|
||||
<textarea name="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/loading/loader-white.svg') }}"></object>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
{% block portico_content %}
|
||||
<div class="flex full-page thanks-page">
|
||||
<div class="center-block new-style">
|
||||
<div class="center-block new-style white-box">
|
||||
<h1>{{ _("Thanks for contacting us!") }}</h1>
|
||||
<p>{{ _("We will be in touch with you soon.") }}</p>
|
||||
<p>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{% extends "zerver/emails/email_base_messages.html" %}
|
||||
|
||||
{% block content %}
|
||||
<b>Subject</b>: Demo request for {{ organization_name }}
|
||||
<br />
|
||||
<b>Full name</b>: {{ full_name }}
|
||||
<br />
|
||||
<b>Email</b>: {{ email }}
|
||||
<br />
|
||||
<b>Role</b>: {{ role }}
|
||||
<br />
|
||||
<b>Organization type</b>: {{ organization_type }}
|
||||
<br />
|
||||
<b>Organization website</b>: {{ organization_website }}
|
||||
<br />
|
||||
<b>Expected user count</b>: {{ expected_user_count }}
|
||||
<br />
|
||||
<b>Message</b>: {{ message }}
|
||||
<br />
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1 @@
|
|||
Demo request for {{organization_name}}
|
|
@ -0,0 +1,15 @@
|
|||
Subject: Demo request for {{ organization_name }}
|
||||
|
||||
Full name: {{ full_name }}
|
||||
|
||||
Email: {{ email }}
|
||||
|
||||
Role: {{ role }}
|
||||
|
||||
Organization type: {{ organization_type }}
|
||||
|
||||
Organization website: {{ organization_website }}
|
||||
|
||||
Expected user count: {{ expected_user_count }}
|
||||
|
||||
Message: {{ message }}
|
|
@ -527,6 +527,7 @@ html {
|
|||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="number"],
|
||||
input[type="url"],
|
||||
textarea,
|
||||
select {
|
||||
padding: 10px 32px 10px 12px;
|
||||
|
|
Loading…
Reference in New Issue