Skip to content

Commit 780027f

Browse files
authored
OPS-1160: OPS-1181: New templates page (#1784)
* init * updates * updates * add integrations * change sidebar * updates * final touches * update shadows * update test * add some padding * just on the left actually * updates * bump
1 parent 9667689 commit 780027f

28 files changed

+1710
-154
lines changed

assets/tailwind-theme.css

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,66 @@
163163
--font-instrument-sans: 'Instrument Sans', sans-serif;
164164
--font-source-code-pro: 'Source Code Pro', monospace;
165165
--font-jetbrains: "JetBrains Mono", monospace;
166+
/* Shadow (light) */
167+
--shadow-small-adaptive: 0px 2px 5px 0px rgba(28, 32, 36, 0.03);
168+
--shadow-medium-adaptive: 0px 4px 8px 0px rgba(28, 32, 36, 0.04);
169+
--shadow-large-adaptive:
170+
0px 24px 12px 0px rgba(28, 32, 36, 0.02),
171+
0px 8px 8px 0px rgba(28, 32, 36, 0.02),
172+
0px 2px 6px 0px rgba(28, 32, 36, 0.02);
173+
--shadow-large-negative-adaptive:
174+
0px -24px 12px 0px rgba(28, 32, 36, 0.02),
175+
0px -8px 8px 0px rgba(28, 32, 36, 0.02),
176+
0px -2px 6px 0px rgba(28, 32, 36, 0.02);
177+
--shadow-large-negative-primary-adaptive:
178+
0px -32px 48px 0px color-mix(in srgb, var(--primary-9) 8%, transparent),
179+
0px -16px 32px 0px color-mix(in srgb, var(--primary-9) 10%, transparent),
180+
0px -8px 24px 0px color-mix(in srgb, var(--primary-9) 12%, transparent),
181+
0px -2px 16px 0px color-mix(in srgb, var(--primary-9) 14%, transparent);
182+
--shadow-x-large-adaptive:
183+
0 0 0 1px rgba(0, 0, 0, 0.04),
184+
0 4px 8px 0 rgba(0, 0, 0, 0.02),
185+
0 1px 1px 0 rgba(0, 0, 0, 0.01),
186+
0 4px 8px 0 rgba(0, 0, 0, 0.03),
187+
0 0 0 1px #fff inset;
188+
--shadow-inner-adaptive: 0 6px 16px 0 rgba(0, 0, 0, 0.04) inset;
189+
--shadow-button-outline-adaptive:
190+
0 -1px 0 0 rgba(0, 0, 0, 0.08) inset,
191+
0 0 0 1px rgba(0, 0, 0, 0.08) inset,
192+
0 1px 2px 0 rgba(0, 0, 0, 0.02),
193+
0 1px 4px 0 rgba(0, 0, 0, 0.02);
194+
--shadow-card-xs-no-left-adaptive:
195+
0 -1px 0 0 rgba(0, 0, 0, 0.16) inset,
196+
0 1px 0 0 rgba(0, 0, 0, 0.08) inset,
197+
-1px 0 0 0 rgba(0, 0, 0, 0.08) inset,
198+
0 1px 2px 0 rgba(0, 0, 0, 0.02),
199+
0 1px 4px 0 rgba(0, 0, 0, 0.02);
200+
--shadow-card-small-adaptive:
201+
0 0 0 1px rgba(0, 0, 0, 0.04),
202+
0 4px 8px 0 rgba(0, 0, 0, 0.04),
203+
0 1px 1px 0 rgba(0, 0, 0, 0.01),
204+
0 2px 4px 0 rgba(0, 0, 0, 0.03);
166205
color-scheme: light dark;
167206
}
168207

208+
.dark {
209+
/* Shadow (dark) */
210+
--shadow-small-adaptive: none;
211+
--shadow-medium-adaptive: none;
212+
--shadow-large-adaptive: none;
213+
--shadow-large-negative-adaptive: none;
214+
--shadow-large-negative-primary-adaptive:
215+
0px -32px 48px 0px color-mix(in srgb, var(--primary-9) 4%, transparent),
216+
0px -16px 32px 0px color-mix(in srgb, var(--primary-9) 8%, transparent),
217+
0px -8px 24px 0px color-mix(in srgb, var(--primary-9) 12%, transparent),
218+
0px -2px 16px 0px color-mix(in srgb, var(--primary-9) 16%, transparent);
219+
--shadow-x-large-adaptive: none;
220+
--shadow-inner-adaptive: none;
221+
--shadow-button-outline-adaptive: none;
222+
--shadow-card-xs-no-left-adaptive: none;
223+
--shadow-card-small-adaptive: none;
224+
}
225+
169226
@theme {
170227
/* Custom Palette */
171228
--color-white-1: var(--c-white-1);
@@ -1104,20 +1161,23 @@
11041161
--font-mono: var(--font-jetbrains);
11051162
/* Shadow */
11061163
--shadow-none: none;
1107-
--shadow-small: 0px 2px 5px 0px light-dark(rgba(28, 32, 36, 0.03), rgba(0, 0, 0, 0));
1108-
--shadow-medium: 0px 4px 8px 0px light-dark(rgba(28, 32, 36, 0.04), rgba(0, 0, 0, 0));
1109-
--shadow-large:
1110-
0px 24px 12px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)),
1111-
0px 8px 8px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)),
1112-
0px 2px 6px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0));
1113-
--shadow-large-negative:
1114-
0px -24px 12px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)),
1115-
0px -8px 8px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0)),
1116-
0px -2px 6px 0px light-dark(rgba(28, 32, 36, 0.02), rgba(0, 0, 0, 0));
1164+
--shadow-small: var(--shadow-small-adaptive);
1165+
--shadow-medium: var(--shadow-medium-adaptive);
1166+
--shadow-large: var(--shadow-large-adaptive);
1167+
--shadow-large-negative: var(--shadow-large-negative-adaptive);
1168+
--shadow-large-negative-primary: var(--shadow-large-negative-primary-adaptive);
1169+
--shadow-x-large: var(--shadow-x-large-adaptive);
1170+
--shadow-inner: var(--shadow-inner-adaptive);
11171171
--shadow-card: 0 0 0 1px rgba(0, 0, 0, 0.04),
11181172
0 4px 8px 0 rgba(0, 0, 0, 0.07),
11191173
0 1px 1px 0 rgba(0, 0, 0, 0.01),
11201174
0 0 0 1px #FFF inset;
1175+
--shadow-button-bordered:
1176+
0 0 0 1px var(--primary-9) inset,
1177+
0 2px 0 0 rgba(255, 255, 255, 0.22) inset;
1178+
--shadow-button-outline: var(--shadow-button-outline-adaptive);
1179+
--shadow-card-xs-no-left: var(--shadow-card-xs-no-left-adaptive);
1180+
--shadow-card-small: var(--shadow-card-small-adaptive);
11211181
--shadow-card-dark: 0 0 0 1px var(--m-slate-9, #2A3037);
11221182
--text-xs: 0.8125rem;
11231183
--text-xs--line-height: 1.25rem;

pcweb/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
"REFLEX_DEV_WEB_GENERAL_FORM_FEEDBACK_WEBHOOK_URL"
1515
)
1616

17+
REPLICATE_FLUX_SCHNELL_PREDICTIONS_URL: str = (
18+
"https://api.replicate.com/v1/models/black-forest-labs/flux-schnell/predictions"
19+
)
20+
1721
# pcweb urls.
1822
REFLEX_URL = "https://reflex.dev/"
1923
REFLEX_DOCS_URL = "https://reflex.dev/docs/getting-started/introduction/"

pcweb/pages/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from .errors import errors as errors
1414
from .faq import faq as faq
1515
from .framework.framework import framework as framework
16-
from .gallery import gallery as gallery
1716
from .gallery.apps import gallery_apps_routes
1817
from .hosting.hosting import hosting_landing as hosting_landing
1918
from .landing.landing import landing as landing
@@ -32,6 +31,8 @@
3231
from .pricing.pricing import pricing as pricing
3332
from .sales import sales as sales
3433
from .security.security import security_page as security_page
34+
from .templates import templates_landing as templates_landing
35+
from .templates.template_details import template_details as template_details
3536
from .to_be_booked import to_be_booked as to_be_booked
3637
from .use_cases.consulting import consulting_use_case_page as consulting_use_case_page
3738
from .use_cases.finance import finance_use_case_page as finance_use_case_page

pcweb/pages/framework/demos/image_gen/image_gen.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,46 @@
1+
import os
2+
3+
import aiohttp
14
import reflex as rx
2-
import replicate
35

46
from pcweb.components.button import button
57
from pcweb.components.icons import get_icon
8+
from pcweb.constants import REPLICATE_FLUX_SCHNELL_PREDICTIONS_URL
9+
from pcweb.utils.http import default_client
10+
11+
_REPLICATE_WAIT_SEC = 5
12+
13+
_FLUX_SCHNELL_INPUT_DEFAULTS: dict[str, str | int | bool] = {
14+
"go_fast": True,
15+
"num_inference_steps": 3,
16+
"num_outputs": 1,
17+
"aspect_ratio": "1:1",
18+
"output_format": "webp",
19+
"output_quality": 80,
20+
}
21+
22+
23+
async def _run_flux_schnell(prompt: str) -> str:
24+
token = os.environ.get("REPLICATE_API_TOKEN")
25+
26+
session = default_client()
27+
timeout = aiohttp.ClientTimeout(total=_REPLICATE_WAIT_SEC)
28+
async with session.post(
29+
REPLICATE_FLUX_SCHNELL_PREDICTIONS_URL,
30+
json={"input": {"prompt": prompt, **_FLUX_SCHNELL_INPUT_DEFAULTS}},
31+
headers={
32+
"Authorization": f"Token {token}",
33+
"Prefer": f"wait={_REPLICATE_WAIT_SEC}",
34+
},
35+
timeout=timeout,
36+
) as resp:
37+
resp.raise_for_status()
38+
prediction = await resp.json()
39+
40+
output = prediction.get("output")
41+
if not output:
42+
raise RuntimeError("Replicate returned no output")
43+
return str(output[0] if isinstance(output, list) else output)
644

745

846
class ImageGenState(rx.State):
@@ -20,15 +58,11 @@ async def get_image(self, form_data):
2058
async with self:
2159
self.processing = True
2260
yield
23-
input = {"prompt": prompt}
2461

2562
try:
26-
output = await replicate.async_run(
27-
"black-forest-labs/flux-schnell",
28-
input=input,
29-
)
63+
image_url = await _run_flux_schnell(prompt)
3064
async with self:
31-
self.image_url = str(output[0])
65+
self.image_url = image_url
3266
except Exception:
3367
async with self:
3468
self.image_url = ""
@@ -106,7 +140,15 @@ def get_image(self, form_data):
106140
self.processing = True
107141
yield
108142
109-
input = {"prompt": prompt}
143+
input = {
144+
"prompt": prompt,
145+
"go_fast": True,
146+
"num_inference_steps": 3,
147+
"num_outputs": 1,
148+
"aspect_ratio": "1:1",
149+
"output_format": "webp",
150+
"output_quality": 80,
151+
}
110152
output = replicate.run(
111153
"black-forest-labs/flux-schnell",
112154
input=input,

pcweb/pages/framework/views/footer_index.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def logo() -> rx.Component:
5959
class_name="shrink-0 hidden dark:block",
6060
),
6161
to="/",
62-
class_name="block shrink-0 mr-[7rem]",
62+
class_name="block shrink-0 mr-[7rem] md:hidden xl:block",
6363
)
6464

6565

@@ -199,7 +199,7 @@ def newsletter() -> rx.Component:
199199

200200

201201
@rx.memo
202-
def footer_index() -> rx.Component:
202+
def footer_index(class_name: str = "", grid_class_name: str = "") -> rx.Component:
203203
return rx.el.footer(
204204
rx.el.div(
205205
logo(),
@@ -235,7 +235,10 @@ def footer_index() -> rx.Component:
235235
rx.el.div(
236236
class_name="absolute -top-24 -right-px w-px h-24 bg-gradient-to-b from-transparent to-current text-m-slate-4 dark:text-m-slate-10 max-lg:hidden"
237237
),
238-
class_name="grid grid-cols-1 lg:grid-cols-3 gap-12 w-full lg:pr-12 pb-8 lg:border-r border-m-slate-4 dark:border-m-slate-10 ml-auto relative",
238+
class_name=ui.cn(
239+
"grid grid-cols-1 lg:grid-cols-3 gap-12 w-full lg:pr-12 pb-8 lg:border-r border-m-slate-4 dark:border-m-slate-10 xl:ml-auto relative",
240+
grid_class_name,
241+
),
239242
),
240243
rx.el.div(
241244
newsletter(),
@@ -259,5 +262,8 @@ def footer_index() -> rx.Component:
259262
),
260263
class_name="flex flex-row items-center justify-between py-6 gap-4 w-full border-t border-m-slate-4 dark:border-m-slate-10 relative",
261264
),
262-
class_name="flex flex-col max-w-(--docs-layout-max-width) justify-center items-center w-full mx-auto mt-24 max-lg:px-4 overflow-hidden",
265+
class_name=ui.cn(
266+
"flex flex-col max-w-(--docs-layout-max-width) justify-center items-center w-full mx-auto mt-24 max-lg:px-4 overflow-hidden",
267+
class_name,
268+
),
263269
)

pcweb/pages/templates/__init__.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import reflex as rx
2+
3+
from pcweb.meta.meta import create_meta_tags
4+
from pcweb.pages.framework.views.footer_index import footer_index
5+
from pcweb.pages.templates.templates_state import TemplatesState
6+
from pcweb.pages.templates.views import templates_grid, templates_sidebar
7+
from pcweb.templates.secondary_page import secondary_page
8+
9+
10+
@secondary_page(
11+
path="/templates",
12+
title="Reflex Templates - Python Dashboards & Tools",
13+
description="Reflex templates: dashboards, chatbots, data tools, and AI apps. Start from a template and customize in Python.",
14+
meta=create_meta_tags(
15+
title="Reflex Templates - Python Dashboards & Tools",
16+
description="Reflex templates: dashboards, chatbots, data tools, and AI apps. Start from a template and customize in Python.",
17+
image="/previews/index_preview.webp",
18+
),
19+
on_load=TemplatesState.load_templates,
20+
)
21+
def templates_landing() -> rx.Component:
22+
return rx.el.div(
23+
rx.el.div(
24+
templates_sidebar(),
25+
rx.el.div(
26+
templates_grid(),
27+
footer_index(
28+
class_name="max-w-[109rem] px-4 xl:px-14",
29+
grid_class_name="w-fit [&>div]:min-w-[9rem]",
30+
),
31+
class_name="flex flex-col flex-1 min-w-0",
32+
),
33+
class_name="flex flex-row w-full max-w-[108rem] mx-auto min-h-screen",
34+
),
35+
class_name="flex flex-col w-full relative overflow-x-clip",
36+
)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import reflex as rx
2+
3+
from pcweb.pages.framework.views.footer_index import footer_index
4+
from pcweb.pages.templates.template_details.views import (
5+
about,
6+
faq,
7+
header,
8+
others,
9+
sidebar,
10+
sidebar_mobile,
11+
social,
12+
)
13+
from pcweb.pages.templates.templates_state import TemplatesState
14+
from pcweb.templates.secondary_page import secondary_page
15+
16+
17+
@secondary_page(
18+
path="/templates/[template_name]/[template_id]",
19+
title="Template Details",
20+
description="Template Details",
21+
image="/previews/index_preview.webp",
22+
on_load=TemplatesState.load_template_details,
23+
)
24+
def template_details():
25+
return rx.el.div(
26+
rx.cond(
27+
TemplatesState.faq_jsonld,
28+
rx.el.script(TemplatesState.faq_jsonld, type="application/ld+json"),
29+
),
30+
rx.cond(
31+
TemplatesState.active_template,
32+
rx.el.div(
33+
rx.el.div(
34+
header(),
35+
sidebar_mobile(),
36+
rx.cond(TemplatesState.active_template.about, about()),
37+
rx.cond(TemplatesState.active_template.quotes, social()),
38+
rx.cond(TemplatesState.active_template.faq, faq()),
39+
others(),
40+
class_name="flex-1 flex flex-col divide-y divide-secondary-4 xl:border-r border-secondary-4 pl-4 pr-4 md:pr-0 md:pl-6 3xl:px-0",
41+
),
42+
sidebar(),
43+
class_name="flex flex-row w-full max-w-[108rem] mx-auto min-h-screen",
44+
),
45+
),
46+
rx.el.hr(
47+
class_name="h-[1px] w-full bg-m-slate-4 dark:bg-m-slate-10",
48+
),
49+
footer_index(
50+
class_name="max-w-[109rem]",
51+
grid_class_name="w-fit [&>div]:min-w-[9rem]",
52+
),
53+
class_name="flex flex-col w-full relative",
54+
)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from .about import about
2+
from .faq import faq
3+
from .header import header
4+
from .others import others
5+
from .sidebar import sidebar, sidebar_mobile
6+
from .social import social
7+
8+
__all__ = [
9+
"about",
10+
"faq",
11+
"header",
12+
"others",
13+
"sidebar",
14+
"sidebar_mobile",
15+
"social",
16+
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import reflex as rx
2+
3+
from pcweb.pages.templates.templates_state import TemplatesState
4+
5+
6+
def about():
7+
return rx.el.div(
8+
rx.el.h2(
9+
"About This Template",
10+
class_name="text-2xl font-[575] text-secondary-12",
11+
),
12+
rx.el.p(
13+
TemplatesState.active_template.about,
14+
class_name="text-sm text-secondary-11 font-[475]",
15+
),
16+
class_name="xl:pr-16 xl:py-16 py-6 flex flex-col gap-6 w-full",
17+
)

0 commit comments

Comments
 (0)