Skip to content

Commit 10c2e13

Browse files
committed
marketing dashboard from flexgen
1 parent a74e268 commit 10c2e13

File tree

17 files changed

+609
-0
lines changed

17 files changed

+609
-0
lines changed

.github/workflows/deploy.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535
ai_image_gen)
3636
echo "EXTRA_ARGS=--env REPLICATE_API_TOKEN=${{ secrets.REPLICATE_API_TOKEN }}" >> $GITHUB_ENV
3737
;;
38+
marketing_dashboard)
39+
echo "EXTRA_ARGS=" >> $GITHUB_ENV
40+
;;
3841
customer_data_app)
3942
cat .deploy/temporary_db.py >> ${{ matrix.folder }}/customer_data/customer_data.py
4043
echo "EXTRA_ARGS=--vmtype ${{ vars.CUSTOMER_DATA_VM_TYPE }}" >> $GITHUB_ENV

marketing_dashboard/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.py[cod]
2+
*.db
3+
assets/external/
4+
.states
5+
__pycache__/
6+
.web
7+
.DS_Store
8+
.idea/
4.19 KB
Binary file not shown.

marketing_dashboard/marketing_dashboard/__init__.py

Whitespace-only changes.

marketing_dashboard/marketing_dashboard/components/__init__.py

Whitespace-only changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import reflex as rx
2+
from typing import List, Dict, Union
3+
4+
5+
def data_list_card(
6+
title: str,
7+
data: rx.Var[List[Dict[str, Union[str, int]]]],
8+
value_key: str = "value",
9+
) -> rx.Component:
10+
"""A card component to display data in a simple list format."""
11+
return rx.el.div(
12+
rx.el.p(
13+
title,
14+
class_name="text-sm font-medium text-gray-400 uppercase tracking-wider mb-4",
15+
),
16+
rx.el.div(
17+
rx.foreach(
18+
data,
19+
lambda item: rx.el.div(
20+
rx.el.span(
21+
item["medium"],
22+
class_name="text-gray-300",
23+
),
24+
rx.el.span(
25+
item[value_key],
26+
class_name="text-white font-medium",
27+
),
28+
class_name="flex justify-between items-center py-2 border-b border-gray-700 last:border-b-0",
29+
),
30+
),
31+
class_name="space-y-1 text-sm",
32+
),
33+
class_name="bg-indigo-900 p-4 sm:p-6 rounded-lg shadow-lg h-full",
34+
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import reflex as rx
2+
from marketing_dashboard.states.marketing_dashboard_state import (
3+
MarketingDashboardState,
4+
)
5+
6+
7+
def footer() -> rx.Component:
8+
"""The footer component for the dashboard."""
9+
return rx.el.footer(
10+
rx.el.div(
11+
rx.el.div(
12+
rx.el.span(
13+
"✓",
14+
class_name="text-green-400 font-bold text-lg transform rotate-12",
15+
),
16+
class_name="bg-green-900 rounded-sm p-1 mr-2 flex items-center justify-center w-6 h-6",
17+
),
18+
rx.el.span(
19+
"Digital dashboard: Marketing",
20+
class_name="text-gray-300 font-medium",
21+
),
22+
class_name="flex items-center text-sm max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",
23+
),
24+
class_name="w-full py-4 bg-indigo-950 border-t border-gray-700 mt-8",
25+
)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import reflex as rx
2+
from typing import Union
3+
4+
5+
def kpi_card(
6+
title: str,
7+
value: Union[str, int, rx.Var],
8+
description: str,
9+
class_name: str = "",
10+
) -> rx.Component:
11+
"""A card component to display a key performance indicator."""
12+
return rx.el.div(
13+
rx.el.p(
14+
title,
15+
class_name="text-sm font-medium text-gray-400 uppercase tracking-wider",
16+
),
17+
rx.el.p(
18+
value,
19+
class_name="text-4xl sm:text-5xl font-bold text-white mt-2",
20+
),
21+
rx.el.p(
22+
description,
23+
class_name="text-base text-gray-300 mt-1",
24+
),
25+
class_name=f"bg-indigo-900 p-4 sm:p-6 rounded-lg shadow-lg {class_name}",
26+
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import reflex as rx
2+
from typing import Union
3+
4+
5+
def kpi_only_card(
6+
primary_value: Union[int, str, rx.Var],
7+
primary_desc: str,
8+
secondary_value: Union[str, rx.Var],
9+
secondary_desc: str,
10+
show_warning: bool = False,
11+
) -> rx.Component:
12+
"""A card specifically for the bottom right two KPIs."""
13+
return rx.el.div(
14+
rx.el.div(
15+
rx.el.p(
16+
primary_value,
17+
class_name="text-4xl sm:text-5xl font-bold text-white",
18+
),
19+
rx.el.p(
20+
primary_desc,
21+
class_name="text-sm text-gray-300 mt-1",
22+
),
23+
class_name="mb-6",
24+
),
25+
rx.el.div(
26+
rx.el.div(
27+
rx.el.p(
28+
secondary_value,
29+
class_name="text-4xl sm:text-5xl font-bold text-white",
30+
),
31+
rx.el.p(
32+
secondary_desc,
33+
class_name="text-sm text-gray-300 mt-1",
34+
),
35+
rx.cond(
36+
show_warning,
37+
rx.el.div(
38+
rx.el.span(
39+
"!",
40+
class_name="text-white font-bold text-xs",
41+
),
42+
class_name="absolute -top-2 -right-2 bg-red-500 rounded-full w-5 h-5 flex items-center justify-center",
43+
),
44+
),
45+
class_name=rx.cond(
46+
show_warning,
47+
"relative border border-red-500 rounded-md p-3 inline-block",
48+
"relative inline-block",
49+
),
50+
)
51+
),
52+
class_name="bg-indigo-900 p-4 sm:p-6 rounded-lg shadow-lg h-full flex flex-col justify-center",
53+
)
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import reflex as rx
2+
from typing import Union, List, Dict
3+
from marketing_dashboard.states.marketing_dashboard_state import (
4+
TOOLTIP_PROPS,
5+
MarketingDashboardState,
6+
)
7+
8+
9+
def kpi_section(
10+
title: str,
11+
value: Union[str, int, rx.Var],
12+
description: str,
13+
) -> rx.Component:
14+
"""Simplified KPI section for the top part of the chart card."""
15+
return rx.el.div(
16+
rx.el.p(
17+
title,
18+
class_name="text-sm font-medium text-gray-400 uppercase tracking-wider",
19+
),
20+
rx.el.p(
21+
value,
22+
class_name="text-4xl sm:text-5xl font-bold text-white mt-2",
23+
),
24+
rx.el.p(
25+
description,
26+
class_name="text-base text-gray-300 mt-1",
27+
),
28+
)
29+
30+
31+
def line_chart_card(
32+
title: str,
33+
data: rx.Var[List[Dict[str, Union[str, int]]]],
34+
y_max: int,
35+
kpi_value: Union[str, int, rx.Var],
36+
kpi_desc: str,
37+
) -> rx.Component:
38+
"""A card containing a line chart and related KPI."""
39+
return rx.el.div(
40+
kpi_section(title, kpi_value, kpi_desc),
41+
rx.el.div(
42+
rx.recharts.line_chart(
43+
rx.recharts.cartesian_grid(
44+
horizontal=True,
45+
vertical=False,
46+
class_name="stroke-gray-700 opacity-50",
47+
),
48+
rx.recharts.graphing_tooltip(**TOOLTIP_PROPS),
49+
rx.recharts.line(
50+
data_key="past_28_days",
51+
stroke="#00BFFF",
52+
dot=False,
53+
type_="monotone",
54+
stroke_width=2,
55+
connect_nulls=True,
56+
),
57+
rx.recharts.line(
58+
data_key="prev_28_days",
59+
stroke="#FFD700",
60+
dot=False,
61+
type_="monotone",
62+
stroke_width=2,
63+
connect_nulls=True,
64+
),
65+
rx.recharts.y_axis(
66+
domain=[0, y_max],
67+
axis_line=False,
68+
tick_line=False,
69+
tick_size=10,
70+
tick_formatter="(value) => value.toLocaleString()",
71+
custom_attrs={
72+
"fontSize": "12px",
73+
"stroke": "#A0AEC0",
74+
},
75+
width=40,
76+
),
77+
rx.recharts.x_axis(
78+
data_key="date",
79+
axis_line=False,
80+
tick_line=False,
81+
tick_size=10,
82+
custom_attrs={
83+
"fontSize": "12px",
84+
"stroke": "#A0AEC0",
85+
},
86+
interval=6,
87+
padding={"left": 10, "right": 10},
88+
),
89+
rx.recharts.legend(
90+
payload=[
91+
{
92+
"value": "past 28 days",
93+
"type": "circle",
94+
"id": "past_28_days",
95+
"color": "#00BFFF",
96+
},
97+
{
98+
"value": "prev 28 days",
99+
"type": "circle",
100+
"id": "prev_28_days",
101+
"color": "#FFD700",
102+
},
103+
],
104+
icon_size=8,
105+
wrapper_style={
106+
"paddingTop": "20px",
107+
"color": "#A0AEC0",
108+
"fontSize": "12px",
109+
},
110+
align="right",
111+
vertical_align="top",
112+
),
113+
data=data,
114+
height=200,
115+
margin={
116+
"top": 5,
117+
"right": 10,
118+
"left": -25,
119+
"bottom": 5,
120+
},
121+
),
122+
class_name="mt-4",
123+
),
124+
class_name="bg-indigo-900 p-4 sm:p-6 rounded-lg shadow-lg",
125+
)

0 commit comments

Comments
 (0)