Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ jobs:
ai_image_gen)
echo "EXTRA_ARGS=--env REPLICATE_API_TOKEN=${{ secrets.REPLICATE_API_TOKEN }}" >> $GITHUB_ENV
;;
admin_dashboard)
echo "EXTRA_ARGS=" >> $GITHUB_ENV
;;
stock_market_dashboard)
echo "EXTRA_ARGS=" >> $GITHUB_ENV
;;
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
.web
__pycache__/
venv/
*/.DS_Store
*/.DS_Store
.idea
11 changes: 11 additions & 0 deletions admin_dashboard/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.states
assets/external/
*.db
*.py[cod]
.venv/
venv/
.vscode/
.web
__pycache__/
.DS_Store
.idea/
Empty file.
69 changes: 69 additions & 0 deletions admin_dashboard/admin_dashboard/admin_dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import reflex as rx
import reflex.components.radix.themes as rdxt

from admin_dashboard.components.customer_details import customer_details
from admin_dashboard.components.data_table import data_table
from admin_dashboard.components.navigation import navigation


def index() -> rx.Component:
"""The main page layout for the dashboard."""
return rdxt.theme(
rx.el.div(
navigation(),
rx.el.div(
rx.el.div(
data_table(),
class_name="flex-grow p-6 overflow-y-auto",
),
customer_details(),
class_name="flex flex-row h-[calc(100vh-56px)] overflow-hidden",
),
class_name="bg-gray-100 h-screen overflow-hidden",
),
appearance="light",
)


def mock_page(title: str) -> rx.Component:
"""Creates a simple mock page layout."""
return rdxt.theme(
rx.el.div(
navigation(),
rx.el.div(
rx.el.h1(
title,
class_name="text-2xl font-bold mb-4 text-gray-800",
),
rx.el.p(
f"Content for {title} goes here.",
class_name="text-gray-600",
),
class_name="p-6",
),
class_name="bg-gray-100 h-screen",
),
appearance="light",
)


def sales_pipeline_page() -> rx.Component:
"""Mock Sales Pipeline page."""
return mock_page("Sales Pipeline")


def hr_portal_page() -> rx.Component:
"""Mock HR Portal page."""
return mock_page("HR Portal")


def customer_success_hub_page() -> rx.Component:
"""Mock Customer Success Hub page."""
return mock_page("Customer Success Hub")


app = rx.App(theme=rx.theme(appearance="light"), stylesheets=[])
app.add_page(index, route="/")
app.add_page(sales_pipeline_page, route="/sales-pipeline")
app.add_page(hr_portal_page, route="/hr-portal")
app.add_page(customer_success_hub_page, route="/customer-success-hub")
Empty file.
180 changes: 180 additions & 0 deletions admin_dashboard/admin_dashboard/components/customer_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import reflex as rx
import reflex.components.recharts as recharts

from admin_dashboard.states.dashboard_state import (
CustomerData,
DashboardState,
)


def detail_item(label: str, value: rx.Var[str]) -> rx.Component:
"""Displays a single detail item with label and value."""
return rx.el.div(
rx.el.dt(
label,
class_name="text-sm font-medium text-gray-500",
),
rx.el.dd(value, class_name="mt-1 text-sm text-gray-900"),
class_name="py-2",
)


def license_stat(label: str, value: rx.Var[int], change: rx.Var[int]) -> rx.Component:
"""Displays a license statistic card."""
return rx.el.div(
rx.el.p(
label,
class_name="text-sm font-medium text-gray-500",
),
rx.el.div(
rx.el.span(
value,
class_name="text-3xl font-bold text-gray-900 mr-2",
),
rx.el.span(
rx.icon(
rx.cond(change > 0, "arrow-up", "arrow-down"),
size=16,
class_name="mr-1",
),
rx.cond(change < 0, change * -1, change),
"%",
class_name=rx.cond(
change > 0,
"text-sm font-medium text-green-600 bg-green-100 px-2 py-0.5 rounded-full inline-flex items-center",
"text-sm font-medium text-red-600 bg-red-100 px-2 py-0.5 rounded-full inline-flex items-center",
),
),
class_name="flex items-baseline",
),
class_name="p-4 bg-white rounded-lg border border-gray-200 shadow-sm",
)


def customer_details_panel(
customer: CustomerData,
) -> rx.Component:
"""Panel showing detailed information about a selected customer."""
usage_percentage = rx.cond(
customer["licenses"] > 0,
round(customer["active_licenses"] * 100 / customer["licenses"]).to(int),
0,
)
return rx.el.div(
rx.el.h3(
customer["customer_name"],
class_name="text-xl font-semibold text-gray-900 mb-4",
),
rx.el.div(
rx.el.h4(
"Usage",
class_name="text-md font-medium text-gray-700 mb-2",
),
rx.el.div(
rx.el.p(
usage_percentage.to_string() + "%",
class_name="text-5xl font-bold text-emerald-600 text-center",
),
class_name="flex items-center justify-center w-32 h-32 rounded-full bg-emerald-50 border-4 border-emerald-200 mx-auto mb-4",
),
class_name="mb-6 p-4 bg-white rounded-lg border border-gray-200 shadow-sm",
),
rx.el.div(
rx.el.h4(
"Details",
class_name="text-md font-medium text-gray-700 mb-2",
),
rx.el.dl(
detail_item(
"Revenue",
"$" + customer["revenue"].to_string(),
),
detail_item("Platform Type", customer["platform"]),
detail_item("Industry", customer["industry"]),
),
class_name="mb-6 p-4 bg-white rounded-lg border border-gray-200 divide-y divide-gray-200 shadow-sm",
),
rx.el.div(
rx.el.h4(
"License Utilization",
class_name="text-md font-medium text-gray-700 mb-3",
),
rx.el.div(
license_stat(
"Active Licenses",
customer["active_licenses"],
customer["active_license_growth"],
),
license_stat(
"Total Licenses",
customer["licenses"],
customer["license_growth"],
),
class_name="grid grid-cols-2 gap-4 mb-4",
),
class_name="mb-6",
),
rx.el.div(
rx.el.h4(
"Usage Over Time",
class_name="text-md font-medium text-gray-700 mb-2",
),
rx.el.div(
recharts.line_chart(
recharts.cartesian_grid(
horizontal=True,
vertical=False,
class_name="opacity-25 stroke-gray-300",
),
recharts.line(
data_key="usage",
stroke="#10B981",
stroke_width=2,
dot=False,
type_="natural",
),
recharts.x_axis(
data_key="month",
axis_line=False,
tick_size=10,
tick_line=False,
interval="preserveStartEnd",
),
recharts.y_axis(
axis_line=False,
tick_size=0,
tick_line=False,
width=30,
),
data=customer["usage_history"],
height=250,
margin={
"top": 5,
"right": 10,
"left": 0,
"bottom": 5,
},
),
class_name="p-2 bg-white rounded-lg border border-gray-200 flex items-center justify-center shadow-sm",
),
),
class_name="px-5 pt-5 pb-14 bg-gray-50 rounded-lg shadow-inner h-[100vh] overflow-y-auto",
)


def customer_details() -> rx.Component:
"""Component to display details of the selected customer or a placeholder."""
return rx.el.div(
rx.cond(
DashboardState.selected_customer,
customer_details_panel(DashboardState.selected_customer),
rx.el.div(
rx.el.p(
"Select a customer to see details.",
class_name="text-center text-gray-500 text-lg",
),
class_name="flex items-center justify-center h-[100vh] p-5 bg-gray-50 rounded-lg shadow-inner",
),
),
class_name="w-1/3 flex-shrink-0 h-[100vh] overflow-hidden sticky top-0 right-0 border-l border-gray-200",
)
Loading