| | from fasthtml.common import * |
| |
|
| | |
| | app,rt = fast_app(pico=True) |
| |
|
| | |
| | |
| | scores = { |
| | |
| | 'A_goals': 0, |
| | 'A_points': 0, |
| | |
| | 'B_goals': 0, |
| | 'B_points': 0, |
| | } |
| |
|
| | |
| | scores_ts = {} |
| | scores_id = len(scores_ts)+1 |
| | scores_ts[scores_id] = {"scores": scores.copy()} |
| |
|
| | |
| | team_A = "Bishopstown" |
| | team_B = "Other Team" |
| |
|
| | def create_score_button(team_code, score_type): |
| | |
| | span_id = f"{team_code}_{score_type}" |
| | |
| | counter_name = f"{team_code}_{score_type}" |
| |
|
| | return Button( |
| | Span(f"{scores[counter_name]}", id=span_id), |
| | hx_post="/increment", |
| | hx_target=f"#{span_id}", |
| | hx_vals=f'{{"counter": "{counter_name}"}}', |
| | hx_swap="innerHTML" |
| | ) |
| |
|
| | def create_score_section(team_code): |
| | return ( |
| | H1(create_score_button(f"{team_code}", "goals"), |
| | Span(" "), |
| | create_score_button(f"{team_code}", "points"), |
| | cls="card-title"), |
| | ) |
| |
|
| | verbose = False |
| |
|
| | @app.post("/increment") |
| | def increment(counter: str): |
| | if verbose: print("incrementing") |
| | global scores |
| | if counter in scores: |
| | scores[counter] += 1 |
| | |
| | global scores_ts |
| | scores_id = len(scores_ts) |
| | scores_ts[scores_id+1] = {"scores": scores.copy()} |
| | |
| | return f"{scores[counter]}" |
| |
|
| | @app.post("/reset") |
| | def reset_scores_and_page(): |
| | if verbose: print("reseting") |
| | global scores |
| | scores = { |
| | |
| | 'A_goals': 0, |
| | 'A_points': 0, |
| | |
| | 'B_goals': 0, |
| | 'B_points': 0, |
| | } |
| | global scores_ts |
| | scores_ts = {} |
| | scores_id = len(scores_ts)+1 |
| | scores_ts[scores_id] = {"scores": scores.copy()} |
| | |
| | |
| | return set_table(team_A, team_B) |
| |
|
| | |
| | @app.post("/reset_recent") |
| | def reset_to_last_score_and_page(): |
| | if verbose: print("reseting to recent") |
| | global scores |
| | global scores_ts |
| | |
| | scores_id = len(scores_ts) |
| | if scores_id > 1: |
| | scores = scores_ts[scores_id-1]["scores"] |
| | |
| | |
| | scores_ts.pop(scores_id) |
| | |
| | |
| | return set_table(team_A, team_B) |
| |
|
| | @rt |
| | def index(): |
| | return Titled('GAA Score Keeper', |
| | Div( |
| | P('Enter the team names'), |
| | Form(Input(name='team_name_A', value=team_A), |
| | Input(name='team_name_B', value=team_B), |
| | Button('Click'), |
| | hx_post='/set_table', hx_target='#main'), |
| | id='main')) |
| |
|
| | @rt |
| | def set_table(team_name_A:str, team_name_B:str): |
| | global team_A |
| | global team_B |
| | team_A = team_name_A |
| | team_B = team_name_B |
| | print("set_table called"+team_A+team_B) |
| | return Main( |
| | Div( |
| | Table( |
| | Tr( |
| | Th(H2(team_A)), |
| | Th(H2(team_B)) |
| | ), |
| | Tr( |
| | Td(create_score_section(team_code = "A"),style="text-align: center;"), |
| | Td(create_score_section(team_code = "B"),style="text-align: center;") |
| | ) |
| | ), |
| | Br(), |
| | Br(), |
| | Div( |
| | id="timer_display", hx_get="/timer", |
| | hx_trigger="every 1s", |
| | style="text-align: center; margin-top: 20px; cursor: pointer;" |
| | ), |
| | style="flex-grow: 1;" |
| | ), |
| | Div( |
| | Button( Span("Undo"), hx_post="/reset_recent", hx_target='#main' ), |
| | Button( Span("Toggle Clock"), hx_post="/timer_toggle", hx_target='#timer_display' ), |
| | Button( Span("Full Reset"), hx_post="/reset", hx_target='#main' ), |
| | style = "display: flex; justify-content: space-between;" |
| | ), |
| | style="display: flex; flex-direction: column; min-height: 80vh;" |
| | ) |
| | |
| | |
| | timer_state = { |
| | 'start_time': None, |
| | 'is_running': False |
| | } |
| |
|
| | @app.get("/timer") |
| | def get_timer(): |
| | import time |
| | if timer_state['is_running'] and timer_state['start_time']: |
| | elapsed = time.time() - timer_state['start_time'] |
| | minutes = int(elapsed // 60) |
| | seconds = int(elapsed % 60) |
| | color = "red" if minutes >= 30 else "green" |
| | return Span(f"{minutes:02d}:{seconds:02d}", style=f"color: {color}; font-size: 2em;") |
| | return Span("00:00", style="color: green; font-size: 2em;") |
| |
|
| | @app.post("/timer_toggle") |
| | def toggle_timer(): |
| | import time |
| | if timer_state['is_running']: |
| | timer_state['is_running'] = False |
| | else: |
| | timer_state['start_time'] = time.time() |
| | timer_state['is_running'] = True |
| | return get_timer() |
| | |
| | serve(port=7860) |