1111from pcweb .constants import REFLEX_CLOUD_URL , PRO_TIERS_TABLE
1212
1313
14- def format_number (number : int ) -> str :
15- return rx .Var (f"({ number } ).toLocaleString('en-US')" ).to (str )
14+ def format_number (number : int | float ) -> str :
15+ """Format number with locale string, handling non-numeric values"""
16+ return rx .Var (
17+ f"(typeof { number } === 'number' ? { number } : 0).toLocaleString('en-US')"
18+ ).to (str )
1619
1720
1821@dataclass
1922class Machine :
2023 vcpu : int
2124 ram : float
2225 index : int
26+ weekly_credits : float = 0.0
2327
2428 @classmethod
2529 def from_index (cls , index : int ) -> "Machine" :
2630 """Create Machine from COMPUTE_TABLE index"""
2731 machine_key = machine_keys [index ]
2832 specs = COMPUTE_TABLE [machine_key ]
29- return cls (vcpu = specs ["vcpu" ], ram = specs ["ram" ], index = index )
33+ weekly_credits = calculate_weekly_credits (specs ["vcpu" ], specs ["ram" ])
34+ return cls (
35+ vcpu = specs ["vcpu" ],
36+ ram = specs ["ram" ],
37+ index = index ,
38+ weekly_credits = weekly_credits ,
39+ )
3040
3141
3242def calculate_weekly_credits (vcpu : int , ram : float ) -> float :
@@ -58,36 +68,92 @@ class MachineState(rx.State):
5868 machines : rx .Field [list [Machine ]] = rx .field (default_factory = list )
5969 messages_tier_index : rx .Field [int ] = rx .field (default = 0 )
6070
71+ machines_weekly_credits : rx .Field [float ] = rx .field (default = 0.0 )
72+ current_tier : rx .Field [dict ] = rx .field (
73+ default_factory = lambda : {"key" : "Pro" , "credits" : 0 , "price" : 0 }
74+ )
75+ total_credits : rx .Field [str ] = rx .field (default = "0" )
76+ recommended_tier_info : rx .Field [dict ] = rx .field (
77+ default_factory = lambda : {
78+ "price" : "$0/mo" ,
79+ "needs_enterprise" : False ,
80+ "name" : "Pro Plan" ,
81+ "credits" : 0 ,
82+ }
83+ )
84+
85+ def _recalculate_all (self ):
86+ """Recalculate all derived values when state changes"""
87+ # Calculate machines weekly credits using cached values
88+ self .machines_weekly_credits = sum (
89+ machine .weekly_credits for machine in self .machines
90+ )
91+
92+ # Calculate current tier based on message credits
93+ msg_credits = get_message_credits (self .messages_tier_index )
94+ is_enterprise = get_is_enterprise_tier (self .messages_tier_index )
95+
96+ if is_enterprise :
97+ self .current_tier = {
98+ "key" : "Enterprise" ,
99+ "credits" : msg_credits ,
100+ "price" : "custom" ,
101+ }
102+ else :
103+ tier = self ._find_tier_for_credits (msg_credits )
104+ self .current_tier = {
105+ "key" : tier ["key" ] if tier else "Enterprise" ,
106+ "credits" : msg_credits ,
107+ "price" : tier ["price" ] if tier else "custom" ,
108+ }
109+
110+ # Calculate total credits and find tier once
111+ total = msg_credits + round (self .machines_weekly_credits , 2 )
112+ total_tier = None if is_enterprise else self ._find_tier_for_credits (total )
113+
114+ # Set total credits display
115+ if is_enterprise or not total_tier :
116+ self .total_credits = "Custom"
117+ else :
118+ self .total_credits = f"{ total :,} "
119+
120+ # Set recommended tier info
121+ if total_tier :
122+ self .recommended_tier_info = {
123+ "price" : f"${ total_tier ['price' ]} /mo" ,
124+ "needs_enterprise" : False ,
125+ "name" : f"{ total_tier ['key' ]} Plan" ,
126+ "credits" : total_tier ["credits" ],
127+ }
128+ else :
129+ self .recommended_tier_info = {
130+ "price" : "Custom" ,
131+ "needs_enterprise" : True ,
132+ "name" : "Enterprise" ,
133+ "credits" : "Custom" ,
134+ }
135+
61136 @rx .event (temporal = True )
62137 def add_machine (self ):
63138 self .machines .append (Machine .from_index (0 ))
139+ self ._recalculate_all ()
64140
65141 @rx .event (temporal = True )
66142 def remove_machine (self , index : int ):
67143 self .machines = self .machines [:index ] + self .machines [index + 1 :]
144+ self ._recalculate_all ()
68145
69146 @rx .event (temporal = True )
70147 def update_machine (self , index : int , new_machine_index : int ):
71148 self .machines [index ] = Machine .from_index (new_machine_index )
149+ self ._recalculate_all ()
72150
73151 @rx .event (temporal = True )
74152 def update_messages_tier (self , new_tier_index : int ):
75153 if new_tier_index == self .messages_tier_index :
76154 return
77155 self .messages_tier_index = new_tier_index
78-
79- def _get_machines_credits (self ) -> float :
80- """Calculate total weekly credits of all machines"""
81- return sum (
82- calculate_weekly_credits (machine .vcpu , machine .ram )
83- for machine in self .machines
84- )
85-
86- def _get_total_credits (self ) -> float :
87- """Calculate total credits as numeric value"""
88- return get_message_credits (self .messages_tier_index ) + round (
89- self ._get_machines_credits (), 2
90- )
156+ self ._recalculate_all ()
91157
92158 def _find_tier_for_credits (self , credits : float ) -> dict | None :
93159 """Find Pro tier that fits the given credits, or None if Enterprise needed"""
@@ -97,63 +163,15 @@ def _find_tier_for_credits(self, credits: float) -> dict | None:
97163 return {"key" : tier_key , ** tier_data }
98164 return None
99165
100- @rx .var
101- def machines_weekly_credits (self ) -> float :
102- """For UI display of machine credits"""
103- return self ._get_machines_credits ()
104-
105- @rx .var
106- def current_tier (self ) -> dict :
107- """Current tier info based on message credits only"""
108- msg_credits = get_message_credits (self .messages_tier_index )
109-
110- if get_is_enterprise_tier (self .messages_tier_index ):
111- return {
112- "key" : "Enterprise" ,
113- "credits" : msg_credits ,
114- "price" : "custom" ,
115- }
116-
117- tier = self ._find_tier_for_credits (msg_credits )
118- return {
119- "key" : tier ["key" ] if tier else "Enterprise" ,
120- "credits" : msg_credits ,
121- "price" : tier ["price" ] if tier else "custom" ,
122- }
123-
124- @rx .var
125- def total_credits (self ) -> str :
126- """Total credits display string"""
127- total = self ._get_total_credits ()
128- if get_is_enterprise_tier (
129- self .messages_tier_index
130- ) or not self ._find_tier_for_credits (total ):
131- return "Custom"
132- return f"{ total :,} "
133-
134- @rx .var
135- def recommended_tier_info (self ) -> dict :
136- """Recommended tier based on total usage"""
137- tier = self ._find_tier_for_credits (self ._get_total_credits ())
138-
139- if tier :
140- return {
141- "price" : f"${ tier ['price' ]} /mo" ,
142- "needs_enterprise" : False ,
143- "name" : f"{ tier ['key' ]} Plan" ,
144- "credits" : tier ["credits" ],
145- }
146-
147- return {
148- "price" : "Custom" ,
149- "needs_enterprise" : True ,
150- "name" : "Enterprise" ,
151- "credits" : "Custom" ,
152- }
153-
154- @rx .event
166+ @rx .event (temporal = True )
155167 def reset_machines (self ):
156168 self .reset ()
169+ self ._recalculate_all ()
170+
171+ @rx .event (temporal = True )
172+ def on_load (self ):
173+ """Initialize calculated values on page load"""
174+ self ._recalculate_all ()
157175
158176
159177def total_credits_card () -> rx .Component :
@@ -196,9 +214,7 @@ def total_credits_card() -> rx.Component:
196214 class_name = "text-secondary-11 text-sm font-medium" ,
197215 ),
198216 rx .el .span (
199- format_number (
200- calculate_weekly_credits (machine .vcpu , machine .ram )
201- ),
217+ format_number (machine .weekly_credits ),
202218 class_name = "text-secondary-12 text-sm font-medium font-mono" ,
203219 ),
204220 class_name = "flex flex-row gap-2 items-center justify-between" ,
@@ -311,13 +327,7 @@ def messages_card() -> rx.Component:
311327 content = rx .cond (
312328 get_is_enterprise_tier (MachineState .messages_tier_index ),
313329 "Custom" ,
314- rx .cond (
315- get_is_enterprise_tier (
316- MachineState .messages_tier_index
317- ),
318- "Custom Messages" ,
319- f"{ format_number (MachineState .current_tier ['credits' ])} Messages" ,
320- ),
330+ f"{ format_number (MachineState .current_tier ['credits' ])} Messages" ,
321331 ),
322332 open = message_tooltip_open_cs .value ,
323333 side = "bottom" ,
@@ -375,7 +385,7 @@ def machine_card(machine: Machine, index: int) -> rx.Component:
375385 ),
376386 rx .el .div (
377387 rx .el .span (
378- f"{ calculate_weekly_credits ( machine .vcpu , machine . ram ) } " ,
388+ f"{ machine .weekly_credits } " ,
379389 class_name = "text-secondary-12 lg:text-lg text-base font-medium font-mono" ,
380390 ),
381391 rx .el .span (
@@ -451,6 +461,6 @@ def slider_calculator() -> rx.Component:
451461 total_credits_card (),
452462 class_name = "flex lg:flex-row flex-col lg:gap-10 gap-6 w-full px-6 h-full" ,
453463 ),
454- on_mount = MachineState .reset_machines ,
464+ on_mount = [ MachineState .reset_machines , MachineState . on_load ] ,
455465 class_name = "flex flex-col w-full max-w-[64.19rem] border-t-0 2xl:border-x divide-y divide-slate-4 2xl:border-b pt-[6rem] justify-center items-center" ,
456466 )
0 commit comments