Remove demo template (#3888)

This commit is contained in:
Elijah Ahianyo 2024-09-05 17:22:07 +00:00 committed by GitHub
parent 677ae314fb
commit 2d6e531e49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 0 additions and 2146 deletions

View File

@ -1,4 +0,0 @@
*.db
*.py[cod]
.web
__pycache__/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,10 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Github" clip-path="url(#clip0_469_1929)">
<path id="Vector" d="M8.0004 0.587524C3.80139 0.587524 0.400391 3.98851 0.400391 8.1875C0.400391 11.5505 2.57589 14.391 5.59689 15.398C5.97689 15.4645 6.11939 15.2365 6.11939 15.037C6.11939 14.8565 6.10989 14.258 6.10989 13.6215C4.20039 13.973 3.70639 13.156 3.55439 12.7285C3.46889 12.51 3.09839 11.8355 2.77539 11.655C2.50939 11.5125 2.12939 11.161 2.76589 11.1515C3.36439 11.142 3.79189 11.7025 3.93439 11.9305C4.61839 13.08 5.71089 12.757 6.14789 12.5575C6.21439 12.0635 6.41388 11.731 6.6324 11.541C4.94139 11.351 3.17439 10.6955 3.17439 7.7885C3.17439 6.962 3.46889 6.27801 3.95339 5.74601C3.87739 5.55601 3.61139 4.77701 4.02939 3.73201C4.02939 3.73201 4.66589 3.53251 6.11939 4.51101C6.7274 4.34001 7.3734 4.25451 8.0194 4.25451C8.6654 4.25451 9.3114 4.34001 9.9194 4.51101C11.3729 3.52301 12.0094 3.73201 12.0094 3.73201C12.4274 4.77701 12.1614 5.55601 12.0854 5.74601C12.5699 6.27801 12.8644 6.9525 12.8644 7.7885C12.8644 10.705 11.0879 11.351 9.3969 11.541C9.6724 11.7785 9.9099 12.2345 9.9099 12.947C9.9099 13.9635 9.9004 14.7805 9.9004 15.037C9.9004 15.2365 10.0429 15.474 10.4229 15.398C13.5165 14.3536 15.5996 11.4527 15.6004 8.1875C15.6004 3.98851 12.1994 0.587524 8.0004 0.587524Z" fill="#494369"/>
</g>
<defs>
<clipPath id="clip0_469_1929">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,37 +0,0 @@
<svg width="67" height="14" viewBox="0 0 67 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="67" height="14" fill="#1E1E1E"/>
<g id="Nav Template &#62; Initial" clip-path="url(#clip0_0_1)">
<rect width="1440" height="1024" transform="translate(-16 -17)" fill="white"/>
<g id="Sidebar">
<g clip-path="url(#clip1_0_1)">
<path d="M-16 -17H264V1007H-16V-17Z" fill="white"/>
<g id="Header">
<path d="M-16 -17H264V31H-16V-17Z" fill="white"/>
<g id="Button">
<rect x="-4" y="-3" width="74.316" height="20" rx="6" fill="white"/>
<g id="Logo">
<g id="Reflex">
<path d="M0 13.6316V0.368408H10.6106V5.67369H7.95792V3.02105H2.65264V5.67369H7.95792V8.32633H2.65264V13.6316H0ZM7.95792 13.6316V8.32633H10.6106V13.6316H7.95792Z" fill="#110F1F"/>
<path d="M13.2632 13.6316V0.368408H21.2211V3.02105H15.9158V5.67369H21.2211V8.32633H15.9158V10.979H21.2211V13.6316H13.2632Z" fill="#110F1F"/>
<path d="M23.8738 13.6316V0.368408H31.8317V3.02105H26.5264V5.67369H31.8317V8.32633H26.5264V13.6316H23.8738Z" fill="#110F1F"/>
<path d="M34.4843 13.6316V0.368408H37.137V10.979H42.4422V13.6316H34.4843Z" fill="#110F1F"/>
<path d="M45.0949 13.6316V0.368408H53.0528V3.02105H47.7475V5.67369H53.0528V8.32633H47.7475V10.979H53.0528V13.6316H45.0949Z" fill="#110F1F"/>
<path d="M55.7054 5.67369V0.368408H58.3581V5.67369H55.7054ZM63.6634 5.67369V0.368408H66.316V5.67369H63.6634ZM58.3581 8.32633V5.67369H63.6634V8.32633H58.3581ZM55.7054 13.6316V8.32633H58.3581V13.6316H55.7054ZM63.6634 13.6316V8.32633H66.316V13.6316H63.6634Z" fill="#110F1F"/>
</g>
</g>
</g>
<path d="M264 30.5H-16V31.5H264V30.5Z" fill="#F4F3F6"/>
</g>
</g>
<path d="M263.5 -17V1007H264.5V-17H263.5Z" fill="#F4F3F6"/>
</g>
</g>
<defs>
<clipPath id="clip0_0_1">
<rect width="1440" height="1024" fill="white" transform="translate(-16 -17)"/>
</clipPath>
<clipPath id="clip1_0_1">
<path d="M-16 -17H264V1007H-16V-17Z" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,68 +0,0 @@
<svg width="80" height="78" viewBox="0 0 80 78" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_ddddi_449_2821)">
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" fill="url(#paint0_radial_449_2821)"/>
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" fill="url(#paint1_radial_449_2821)"/>
<g filter="url(#filter1_i_449_2821)">
<path d="M31 37.5C30.4477 37.5 30 37.0523 30 36.5V13.5001C30 12.9478 30.4477 12.5001 31 12.5001H49C49.5523 12.5001 50 12.9478 50 13.5001V21.5001C50 22.0524 49.5523 22.5001 49 22.5001H45V18.5001C45 17.9478 44.5523 17.5001 44 17.5001H36C35.4477 17.5001 35 17.9478 35 18.5001V21.5001C35 22.0524 35.4477 22.5001 36 22.5001H45V27.5001H36C35.4477 27.5001 35 27.9478 35 28.5001V36.5C35 37.0523 34.5523 37.5 34 37.5H31ZM46 37.5C45.4477 37.5 45 37.0523 45 36.5V27.5001H49C49.5523 27.5001 50 27.9478 50 28.5001V36.5C50 37.0523 49.5523 37.5 49 37.5H46Z" fill="url(#paint2_radial_449_2821)"/>
</g>
<path d="M13 11C13 6.58172 16.5817 3 21 3H59C63.4183 3 67 6.58172 67 11V49C67 52.3137 64.3137 55 61 55H19C15.6863 55 13 52.3137 13 49V11Z" stroke="#20117E" stroke-opacity="0.04"/>
</g>
<defs>
<filter id="filter0_ddddi_449_2821" x="0.5" y="0.5" width="79" height="77" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect1_dropShadow_449_2821"/>
<feOffset dy="10"/>
<feGaussianBlur stdDeviation="8"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0784314 0 0 0 0 0.0705882 0 0 0 0 0.231373 0 0 0 0.06 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="6" operator="erode" in="SourceAlpha" result="effect2_dropShadow_449_2821"/>
<feOffset dy="12"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.0784314 0 0 0 0 0.0705882 0 0 0 0 0.231373 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_449_2821" result="effect2_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect3_dropShadow_449_2821"/>
<feOffset dy="10"/>
<feGaussianBlur stdDeviation="3"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.16 0"/>
<feBlend mode="normal" in2="effect2_dropShadow_449_2821" result="effect3_dropShadow_449_2821"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="effect4_dropShadow_449_2821"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.05 0"/>
<feBlend mode="normal" in2="effect3_dropShadow_449_2821" result="effect4_dropShadow_449_2821"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect4_dropShadow_449_2821" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="-8"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.678431 0 0 0 0 0.607843 0 0 0 0 0.972549 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="shape" result="effect5_innerShadow_449_2821"/>
</filter>
<filter id="filter1_i_449_2821" x="30" y="12.5001" width="20" height="26.9999" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="2"/>
<feGaussianBlur stdDeviation="1.5"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.12549 0 0 0 0 0.0666667 0 0 0 0 0.494118 0 0 0 0.32 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_449_2821"/>
</filter>
<radialGradient id="paint0_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 3) rotate(90) scale(52 54)">
<stop stop-color="white" stop-opacity="0.9"/>
<stop offset="1" stop-color="#4E3DB9" stop-opacity="0.24"/>
</radialGradient>
<radialGradient id="paint1_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 3) rotate(90) scale(52 54)">
<stop stop-color="white"/>
<stop offset="1" stop-color="#F7F7F7"/>
</radialGradient>
<radialGradient id="paint2_radial_449_2821" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(40 12.5001) rotate(90) scale(24.9999 20)">
<stop stop-color="#F5F3FF"/>
<stop stop-color="white"/>
<stop offset="1" stop-color="#E1DDF4"/>
</radialGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,13 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="PaneLeft" clip-path="url(#clip0_469_1942)">
<g id="Vector">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.80217 0.525009C7.34654 0.525009 6.97717 0.894373 6.97717 1.35001V10.65C6.97717 11.1056 7.34654 11.475 7.80217 11.475H10.6522C11.1078 11.475 11.4772 11.1056 11.4772 10.65V1.35001C11.4772 0.894373 11.1078 0.525009 10.6522 0.525009H7.80217ZM8.02717 10.425V1.57501H10.4272V10.425H8.02717Z" fill="#494369"/>
<path d="M3.78215 8.14502L2.16213 6.525H5.92717V5.475H2.16213L3.78215 3.85498L3.03969 3.11252L0.523438 5.62877V6.37123L3.03969 8.88748L3.78215 8.14502Z" fill="#494369"/>
</g>
</g>
<defs>
<clipPath id="clip0_469_1942">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 807 B

View File

@ -1 +0,0 @@
"""Base template for Reflex."""

View File

@ -1,127 +0,0 @@
"""Welcome to Reflex! This file outlines the steps to create a basic app."""
from typing import Callable
import reflex as rx
from .pages import chatapp_page, datatable_page, forms_page, graphing_page, home_page
from .sidebar import sidebar
from .state import State
from .styles import *
meta = [
{
"name": "viewport",
"content": "width=device-width, shrink-to-fit=no, initial-scale=1",
},
]
def template(main_content: Callable[[], rx.Component]) -> rx.Component:
"""The template for each page of the app.
Args:
main_content (Callable[[], rx.Component]): The main content of the page.
Returns:
rx.Component: The template for each page of the app.
"""
menu_button = rx.chakra.box(
rx.chakra.menu(
rx.chakra.menu_button(
rx.chakra.icon(
tag="hamburger",
size="4em",
color=text_color,
),
),
rx.chakra.menu_list(
rx.chakra.menu_item(rx.chakra.link("Home", href="/", width="100%")),
rx.chakra.menu_divider(),
rx.chakra.menu_item(
rx.chakra.link(
"About", href="https://github.com/reflex-dev", width="100%"
)
),
rx.chakra.menu_item(
rx.chakra.link(
"Contact", href="mailto:founders@reflex.dev", width="100%"
)
),
),
),
position="fixed",
right="1.5em",
top="1.5em",
z_index="500",
)
return rx.chakra.hstack(
sidebar(),
main_content(),
rx.chakra.spacer(),
menu_button,
align_items="flex-start",
transition="left 0.5s, width 0.5s",
position="relative",
left=rx.cond(State.sidebar_displayed, "0px", f"-{sidebar_width}"),
)
@rx.page("/", meta=meta)
@template
def home() -> rx.Component:
"""Home page.
Returns:
rx.Component: The home page.
"""
return home_page()
@rx.page("/forms", meta=meta)
@template
def forms() -> rx.Component:
"""Forms page.
Returns:
rx.Component: The settings page.
"""
return forms_page()
@rx.page("/graphing", meta=meta)
@template
def graphing() -> rx.Component:
"""Graphing page.
Returns:
rx.Component: The graphing page.
"""
return graphing_page()
@rx.page("/datatable", meta=meta)
@template
def datatable() -> rx.Component:
"""Data Table page.
Returns:
rx.Component: The chatapp page.
"""
return datatable_page()
@rx.page("/chatapp", meta=meta)
@template
def chatapp() -> rx.Component:
"""Chatapp page.
Returns:
rx.Component: The chatapp page.
"""
return chatapp_page()
# Create the app.
app = rx.App(style=base_style)

View File

@ -1,7 +0,0 @@
"""The pages of the app."""
from .chatapp import chatapp_page
from .datatable import datatable_page
from .forms import forms_page
from .graphing import graphing_page
from .home import home_page

View File

@ -1,31 +0,0 @@
"""The main Chat app."""
import reflex as rx
from ..styles import *
from ..webui import styles
from ..webui.components import chat, modal, navbar, sidebar
def chatapp_page() -> rx.Component:
"""The main app.
Returns:
The UI for the main app.
"""
return rx.chakra.box(
rx.chakra.vstack(
navbar(),
chat.chat(),
chat.action_bar(),
sidebar(),
modal(),
bg=styles.bg_dark_color,
color=styles.text_light_color,
min_h="100vh",
align_items="stretch",
spacing="0",
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,360 +0,0 @@
"""The settings page for the template."""
from typing import Any
import reflex as rx
from reflex.components.datadisplay.dataeditor import DataEditorTheme
from ..styles import *
from ..webui.state import State
class DataTableState(State):
"""Datatable state."""
cols: list[Any] = [
{"title": "Title", "type": "str"},
{
"title": "Name",
"type": "str",
"group": "Data",
"width": 300,
},
{
"title": "Birth",
"type": "str",
"group": "Data",
"width": 150,
},
{
"title": "Human",
"type": "bool",
"group": "Data",
"width": 80,
},
{
"title": "House",
"type": "str",
"group": "Data",
},
{
"title": "Wand",
"type": "str",
"group": "Data",
"width": 250,
},
{
"title": "Patronus",
"type": "str",
"group": "Data",
},
{
"title": "Blood status",
"type": "str",
"group": "Data",
"width": 200,
},
]
data = [
[
"1",
"Harry James Potter",
"31 July 1980",
True,
"Gryffindor",
"11' Holly phoenix feather",
"Stag",
"Half-blood",
],
[
"2",
"Ronald Bilius Weasley",
"1 March 1980",
True,
"Gryffindor",
"12' Ash unicorn tail hair",
"Jack Russell terrier",
"Pure-blood",
],
[
"3",
"Hermione Jean Granger",
"19 September, 1979",
True,
"Gryffindor",
"10¾' vine wood dragon heartstring",
"Otter",
"Muggle-born",
],
[
"4",
"Albus Percival Wulfric Brian Dumbledore",
"Late August 1881",
True,
"Gryffindor",
"15' Elder Thestral tail hair core",
"Phoenix",
"Half-blood",
],
[
"5",
"Rubeus Hagrid",
"6 December 1928",
False,
"Gryffindor",
"16' Oak unknown core",
"None",
"Part-Human (Half-giant)",
],
[
"6",
"Fred Weasley",
"1 April, 1978",
True,
"Gryffindor",
"Unknown",
"Unknown",
"Pure-blood",
],
[
"7",
"George Weasley",
"1 April, 1978",
True,
"Gryffindor",
"Unknown",
"Unknown",
"Pure-blood",
],
]
code_show = """rx.chakra.hstack(
rx.chakra.divider(orientation="vertical", height="100vh", border="solid black 1px"),
rx.chakra.vstack(
rx.chakra.box(
rx.data_editor(
columns=DataTableState.cols,
data=DataTableState.data,
draw_focus_ring=True,
row_height=50,
smooth_scroll_x=True,
smooth_scroll_y=True,
column_select="single",
# style
theme=DataEditorTheme(**darkTheme),
width="80vw",
height="80vh",
),
),
rx.chakra.spacer(),
height="100vh",
spacing="25",
),
)"""
state_show = """class DataTableState(State):
cols: list[Any] = [
{"title": "Title", "type": "str"},
{
"title": "Name",
"type": "str",
"group": "Data",
"width": 300,
},
{
"title": "Birth",
"type": "str",
"group": "Data",
"width": 150,
},
{
"title": "Human",
"type": "bool",
"group": "Data",
"width": 80,
},
{
"title": "House",
"type": "str",
"group": "Data",
},
{
"title": "Wand",
"type": "str",
"group": "Data",
"width": 250,
},
{
"title": "Patronus",
"type": "str",
"group": "Data",
},
{
"title": "Blood status",
"type": "str",
"group": "Data",
"width": 200,
},
]"""
data_show = """[
["1", "Harry James Potter", "31 July 1980", True, "Gryffindor", "11' Holly phoenix feather", "Stag", "Half-blood"],
["2", "Ronald Bilius Weasley", "1 March 1980", True,"Gryffindor", "12' Ash unicorn tail hair", "Jack Russell terrier", "Pure-blood"],
["3", "Hermione Jean Granger", "19 September, 1979", True, "Gryffindor", "10¾' vine wood dragon heartstring", "Otter", "Muggle-born"],
["4", "Albus Percival Wulfric Brian Dumbledore", "Late August 1881", True, "Gryffindor", "15' Elder Thestral tail hair core", "Phoenix", "Half-blood"],
["5", "Rubeus Hagrid", "6 December 1928", False, "Gryffindor", "16' Oak unknown core", "None", "Part-Human (Half-giant)"],
["6", "Fred Weasley", "1 April, 1978", True, "Gryffindor", "Unknown", "Unknown", "Pure-blood"],
["7", "George Weasley", "1 April, 1978", True, "Gryffindor", "Unknown", "Unknown", "Pure-blood"],
]"""
darkTheme = {
"accent_color": "#8c96ff",
"accent_light": "rgba(202, 206, 255, 0.253)",
"text_dark": "#ffffff",
"text_medium": "#b8b8b8",
"text_light": "#a0a0a0",
"text_bubble": "#ffffff",
"bg_icon_header": "#b8b8b8",
"fg_icon_header": "#000000",
"text_header": "#a1a1a1",
"text_header_selected": "#000000",
"bg_cell": "#16161b",
"bg_cell_medium": "#202027",
"bg_header": "#212121",
"bg_header_has_focus": "#474747",
"bg_header_hovered": "#404040",
"bg_bubble": "#212121",
"bg_bubble_selected": "#000000",
"bg_search_result": "#423c24",
"border_color": "rgba(225,225,225,0.2)",
"drilldown_border": "rgba(225,225,225,0.4)",
"link_color": "#4F5DFF",
"header_font_style": "bold 14px",
"base_font_style": "13px",
"font_family": "Inter, Roboto, -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, noto, arial, sans-serif",
}
darkTheme_show = """darkTheme={
"accent_color": "#8c96ff",
"accent_light": "rgba(202, 206, 255, 0.253)",
"text_dark": "#ffffff",
"text_medium": "#b8b8b8",
"text_light": "#a0a0a0",
"text_bubble": "#ffffff",
"bg_icon_header": "#b8b8b8",
"fg_icon_header": "#000000",
"text_header": "#a1a1a1",
"text_header_selected": "#000000",
"bg_cell": "#16161b",
"bg_cell_medium": "#202027",
"bg_header": "#212121",
"bg_header_has_focus": "#474747",
"bg_header_hovered": "#404040",
"bg_bubble": "#212121",
"bg_bubble_selected": "#000000",
"bg_search_result": "#423c24",
"border_color": "rgba(225,225,225,0.2)",
"drilldown_border": "rgba(225,225,225,0.4)",
"link_color": "#4F5DFF",
"header_font_style": "bold 14px",
"base_font_style": "13px",
"font_family": "Inter, Roboto, -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Ubuntu, noto, arial, sans-serif",
}"""
def datatable_page() -> rx.Component:
"""The UI for the settings page.
Returns:
rx.Component: The UI for the settings page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Data Table Demo",
font_size="3em",
),
rx.chakra.hstack(
rx.chakra.vstack(
rx.chakra.box(
rx.data_editor(
columns=DataTableState.cols,
data=DataTableState.data,
draw_focus_ring=True,
row_height=50,
smooth_scroll_x=True,
smooth_scroll_y=True,
column_select="single",
# style
theme=DataEditorTheme(**darkTheme),
width="80vw",
),
),
rx.chakra.spacer(),
spacing="25",
),
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("Data", style=tab_style),
rx.chakra.tab("State", style=tab_style),
rx.chakra.tab("Styling", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
code_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
data_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
state_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
darkTheme_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,257 +0,0 @@
"""The settings page for the template."""
import reflex as rx
from ..states.form_state import FormState, UploadState
from ..styles import *
forms_1_code = """rx.chakra.vstack(
rx.chakra.form(
rx.chakra.vstack(
rx.chakra.input(
placeholder="First Name",
id="first_name",
),
rx.chakra.input(
placeholder="Last Name", id="last_name"
),
rx.chakra.hstack(
rx.chakra.checkbox("Checked", id="check"),
rx.chakra.switch("Switched", id="switch"),
),
rx.chakra.button("Submit",
type_="submit",
bg="#ecfdf5",
color="#047857",
border_radius="lg",
),
),
on_submit=FormState.handle_submit,
),
rx.chakra.divider(),
rx.chakra.heading("Results"),
rx.chakra.text(FormState.form_data.to_string()),
width="100%",
)"""
color = "rgb(107,99,246)"
forms_1_state = """class FormState(rx.State):
form_data: dict = {}
def handle_submit(self, form_data: dict):
"Handle the form submit."
self.form_data = form_data"""
forms_2_code = """rx.chakra.vstack(
rx.upload(
rx.chakra.vstack(
rx.chakra.button(
"Select File",
color=color,
bg="white",
border=f"1px solid {color}",
),
rx.chakra.text(
"Drag and drop files here or click to select files"
),
),
border=f"1px dotted {color}",
padding="5em",
),
rx.chakra.hstack(rx.foreach(rx.selected_files, rx.chakra.text)),
rx.chakra.button(
"Upload",
on_click=lambda: UploadState.handle_upload(
rx.upload_files()
),
),
rx.chakra.button(
"Clear",
on_click=rx.clear_selected_files,
),
rx.foreach(
UploadState.img, lambda img: rx.chakra.image(src=img, width="20%", height="auto",)
),
padding="5em",
width="100%",
)"""
forms_2_state = """class UploadState(State):
"The app state."
# The images to show.
img: list[str]
async def handle_upload(
self, files: list[rx.UploadFile]
):
"Handle the upload of file(s).
Args:
files: The uploaded files.
"
for file in files:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(f"/{file.filename}")"""
def forms_page() -> rx.Component:
"""The UI for the settings page.
Returns:
rx.Component: The UI for the settings page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Forms Demo",
font_size="3em",
),
rx.chakra.vstack(
rx.chakra.form(
rx.chakra.vstack(
rx.chakra.input(
placeholder="First Name",
id="first_name",
),
rx.chakra.input(placeholder="Last Name", id="last_name"),
rx.chakra.hstack(
rx.chakra.checkbox("Checked", id="check"),
rx.chakra.switch("Switched", id="switch"),
),
rx.chakra.button(
"Submit",
type_="submit",
bg="#ecfdf5",
color="#047857",
border_radius="lg",
),
),
on_submit=FormState.handle_submit,
),
rx.chakra.divider(),
rx.chakra.heading("Results"),
rx.chakra.text(FormState.form_data.to_string()),
width="100%",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
forms_1_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
forms_1_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
rx.chakra.heading("Upload Example", font_size="3em"),
rx.chakra.text("Try uploading some images and see how they look."),
rx.chakra.vstack(
rx.upload(
rx.chakra.vstack(
rx.chakra.button(
"Select File",
color=color,
bg="white",
border=f"1px solid {color}",
),
rx.chakra.text(
"Drag and drop files here or click to select files"
),
),
border=f"1px dotted {color}",
padding="5em",
),
rx.chakra.hstack(rx.foreach(rx.selected_files, rx.chakra.text)),
rx.chakra.button(
"Upload",
on_click=lambda: UploadState.handle_upload(rx.upload_files()),
),
rx.chakra.button(
"Clear",
on_click=rx.clear_selected_files,
),
rx.foreach(
UploadState.img,
lambda img: rx.chakra.image(
src=img,
width="20%",
height="auto",
),
),
padding="5em",
width="100%",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
forms_2_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
forms_2_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,253 +0,0 @@
"""The dashboard page for the template."""
import reflex as rx
from ..states.pie_state import PieChartState
from ..styles import *
data_1 = [
{"name": "Page A", "uv": 4000, "pv": 2400, "amt": 2400},
{"name": "Page B", "uv": 3000, "pv": 1398, "amt": 2210},
{"name": "Page C", "uv": 2000, "pv": 9800, "amt": 2290},
{"name": "Page D", "uv": 2780, "pv": 3908, "amt": 2000},
{"name": "Page E", "uv": 1890, "pv": 4800, "amt": 2181},
{"name": "Page F", "uv": 2390, "pv": 3800, "amt": 2500},
{"name": "Page G", "uv": 3490, "pv": 4300, "amt": 2100},
]
data_1_show = """[
{"name": "Page A", "uv": 4000, "pv": 2400, "amt": 2400},
{"name": "Page B", "uv": 3000, "pv": 1398, "amt": 2210},
{"name": "Page C", "uv": 2000, "pv": 9800, "amt": 2290},
{"name": "Page D", "uv": 2780, "pv": 3908, "amt": 2000},
{"name": "Page E", "uv": 1890, "pv": 4800, "amt": 2181},
{"name": "Page F", "uv": 2390, "pv": 3800, "amt": 2500},
{"name": "Page G", "uv": 3490, "pv": 4300, "amt": 2100},
]"""
graph_1_code = """rx.recharts.composed_chart(
rx.recharts.area(
data_key="uv", stroke="#8884d8", fill="#8884d8"
),
rx.recharts.bar(
data_key="amt", bar_size=20, fill="#413ea0"
),
rx.recharts.line(
data_key="pv", type_="monotone", stroke="#ff7300"
),
rx.recharts.x_axis(data_key="name"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.graphing_tooltip(),
data=data,
)"""
graph_2_code = """rx.recharts.pie_chart(
rx.recharts.pie(
data=PieChartState.resources,
data_key="count",
name_key="type_",
cx="50%",
cy="50%",
start_angle=180,
end_angle=0,
fill="#8884d8",
label=True,
),
rx.recharts.graphing_tooltip(),
),
rx.chakra.vstack(
rx.foreach(
PieChartState.resource_types,
lambda type_, i: rx.chakra.hstack(
rx.chakra.button(
"-",
on_click=PieChartState.decrement(type_),
),
rx.chakra.text(
type_,
PieChartState.resources[i]["count"],
),
rx.chakra.button(
"+",
on_click=PieChartState.increment(type_),
),
),
),
)"""
graph_2_state = """class PieChartState(rx.State):
resources: list[dict[str, Any]] = [
dict(type_="🏆", count=1),
dict(type_="🪵", count=1),
dict(type_="🥑", count=1),
dict(type_="🧱", count=1),
]
@rx.cached_var
def resource_types(self) -> list[str]:
return [r["type_"] for r in self.resources]
def increment(self, type_: str):
for resource in self.resources:
if resource["type_"] == type_:
resource["count"] += 1
break
def decrement(self, type_: str):
for resource in self.resources:
if (
resource["type_"] == type_
and resource["count"] > 0
):
resource["count"] -= 1
break
"""
def graphing_page() -> rx.Component:
"""The UI for the dashboard page.
Returns:
rx.Component: The UI for the dashboard page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Graphing Demo",
font_size="3em",
),
rx.chakra.heading(
"Composed Chart",
font_size="2em",
),
rx.chakra.stack(
rx.recharts.composed_chart(
rx.recharts.area(data_key="uv", stroke="#8884d8", fill="#8884d8"),
rx.recharts.bar(data_key="amt", bar_size=20, fill="#413ea0"),
rx.recharts.line(data_key="pv", type_="monotone", stroke="#ff7300"),
rx.recharts.x_axis(data_key="name"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.graphing_tooltip(),
data=data_1,
# height="15em",
),
width="100%",
height="20em",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("Data", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
graph_1_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
data_1_show,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
rx.chakra.heading("Interactive Example", font_size="2em"),
rx.chakra.hstack(
rx.recharts.pie_chart(
rx.recharts.pie(
data=PieChartState.resources,
data_key="count",
name_key="type_",
cx="50%",
cy="50%",
start_angle=180,
end_angle=0,
fill="#8884d8",
label=True,
),
rx.recharts.graphing_tooltip(),
),
rx.chakra.vstack(
rx.foreach(
PieChartState.resource_types,
lambda type_, i: rx.chakra.hstack(
rx.chakra.button(
"-",
on_click=PieChartState.decrement(type_),
),
rx.chakra.text(
type_,
PieChartState.resources[i]["count"],
),
rx.chakra.button(
"+",
on_click=PieChartState.increment(type_),
),
),
),
),
width="100%",
height="15em",
),
rx.chakra.tabs(
rx.chakra.tab_list(
rx.chakra.tab("Code", style=tab_style),
rx.chakra.tab("State", style=tab_style),
padding_x=0,
),
rx.chakra.tab_panels(
rx.chakra.tab_panel(
rx.code_block(
graph_2_code,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
rx.chakra.tab_panel(
rx.code_block(
graph_2_state,
language="python",
show_line_numbers=True,
),
width="100%",
padding_x=0,
padding_y=".25em",
),
width="100%",
),
variant="unstyled",
color_scheme="purple",
align="end",
width="100%",
padding_top=".5em",
),
style=template_content_style,
min_h="100vh",
),
style=template_page_style,
min_h="100vh",
)

View File

@ -1,56 +0,0 @@
"""The home page of the app."""
import reflex as rx
from ..styles import *
def home_page() -> rx.Component:
"""The UI for the home page.
Returns:
rx.Component: The UI for the home page.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.heading(
"Welcome to Reflex! 👋",
font_size="3em",
),
rx.chakra.text(
"Reflex is an open-source app framework built specifically to allow you to build web apps in pure python. 👈 Select a demo from the sidebar to see some examples of what Reflex can do!",
),
rx.chakra.heading(
"Things to check out:",
font_size="2em",
),
rx.chakra.unordered_list(
rx.chakra.list_item(
"Take a look at ",
rx.chakra.link(
"reflex.dev",
href="https://reflex.dev",
color="rgb(107,99,246)",
),
),
rx.chakra.list_item(
"Check out our ",
rx.chakra.link(
"docs",
href="https://reflex.dev/docs/getting-started/introduction/",
color="rgb(107,99,246)",
),
),
rx.chakra.list_item(
"Ask a question in our ",
rx.chakra.link(
"community",
href="https://discord.gg/T5WSbC2YtQ",
color="rgb(107,99,246)",
),
),
),
style=template_content_style,
),
style=template_page_style,
)

View File

@ -1,178 +0,0 @@
"""Sidebar component for the app."""
import reflex as rx
from .state import State
from .styles import *
def sidebar_header() -> rx.Component:
"""Sidebar header.
Returns:
rx.Component: The sidebar header component.
"""
return rx.chakra.hstack(
rx.chakra.image(
src="/icon.svg",
height="2em",
),
rx.chakra.spacer(),
rx.chakra.link(
rx.chakra.center(
rx.chakra.image(
src="/github.svg",
height="3em",
padding="0.5em",
),
box_shadow=box_shadow,
bg="transparent",
border_radius=border_radius,
_hover={
"bg": accent_color,
},
),
href="https://github.com/reflex-dev/reflex",
),
width="100%",
border_bottom=border,
padding="1em",
)
def sidebar_footer() -> rx.Component:
"""Sidebar footer.
Returns:
rx.Component: The sidebar footer component.
"""
return rx.chakra.hstack(
rx.chakra.link(
rx.chakra.center(
rx.chakra.image(
src="/paneleft.svg",
height="2em",
padding="0.5em",
),
bg="transparent",
border_radius=border_radius,
**hover_accent_bg,
),
on_click=State.toggle_sidebar_displayed,
transform=rx.cond(~State.sidebar_displayed, "rotate(180deg)", ""),
transition="transform 0.5s, left 0.5s",
position="relative",
left=rx.cond(State.sidebar_displayed, "0px", "20.5em"),
**overlapping_button_style,
),
rx.chakra.spacer(),
rx.chakra.link(
rx.chakra.text(
"Docs",
),
href="https://reflex.dev/docs/getting-started/introduction/",
),
rx.chakra.link(
rx.chakra.text(
"Blog",
),
href="https://reflex.dev/blog/",
),
width="100%",
border_top=border,
padding="1em",
)
def sidebar_item(text: str, icon: str, url: str) -> rx.Component:
"""Sidebar item.
Args:
text (str): The text of the item.
icon (str): The icon of the item.
url (str): The URL of the item.
Returns:
rx.Component: The sidebar item component.
"""
return rx.chakra.link(
rx.chakra.hstack(
rx.chakra.image(
src=icon,
height="2.5em",
padding="0.5em",
),
rx.chakra.text(
text,
),
bg=rx.cond(
State.origin_url == f"/{text.lower()}/",
accent_color,
"transparent",
),
color=rx.cond(
State.origin_url == f"/{text.lower()}/",
accent_text_color,
text_color,
),
border_radius=border_radius,
box_shadow=box_shadow,
width="100%",
padding_x="1em",
),
href=url,
width="100%",
)
def sidebar() -> rx.Component:
"""Sidebar.
Returns:
rx.Component: The sidebar component.
"""
return rx.chakra.box(
rx.chakra.vstack(
sidebar_header(),
rx.chakra.vstack(
sidebar_item(
"Welcome",
"/github.svg",
"/",
),
sidebar_item(
"Graphing Demo",
"/github.svg",
"/graphing",
),
sidebar_item(
"Data Table Demo",
"/github.svg",
"/datatable",
),
sidebar_item(
"Forms Demo",
"/github.svg",
"/forms",
),
sidebar_item(
"Chat App Demo",
"/github.svg",
"/chatapp",
),
width="100%",
overflow_y="auto",
align_items="flex-start",
padding="1em",
),
rx.chakra.spacer(),
sidebar_footer(),
height="100dvh",
),
display=["none", "none", "block"],
min_width=sidebar_width,
height="100%",
position="sticky",
top="0px",
border_right=border,
)

View File

@ -1,22 +0,0 @@
"""Base state for the app."""
import reflex as rx
class State(rx.State):
"""State for the app."""
sidebar_displayed: bool = True
@rx.var
def origin_url(self) -> str:
"""Get the url of the current page.
Returns:
str: The url of the current page.
"""
return self.router_data.get("asPath", "")
def toggle_sidebar_displayed(self) -> None:
"""Toggle the sidebar displayed."""
self.sidebar_displayed = not self.sidebar_displayed

View File

@ -1,40 +0,0 @@
import reflex as rx
from ..state import State
class FormState(State):
"""Form state."""
form_data: dict = {}
def handle_submit(self, form_data: dict):
"""Handle the form submit.
Args:
form_data: The form data.
"""
self.form_data = form_data
class UploadState(State):
"""The app state."""
# The images to show.
img: list[str]
async def handle_upload(self, files: list[rx.UploadFile]):
"""Handle the upload of file(s).
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = rx.get_asset_path(file.filename)
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img.append(f"/{file.filename}")

View File

@ -1,47 +0,0 @@
from typing import Any
import reflex as rx
from ..state import State
class PieChartState(State):
"""Pie Chart State."""
resources: list[dict[str, Any]] = [
dict(type_="🏆", count=1),
dict(type_="🪵", count=1),
dict(type_="🥑", count=1),
dict(type_="🧱", count=1),
]
@rx.cached_var
def resource_types(self) -> list[str]:
"""Get the resource types.
Returns:
The resource types.
"""
return [r["type_"] for r in self.resources]
def increment(self, type_: str):
"""Increment the count of a resource type.
Args:
type_: The type of resource to increment.
"""
for resource in self.resources:
if resource["type_"] == type_:
resource["count"] += 1
break
def decrement(self, type_: str):
"""Decrement the count of a resource type.
Args:
type_: The type of resource to decrement.
"""
for resource in self.resources:
if resource["type_"] == type_ and resource["count"] > 0:
resource["count"] -= 1
break

View File

@ -1,68 +0,0 @@
"""Styles for the app."""
import reflex as rx
from .state import State
border_radius = "0.375rem"
box_shadow = "0px 0px 0px 1px rgba(84, 82, 95, 0.14)"
border = "1px solid #F4F3F6"
text_color = "black"
accent_text_color = "#1A1060"
accent_color = "#F5EFFE"
hover_accent_color = {"_hover": {"color": accent_color}}
hover_accent_bg = {"_hover": {"bg": accent_color}}
content_width_vw = "90vw"
sidebar_width = "20em"
template_page_style = {
"padding_top": "5em",
"padding_x": "2em",
}
template_content_style = {
"width": rx.cond(
State.sidebar_displayed,
f"calc({content_width_vw} - {sidebar_width})",
content_width_vw,
),
"min-width": sidebar_width,
"align_items": "flex-start",
"box_shadow": box_shadow,
"border_radius": border_radius,
"padding": "1em",
"margin_bottom": "2em",
}
link_style = {
"color": text_color,
"text_decoration": "none",
**hover_accent_color,
}
overlapping_button_style = {
"background_color": "white",
"border": border,
"border_radius": border_radius,
}
base_style = {
rx.chakra.MenuButton: {
"width": "3em",
"height": "3em",
**overlapping_button_style,
},
rx.chakra.MenuItem: hover_accent_bg,
}
tab_style = {
"color": "#494369",
"font_weight": 600,
"_selected": {
"color": "#5646ED",
"bg": "#F5EFFE",
"padding_x": "0.5em",
"padding_y": "0.25em",
"border_radius": "8px",
},
}

View File

@ -1,4 +0,0 @@
from .loading_icon import loading_icon
from .modal import modal
from .navbar import navbar
from .sidebar import sidebar

View File

@ -1,118 +0,0 @@
import reflex as rx
from ...webui import styles
from ...webui.components import loading_icon
from ...webui.state import QA, State
def message(qa: QA) -> rx.Component:
"""A single question/answer message.
Args:
qa: The question/answer pair.
Returns:
A component displaying the question/answer pair.
"""
return rx.chakra.box(
rx.chakra.box(
rx.chakra.text(
qa.question,
bg=styles.border_color,
shadow=styles.shadow_light,
**styles.message_style,
),
text_align="right",
margin_top="1em",
),
rx.chakra.box(
rx.chakra.text(
qa.answer,
bg=styles.accent_color,
shadow=styles.shadow_light,
**styles.message_style,
),
text_align="left",
padding_top="1em",
),
width="100%",
)
def chat() -> rx.Component:
"""List all the messages in a single conversation.
Returns:
A component displaying all the messages in a single conversation.
"""
return rx.chakra.vstack(
rx.chakra.box(rx.foreach(State.chats[State.current_chat], message)),
py="8",
flex="1",
width="100%",
max_w="3xl",
padding_x="4",
align_self="center",
overflow="hidden",
padding_bottom="5em",
**styles.base_style[rx.chakra.Vstack],
)
def action_bar() -> rx.Component:
"""The action bar to send a new message.
Returns:
The action bar to send a new message.
"""
return rx.chakra.box(
rx.chakra.vstack(
rx.chakra.form(
rx.chakra.form_control(
rx.chakra.hstack(
rx.chakra.input(
placeholder="Type something...",
value=State.question,
on_change=State.set_question,
_placeholder={"color": "#fffa"},
_hover={"border_color": styles.accent_color},
style=styles.input_style,
),
rx.chakra.button(
rx.cond(
State.processing,
loading_icon(height="1em"),
rx.chakra.text("Send"),
),
type_="submit",
_hover={"bg": styles.accent_color},
style=styles.input_style,
),
**styles.base_style[rx.chakra.Hstack],
),
is_disabled=State.processing,
),
on_submit=State.process_question,
width="100%",
),
rx.chakra.text(
"ReflexGPT may return factually incorrect or misleading responses. Use discretion.",
font_size="xs",
color="#fff6",
text_align="center",
),
width="100%",
max_w="3xl",
mx="auto",
**styles.base_style[rx.chakra.Vstack],
),
position="sticky",
bottom="0",
left="0",
py="4",
backdrop_filter="auto",
backdrop_blur="lg",
border_top=f"1px solid {styles.border_color}",
align_items="stretch",
width="100%",
)

View File

@ -1,19 +0,0 @@
import reflex as rx
class LoadingIcon(rx.Component):
"""A custom loading icon component."""
library = "react-loading-icons"
tag = "SpinningCircles"
stroke: rx.Var[str]
stroke_opacity: rx.Var[str]
fill: rx.Var[str]
fill_opacity: rx.Var[str]
stroke_width: rx.Var[str]
speed: rx.Var[str]
height: rx.Var[str]
on_change: rx.EventHandler[lambda status: [status]]
loading_icon = LoadingIcon.create

View File

@ -1,56 +0,0 @@
import reflex as rx
from ...webui.state import State
def modal() -> rx.Component:
"""A modal to create a new chat.
Returns:
The modal component.
"""
return rx.chakra.modal(
rx.chakra.modal_overlay(
rx.chakra.modal_content(
rx.chakra.modal_header(
rx.chakra.hstack(
rx.chakra.text("Create new chat"),
rx.chakra.icon(
tag="close",
font_size="sm",
on_click=State.toggle_modal,
color="#fff8",
_hover={"color": "#fff"},
cursor="pointer",
),
align_items="center",
justify_content="space-between",
)
),
rx.chakra.modal_body(
rx.chakra.input(
placeholder="Type something...",
on_blur=State.set_new_chat_name,
bg="#222",
border_color="#fff3",
_placeholder={"color": "#fffa"},
),
),
rx.chakra.modal_footer(
rx.chakra.button(
"Create",
bg="#5535d4",
box_shadow="md",
px="4",
py="2",
h="auto",
_hover={"bg": "#4c2db3"},
on_click=State.create_chat,
),
),
bg="#222",
color="#fff",
),
),
is_open=State.modal_open,
)

View File

@ -1,70 +0,0 @@
import reflex as rx
from ...webui import styles
from ...webui.state import State
def navbar():
return rx.chakra.box(
rx.chakra.hstack(
rx.chakra.hstack(
rx.chakra.icon(
tag="hamburger",
mr=4,
on_click=State.toggle_drawer,
cursor="pointer",
),
rx.chakra.link(
rx.chakra.box(
rx.chakra.image(src="favicon.ico", width=30, height="auto"),
p="1",
border_radius="6",
bg="#F0F0F0",
mr="2",
),
href="/",
),
rx.chakra.breadcrumb(
rx.chakra.breadcrumb_item(
rx.chakra.heading("ReflexGPT", size="sm"),
),
rx.chakra.breadcrumb_item(
rx.chakra.text(
State.current_chat, size="sm", font_weight="normal"
),
),
),
),
rx.chakra.hstack(
rx.chakra.button(
"+ New chat",
bg=styles.accent_color,
px="4",
py="2",
h="auto",
on_click=State.toggle_modal,
),
rx.chakra.menu(
rx.chakra.menu_button(
rx.chakra.avatar(name="User", size="md"),
rx.chakra.box(),
),
rx.chakra.menu_list(
rx.chakra.menu_item("Help"),
rx.chakra.menu_divider(),
rx.chakra.menu_item("Settings"),
),
),
spacing="8",
),
justify="space-between",
),
bg=styles.bg_dark_color,
backdrop_filter="auto",
backdrop_blur="lg",
p="4",
border_bottom=f"1px solid {styles.border_color}",
position="sticky",
top="0",
z_index="100",
)

View File

@ -1,66 +0,0 @@
import reflex as rx
from ...webui import styles
from ...webui.state import State
def sidebar_chat(chat: str) -> rx.Component:
"""A sidebar chat item.
Args:
chat: The chat item.
Returns:
The sidebar chat item.
"""
return rx.chakra.hstack(
rx.chakra.box(
chat,
on_click=lambda: State.set_chat(chat),
style=styles.sidebar_style,
color=styles.icon_color,
flex="1",
),
rx.chakra.box(
rx.chakra.icon(
tag="delete",
style=styles.icon_style,
on_click=State.delete_chat,
),
style=styles.sidebar_style,
),
color=styles.text_light_color,
cursor="pointer",
)
def sidebar() -> rx.Component:
"""The sidebar component.
Returns:
The sidebar component.
"""
return rx.chakra.drawer(
rx.chakra.drawer_overlay(
rx.chakra.drawer_content(
rx.chakra.drawer_header(
rx.chakra.hstack(
rx.chakra.text("Chats"),
rx.chakra.icon(
tag="close",
on_click=State.toggle_drawer,
style=styles.icon_style,
),
)
),
rx.chakra.drawer_body(
rx.chakra.vstack(
rx.foreach(State.chat_titles, lambda chat: sidebar_chat(chat)),
align_items="stretch",
)
),
),
),
placement="left",
is_open=State.drawer_open,
)

View File

@ -1,146 +0,0 @@
import asyncio
import reflex as rx
from ..state import State
# openai.api_key = os.environ["OPENAI_API_KEY"]
# openai.api_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
class QA(rx.Base):
"""A question and answer pair."""
question: str
answer: str
DEFAULT_CHATS = {
"Intros": [],
}
class State(State):
"""The app state."""
# A dict from the chat name to the list of questions and answers.
chats: dict[str, list[QA]] = DEFAULT_CHATS
# The current chat name.
current_chat = "Intros"
# The current question.
question: str
# Whether we are processing the question.
processing: bool = False
# The name of the new chat.
new_chat_name: str = ""
# Whether the drawer is open.
drawer_open: bool = False
# Whether the modal is open.
modal_open: bool = False
def create_chat(self):
"""Create a new chat."""
# Add the new chat to the list of chats.
self.current_chat = self.new_chat_name
self.chats[self.new_chat_name] = []
# Toggle the modal.
self.modal_open = False
def toggle_modal(self):
"""Toggle the new chat modal."""
self.modal_open = not self.modal_open
def toggle_drawer(self):
"""Toggle the drawer."""
self.drawer_open = not self.drawer_open
def delete_chat(self):
"""Delete the current chat."""
del self.chats[self.current_chat]
if len(self.chats) == 0:
self.chats = DEFAULT_CHATS
# set self.current_chat to the first chat.
self.current_chat = next(iter(self.chats))
self.toggle_drawer()
def set_chat(self, chat_name: str):
"""Set the name of the current chat.
Args:
chat_name: The name of the chat.
"""
self.current_chat = chat_name
self.toggle_drawer()
@rx.var
def chat_titles(self) -> list[str]:
"""Get the list of chat titles.
Returns:
The list of chat names.
"""
return [*self.chats]
async def process_question(self, form_data: dict[str, str]):
"""Get the response from the API.
Args:
form_data: A dict with the current question.
Yields:
The current question and the response.
"""
# Check if the question is empty
if self.question == "":
return
# Add the question to the list of questions.
qa = QA(question=self.question, answer="")
self.chats[self.current_chat].append(qa)
# Clear the input and start the processing.
self.processing = True
self.question = ""
yield
# # Build the messages.
# messages = [
# {"role": "system", "content": "You are a friendly chatbot named Reflex."}
# ]
# for qa in self.chats[self.current_chat]:
# messages.append({"role": "user", "content": qa.question})
# messages.append({"role": "assistant", "content": qa.answer})
# # Remove the last mock answer.
# messages = messages[:-1]
# Start a new session to answer the question.
# session = openai.ChatCompletion.create(
# model=os.getenv("OPENAI_MODEL", "gpt-3.5-turbo"),
# messages=messages,
# stream=True,
# )
# Stream the results, yielding after every word.
# for item in session:
answer = "I don't know! This Chatbot still needs to add in AI API keys!"
for i in range(len(answer)):
# Pause to show the streaming effect.
await asyncio.sleep(0.1)
# Add one letter at a time to the output.
# if hasattr(item.choices[0].delta, "content"):
# answer_text = item.choices[0].delta.content
self.chats[self.current_chat][-1].answer += answer[i]
self.chats = self.chats
yield
# Toggle the processing flag.
self.processing = False

View File

@ -1,88 +0,0 @@
import reflex as rx
bg_dark_color = "#111"
bg_medium_color = "#222"
border_color = "#fff3"
accennt_light = "#6649D8"
accent_color = "#5535d4"
accent_dark = "#4c2db3"
icon_color = "#fff8"
text_light_color = "#fff"
shadow_light = "rgba(17, 12, 46, 0.15) 0px 48px 100px 0px;"
shadow = "rgba(50, 50, 93, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px, rgba(10, 37, 64, 0.35) 0px -2px 6px 0px inset;"
message_style = dict(display="inline-block", p="4", border_radius="xl", max_w="30em")
input_style = dict(
bg=bg_medium_color,
border_color=border_color,
border_width="1px",
p="4",
)
icon_style = dict(
font_size="md",
color=icon_color,
_hover=dict(color=text_light_color),
cursor="pointer",
w="8",
)
sidebar_style = dict(
border="double 1px transparent;",
border_radius="10px;",
background_image=f"linear-gradient({bg_dark_color}, {bg_dark_color}), radial-gradient(circle at top left, {accent_color},{accent_dark});",
background_origin="border-box;",
background_clip="padding-box, border-box;",
p="2",
_hover=dict(
background_image=f"linear-gradient({bg_dark_color}, {bg_dark_color}), radial-gradient(circle at top left, {accent_color},{accennt_light});",
),
)
base_style = {
rx.chakra.Avatar: {
"shadow": shadow,
"color": text_light_color,
# "bg": border_color,
},
rx.chakra.Button: {
"shadow": shadow,
"color": text_light_color,
"_hover": {
"bg": accent_dark,
},
},
rx.chakra.Menu: {
"bg": bg_dark_color,
"border": f"red",
},
rx.chakra.MenuList: {
"bg": bg_dark_color,
"border": f"1.5px solid {bg_medium_color}",
},
rx.chakra.MenuDivider: {
"border": f"1px solid {bg_medium_color}",
},
rx.chakra.MenuItem: {
"bg": bg_dark_color,
"color": text_light_color,
},
rx.chakra.DrawerContent: {
"bg": bg_dark_color,
"color": text_light_color,
"opacity": "0.9",
},
rx.chakra.Hstack: {
"align_items": "center",
"justify_content": "space-between",
},
rx.chakra.Vstack: {
"align_items": "stretch",
"justify_content": "space-between",
},
}