Skip to content

Commit bd6ee00

Browse files
committed
more changes
1 parent 3723a4d commit bd6ee00

File tree

12 files changed

+402
-443
lines changed

12 files changed

+402
-443
lines changed

admin_dashboard/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ venv/
88
.web
99
__pycache__/
1010
.DS_Store
11-
.idea/
11+
.idea/

admin_dashboard/admin_dashboard/admin_dashboard.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import reflex as rx
2-
from admin_dashboard.components.navigation import navigation
3-
from admin_dashboard.components.data_table import data_table
4-
from admin_dashboard.components.customer_details import customer_details
52
import reflex.components.radix.themes as rdxt
63

4+
from admin_dashboard.components.customer_details import customer_details
5+
from admin_dashboard.components.data_table import data_table
6+
from admin_dashboard.components.navigation import navigation
7+
78

89
def index() -> rx.Component:
910
"""The main page layout for the dashboard."""
@@ -61,12 +62,8 @@ def customer_success_hub_page() -> rx.Component:
6162
return mock_page("Customer Success Hub")
6263

6364

64-
app = rx.App(
65-
theme=rx.theme(appearance="light"), stylesheets=[]
66-
)
65+
app = rx.App(theme=rx.theme(appearance="light"), stylesheets=[])
6766
app.add_page(index, route="/")
6867
app.add_page(sales_pipeline_page, route="/sales-pipeline")
6968
app.add_page(hr_portal_page, route="/hr-portal")
70-
app.add_page(
71-
customer_success_hub_page, route="/customer-success-hub"
72-
)
69+
app.add_page(customer_success_hub_page, route="/customer-success-hub")

admin_dashboard/admin_dashboard/components/customer_details.py

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
11
import reflex as rx
22
import reflex.components.recharts as recharts
3+
34
from admin_dashboard.states.dashboard_state import (
4-
DashboardState,
55
CustomerData,
6+
DashboardState,
67
)
7-
from typing import Optional
88

99

10-
def detail_item(
11-
label: str, value: rx.Var[str]
12-
) -> rx.Component:
10+
def detail_item(label: str, value: rx.Var[str]) -> rx.Component:
1311
"""Displays a single detail item with label and value."""
1412
return rx.el.div(
1513
rx.el.dt(
1614
label,
1715
class_name="text-sm font-medium text-gray-500",
1816
),
19-
rx.el.dd(
20-
value, class_name="mt-1 text-sm text-gray-900"
21-
),
17+
rx.el.dd(value, class_name="mt-1 text-sm text-gray-900"),
2218
class_name="py-2",
2319
)
2420

2521

26-
def license_stat(
27-
label: str, value: rx.Var[int], change: rx.Var[int]
28-
) -> rx.Component:
22+
def license_stat(label: str, value: rx.Var[int], change: rx.Var[int]) -> rx.Component:
2923
"""Displays a license statistic card."""
3024
return rx.el.div(
3125
rx.el.p(
@@ -39,9 +33,7 @@ def license_stat(
3933
),
4034
rx.el.span(
4135
rx.icon(
42-
rx.cond(
43-
change > 0, "arrow-up", "arrow-down"
44-
),
36+
rx.cond(change > 0, "arrow-up", "arrow-down"),
4537
size=16,
4638
class_name="mr-1",
4739
),
@@ -65,11 +57,7 @@ def customer_details_panel(
6557
"""Panel showing detailed information about a selected customer."""
6658
usage_percentage = rx.cond(
6759
customer["licenses"] > 0,
68-
round(
69-
customer["active_licenses"]
70-
* 100
71-
/ customer["licenses"]
72-
).to(int),
60+
round(customer["active_licenses"] * 100 / customer["licenses"]).to(int),
7361
0,
7462
)
7563
return rx.el.div(
@@ -101,12 +89,8 @@ def customer_details_panel(
10189
"Revenue",
10290
"$" + customer["revenue"].to_string(),
10391
),
104-
detail_item(
105-
"Platform Type", customer["platform"]
106-
),
107-
detail_item(
108-
"Industry", customer["industry"]
109-
),
92+
detail_item("Platform Type", customer["platform"]),
93+
detail_item("Industry", customer["industry"]),
11094
),
11195
class_name="mb-6 p-4 bg-white rounded-lg border border-gray-200 divide-y divide-gray-200 shadow-sm",
11296
),
@@ -183,9 +167,7 @@ def customer_details() -> rx.Component:
183167
return rx.el.div(
184168
rx.cond(
185169
DashboardState.selected_customer,
186-
customer_details_panel(
187-
DashboardState.selected_customer
188-
),
170+
customer_details_panel(DashboardState.selected_customer),
189171
rx.el.div(
190172
rx.el.p(
191173
"Select a customer to see details.",
@@ -195,4 +177,4 @@ def customer_details() -> rx.Component:
195177
),
196178
),
197179
class_name="w-1/3 flex-shrink-0 h-[100vh] overflow-hidden sticky top-0 right-0 border-l border-gray-200",
198-
)
180+
)

admin_dashboard/admin_dashboard/components/data_table.py

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
from typing import Optional, Tuple
2+
13
import reflex as rx
4+
25
from admin_dashboard.states.dashboard_state import (
6+
CustomerData,
37
DashboardState,
48
SortColumn,
5-
SortOrder,
6-
CustomerData,
79
)
8-
from typing import Optional, List, Tuple
910

1011

1112
def platform_tag(platform: rx.Var[str]) -> rx.Component:
@@ -56,12 +57,12 @@ def industry_tag(industry: rx.Var[str]) -> rx.Component:
5657

5758
def sort_icon(column_key: SortColumn) -> rx.Component:
5859
"""Displays sort direction icon or a neutral sortable indicator."""
59-
icon_base_class = "ml-1 inline-block w-3 h-3 transition-colors duration-150 ease-in-out"
60+
icon_base_class = (
61+
"ml-1 inline-block w-3 h-3 transition-colors duration-150 ease-in-out"
62+
)
6063
active_icon_class = f"{icon_base_class} text-gray-700"
6164
inactive_icon_class = f"{icon_base_class} text-gray-400 group-hover:text-gray-600"
62-
is_active_column = (
63-
DashboardState.sort_column == column_key
64-
)
65+
is_active_column = DashboardState.sort_column == column_key
6566
return rx.cond(
6667
is_active_column,
6768
rx.cond(
@@ -85,9 +86,7 @@ def sort_icon(column_key: SortColumn) -> rx.Component:
8586
)
8687

8788

88-
def sortable_table_header(
89-
col_name: str, column_key: SortColumn
90-
) -> rx.Component:
89+
def sortable_table_header(col_name: str, column_key: SortColumn) -> rx.Component:
9190
"""Renders a sortable table header cell."""
9291
base_class = "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider group"
9392
sortable_class = f"{base_class} cursor-pointer"
@@ -124,7 +123,9 @@ def non_sortable_table_header(
124123
col_name: str,
125124
) -> rx.Component:
126125
"""Renders a non-sortable table header cell."""
127-
base_class = "px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
126+
base_class = (
127+
"px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
128+
)
128129
text_align_class = rx.match(
129130
col_name,
130131
("Revenue", "text-right"),
@@ -159,17 +160,13 @@ def table_header(
159160
col_name = col_data[0]
160161
column_key = col_data[1]
161162
return rx.cond(
162-
column_key != None,
163-
sortable_table_header(
164-
col_name, column_key.to(SortColumn)
165-
),
163+
column_key is not None,
164+
sortable_table_header(col_name, column_key.to(SortColumn)),
166165
non_sortable_table_header(col_name),
167166
)
168167

169168

170-
def get_cell_content(
171-
col_name: rx.Var[str], customer: CustomerData
172-
) -> rx.Component:
169+
def get_cell_content(col_name: rx.Var[str], customer: CustomerData) -> rx.Component:
173170
"""Gets the appropriate component for a specific cell based on column name."""
174171
base_class = "px-4 py-3 whitespace-nowrap text-sm"
175172
return rx.match(
@@ -224,9 +221,7 @@ def get_cell_content(
224221
"+",
225222
"",
226223
)
227-
+ customer[
228-
"active_license_growth"
229-
].to_string()
224+
+ customer["active_license_growth"].to_string()
230225
+ "%",
231226
class_name=rx.cond(
232227
customer["active_license_growth"] > 0,
@@ -261,16 +256,11 @@ def table_row(customer: CustomerData) -> rx.Component:
261256
return rx.el.tr(
262257
rx.foreach(
263258
DashboardState.column_data,
264-
lambda col_data: get_cell_content(
265-
col_data[0], customer
266-
),
267-
),
268-
on_click=lambda: DashboardState.select_customer(
269-
customer["id"]
259+
lambda col_data: get_cell_content(col_data[0], customer),
270260
),
261+
on_click=lambda: DashboardState.select_customer(customer["id"]),
271262
class_name=rx.cond(
272-
DashboardState.selected_customer_id
273-
== customer["id"],
263+
DashboardState.selected_customer_id == customer["id"],
274264
"bg-emerald-50 border-l-4 border-emerald-500 cursor-pointer hover:bg-emerald-100 transition-colors duration-150 ease-in-out",
275265
"border-b border-gray-200 cursor-pointer hover:bg-gray-50 transition-colors duration-150 ease-in-out",
276266
),
@@ -290,9 +280,7 @@ def data_table() -> rx.Component:
290280
rx.el.input(
291281
placeholder="Search by customer name...",
292282
default_value=DashboardState.search_term,
293-
on_change=DashboardState.set_search_term.debounce(
294-
300
295-
),
283+
on_change=DashboardState.set_search_term.debounce(300),
296284
class_name="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:border-transparent text-sm text-gray-800 placeholder-gray-500",
297285
),
298286
class_name="relative flex-grow",
@@ -334,11 +322,10 @@ def data_table() -> rx.Component:
334322
),
335323
rx.el.div(
336324
rx.el.p(
337-
DashboardState.result_count.to_string()
338-
+ " results",
325+
DashboardState.result_count.to_string() + " results",
339326
class_name="text-sm text-gray-500 mt-4",
340327
),
341328
class_name="flex justify-end",
342329
),
343330
class_name="bg-white p-6 rounded-lg shadow-md",
344-
)
331+
)

admin_dashboard/admin_dashboard/components/navigation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import reflex as rx
2+
23
from admin_dashboard.states.navigation_state import NavigationState
34

45

@@ -24,9 +25,7 @@ def navigation() -> rx.Component:
2425
class_name="h-8 w-auto mr-4",
2526
alt="App Logo",
2627
),
27-
navigation_item(
28-
"Sales Pipeline", "/sales-pipeline"
29-
),
28+
navigation_item("Sales Pipeline", "/sales-pipeline"),
3029
navigation_item("Customer Admin Panel", "/"),
3130
navigation_item("HR Portal", "/hr-portal"),
3231
navigation_item(
@@ -36,4 +35,4 @@ def navigation() -> rx.Component:
3635
class_name="flex items-center space-x-2",
3736
),
3837
class_name="bg-emerald-800 px-6 py-2 shadow-md sticky top-0 left-0 w-full z-50 h-[56px]",
39-
)
38+
)

admin_dashboard/admin_dashboard/models/__init__.py

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from datetime import datetime
2+
from typing import (
3+
Dict,
4+
List,
5+
Optional,
6+
TypedDict,
7+
Union,
8+
)
9+
10+
11+
class CustomerData(TypedDict):
12+
id: int
13+
customer_name: str
14+
next_renewal: str
15+
revenue: float
16+
licenses: int
17+
active_licenses: int
18+
active_license_growth: int
19+
license_growth: int
20+
industry: str
21+
platform: str
22+
usage_history: List[Dict[str, Union[str, int]]]
23+
next_renewal_date: Optional[datetime]

0 commit comments

Comments
 (0)