Repository: zulip/zulip

Issue:
Open Organizations landing page
@alya asked me to provide a design for the Open Organizations landing page for the Zulip website. She also told me that probably @amanagr is the right person to implement this (if its not so, please reassign the task)

We don't introduce any new design to the Zulip website this time and would like to reuse already available styles and elements.
S lets take [integrations](https://zulip.com/integrations/) page and tune/add some styles.

[Figma frame with the mock](https://www.figma.com/file/0MHqR2QphLTfJxFLeWIIDC/Web-site?node-id=3%3A24)
![image](https://user-images.githubusercontent.com/1903309/167272818-754c65ee-aa53-44cd-af50-c557b9fe710e.png)


The text itself isn't final, please talk to @alya for the content acceptance.

## Design clarifications
I suggest to round corners of the white background:
<img width="744" alt="image" src="https://user-images.githubusercontent.com/1903309/167272542-09423950-c978-41e7-b45e-96f584b2273a.png">

There might be no, 1 line or 2 line description of the organization 
<img width="675" alt="image" src="https://user-images.githubusercontent.com/1903309/167272582-277dea85-bead-46ef-a1dd-1ebc0bff6817.png">. Vertically align with 60x60 square of the image

Image/Logo is fixed rectangle in which we fit the actual logotype of the company:
<img width="241" alt="image" src="https://user-images.githubusercontent.com/1903309/167272609-84cc2db9-7efb-4a7f-bc9d-ea459073cfea.png">
I suggest to have max-width of the list item as 700px (or something around it, if it's convenient in the current column system)

List items on hover should have a green border:
<img width="777" alt="image" src="https://user-images.githubusercontent.com/1903309/167272706-7664b6f9-ba7c-4df9-9748-dad4f291a717.png">, but there is no border in the normal state
![image](https://user-images.githubusercontent.com/1903309/167272808-ba807112-0dc5-4b31-b9f6-e9bc43bc64b5.png)


## Extra improvement - TBD if should be implemented
I noticed that there is a problem with background on the Zulip website
<img width="509" alt="image" src="https://user-images.githubusercontent.com/1903309/167272944-0f95206b-8d41-41dd-a64d-4005615fd881.png">

And I suggest a correction for the background gradients
![image](https://user-images.githubusercontent.com/1903309/167272880-16513ba3-5f9d-4097-8113-c812c78e4061.png)

In my suggestion I exclude the shadow from the white container, so the bottom part will look like this:
<img width="1453" alt="image" src="https://user-images.githubusercontent.com/1903309/167272988-7fd41472-6320-49f8-9eac-203e573e5352.png"> instead of this 
<img width="1459" alt="image" src="https://user-images.githubusercontent.com/1903309/167272993-25ce07c3-1f12-4c02-a26e-311e9f6a7d7d.png">

So there is a white background and there is a fixed height gradient (it can be of any desired size). In my example it is 1100px of height. It consist from 4 layers of gradients:
1. Corner green to white. Layer with with 80% opacity
<img width="992" alt="image" src="https://user-images.githubusercontent.com/1903309/167273035-78760cc0-d5dd-4746-84a4-93ecb864c9ac.png">

```css
background: radial-gradient(100% 100% at 0% 0%, #61AD86 0%, rgba(97, 173, 134, 0) 100%);
opacity: 0.8;
```

2. Centered blue
<img width="1014" alt="image" src="https://user-images.githubusercontent.com/1903309/167273077-c37372df-d12e-4ae6-8e6f-7508b613b082.png">

```css
background: radial-gradient(100% 100% at 50.05% 0%, #5298B1 0%, rgba(82, 152, 177, 0) 100%);
```

3. Corner blue
<img width="1023" alt="image" src="https://user-images.githubusercontent.com/1903309/167273110-04f7c26d-92f7-42db-a982-94b72cebae9a.png">

```css
background: radial-gradient(100% 100% at 100% 0%, #5298B1 0%, rgba(82, 152, 177, 0) 100%);
```

4. Yellow linear
<img width="1041" alt="image" src="https://user-images.githubusercontent.com/1903309/167273129-fc24c111-eeef-48ee-800d-1827e4bf12bd.png">

```css
background: linear-gradient(180deg, #FFED9D 0%, rgba(255, 237, 157, 0) 100%);
```

A cool aspect about such gradient approach that it's working with any background color. Here is black background:
<img width="820" alt="image" src="https://user-images.githubusercontent.com/1903309/167273193-b19e8078-80e9-4f66-b81c-1f43d3dd870f.png">




Discussion:
Hello @zulip/server-misc members, this issue was labeled with the "area: portico" label, so you may want to check it out!

<!-- areaLabelAddition -->

I see we removed the search bar that is in integrations. It would still be useful here, right?
@amanagr as soon as there are more than 20 organizations.
@amanagr You have been unassigned from this issue because you have not made any updates for over 14 days. Please feel free to reclaim the issue if you decide to pick up again. Thanks!


Resolving patch:
diff --git a/corporate/urls.py b/corporate/urls.py
--- a/corporate/urls.py
+++ b/corporate/urls.py
@@ -9,6 +9,7 @@
 from corporate.views.portico import (
     app_download_link_redirect,
     apps_view,
+    communities_view,
     hello_view,
     landing_view,
     plans_view,
@@ -125,6 +126,7 @@
         landing_view,
         {"template_name": "corporate/case-studies/recurse-center-case-study.html"},
     ),
+    path("communities/", communities_view),
 ]
 i18n_urlpatterns += landing_page_urls
 
diff --git a/corporate/views/portico.py b/corporate/views/portico.py
--- a/corporate/views/portico.py
+++ b/corporate/views/portico.py
@@ -10,6 +10,8 @@
 from zerver.context_processors import get_realm_from_request, latest_info_context
 from zerver.decorator import add_google_analytics
 from zerver.lib.github import InvalidPlatform, get_latest_github_release_download_link_for_platform
+from zerver.lib.realm_description import get_realm_text_description
+from zerver.lib.realm_icon import get_realm_icon_url
 from zerver.lib.subdomains import is_subdomain_root_or_alias
 from zerver.models import Realm
 
@@ -103,3 +105,47 @@ def landing_view(request: HttpRequest, template_name: str) -> HttpResponse:
 @add_google_analytics
 def hello_view(request: HttpRequest) -> HttpResponse:
     return TemplateResponse(request, "corporate/hello.html", latest_info_context())
+
+
+@add_google_analytics
+def communities_view(request: HttpRequest) -> HttpResponse:
+    eligible_realms = []
+    unique_org_type_ids = set()
+    want_to_be_advertised_realms = Realm.objects.filter(
+        want_advertise_in_communities_directory=True
+    ).order_by("name")
+    for realm in want_to_be_advertised_realms:
+        if realm.allow_web_public_streams_access():
+            eligible_realms.append(
+                {
+                    "id": realm.id,
+                    "name": realm.name,
+                    "realm_url": realm.uri,
+                    "logo_url": get_realm_icon_url(realm),
+                    "description": get_realm_text_description(realm),
+                    "org_type_key": [
+                        org_type
+                        for org_type in Realm.ORG_TYPES
+                        if Realm.ORG_TYPES[org_type]["id"] == realm.org_type
+                    ][0],
+                }
+            )
+            unique_org_type_ids.add(realm.org_type)
+
+    # Remove org_types for which there are no open organizations.
+    org_types = dict()
+    for org_type in Realm.ORG_TYPES:
+        if Realm.ORG_TYPES[org_type]["id"] in unique_org_type_ids:
+            org_types[org_type] = Realm.ORG_TYPES[org_type]
+
+        # Remove `Unspecified` ORG_TYPE
+        org_types.pop("unspecified", None)
+
+    return TemplateResponse(
+        request,
+        "corporate/communities.html",
+        context={
+            "eligible_realms": eligible_realms,
+            "org_types": org_types,
+        },
+    )
diff --git a/zerver/lib/templates.py b/zerver/lib/templates.py
--- a/zerver/lib/templates.py
+++ b/zerver/lib/templates.py
@@ -192,8 +192,15 @@ def webpack_entry(entrypoint: str) -> List[str]:
     if status != "done":
         raise RuntimeError("Webpack compilation was not successful")
 
-    return [
-        staticfiles_storage.url(settings.WEBPACK_BUNDLES + filename)
-        for filename in stats["chunks"][entrypoint]
-        if filename.endswith((".css", ".js")) and not filename.endswith(".hot-update.js")
-    ]
+    try:
+        files_from_entrypoints = [
+            staticfiles_storage.url(settings.WEBPACK_BUNDLES + filename)
+            for filename in stats["chunks"][entrypoint]
+            if filename.endswith((".css", ".js")) and not filename.endswith(".hot-update.js")
+        ]
+    except KeyError:
+        raise KeyError(
+            f"'{entrypoint}' entrypoint could not be found. Please define it in tools/webpack.assets.json."
+        )
+
+    return files_from_entrypoints


Test patch:
diff --git a/zerver/tests/test_docs.py b/zerver/tests/test_docs.py
--- a/zerver/tests/test_docs.py
+++ b/zerver/tests/test_docs.py
@@ -199,6 +199,13 @@ def test_doc_endpoints(self) -> None:
         result = self.client_get("/for/companies/", follow=True)
         self.assert_in_success_response(["Communication efficiency represents"], result)
 
+    def test_open_organizations_endpoint(self) -> None:
+        realm = get_realm("zulip")
+        realm.want_advertise_in_communities_directory = True
+        realm.save()
+
+        self._test("/communities/", "Open communities directory")
+
     def test_portico_pages_open_graph_metadata(self) -> None:
         # Why Zulip
         url = "/why-zulip/"