Upload current progress

This commit is contained in:
2026-01-03 10:23:05 -06:00
commit ec57d94cc0
66 changed files with 4031 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
import reflex as rx
from ..state.app_state import AppState
from ..components.layout import dashboard_layout
from ..components.terminal import terminal_window
def dashboard_page():
return dashboard_layout(
rx.vstack(
rx.hstack(
rx.heading("Dashboard", size="8"),
rx.spacer(),
rx.button(
rx.hstack(rx.icon("download"), rx.text("Sync from CouchDB")),
on_click=AppState.run_couch_sync,
loading=AppState.is_running,
variant="soft",
color_scheme="orange",
size="3",
margin_right="2",
disabled=AppState.is_running
),
rx.select(
AppState.available_subfolders,
value=AppState.selected_subfolder,
on_change=AppState.set_selected_subfolder,
placeholder="Select Target Folder",
size="3",
margin_right="2",
width="200px"
),
rx.icon_button(
rx.icon("refresh-cw"),
on_click=AppState.refresh_subfolders,
variant="soft",
size="3",
margin_right="2"
),
rx.button(
rx.hstack(rx.icon("play"), rx.text("Run Agent Now")),
on_click=AppState.run_agent_process,
loading=AppState.is_running,
size="3",
disabled=AppState.is_running
),
width="100%",
align_items="center",
margin_bottom="6"
),
rx.grid(
rx.card(
rx.vstack(
rx.text("Scheduler", size="2", color="gray.11", weight="bold"),
rx.text("Active", size="6", weight="bold"),
rx.text("Daily @ 02:00", size="1", color="gray.10"),
spacing="1"
)
),
rx.card(
rx.vstack(
rx.text("Model", size="2", color="gray.11", weight="bold"),
rx.text("Gemini Flash", size="6", weight="bold"),
rx.text("v3 Preview", size="1", color="gray.10"),
spacing="1"
)
),
columns="2",
spacing="4",
width="100%"
),
rx.box(
terminal_window(AppState.logs, title="Agent Activity Log"),
width="100%",
box_shadow="0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"
),
spacing="6",
width="100%"
)
)
def settings_page():
return dashboard_layout(
rx.vstack(
rx.heading("Settings", size="8", margin_bottom="6"),
rx.tabs.root(
rx.tabs.list(
rx.tabs.trigger("General", value="general"),
rx.tabs.trigger("CouchDB Sync", value="couchdb"),
),
rx.tabs.content(
rx.card(
rx.vstack(
rx.text("Gemini API Key", weight="bold"),
rx.input(value=AppState.api_key, on_change=AppState.set_api_key, type="password", width="100%"),
rx.text("Input Folder Path", weight="bold"),
rx.input(value=AppState.input_folder, on_change=AppState.set_input_folder, width="100%"),
rx.text("Rewrite Tag", weight="bold"),
rx.input(value=AppState.rewrite_tag, on_change=AppState.set_rewrite_tag, width="100%"),
rx.text("Vault Philosophy", weight="bold"),
rx.text_area(value=AppState.philosophy, on_change=AppState.set_philosophy, height="200px", width="100%"),
rx.button("Save Changes", on_click=AppState.save_config, size="3", margin_top="4"),
spacing="4",
align_items="start",
padding="6"
),
width="100%",
max_width="800px",
margin_top="4"
),
value="general"
),
rx.tabs.content(
rx.card(
rx.vstack(
rx.heading("CouchDB Configuration", size="4"),
rx.text("Connect to your Obsidian LiveSync database to download notes.", color="gray.11", size="2"),
rx.text("Database URL", weight="bold", margin_top="2"),
rx.input(placeholder="http://localhost:5984", value=AppState.couch_url, on_change=AppState.set_couch_url, width="100%"),
rx.text("Database Name", weight="bold"),
rx.input(placeholder="obsidian_livesync", value=AppState.couch_db, on_change=AppState.set_couch_db, width="100%"),
rx.text("Username (Optional)", weight="bold"),
rx.input(value=AppState.couch_user, on_change=AppState.set_couch_user, width="100%"),
rx.text("Password (Optional)", weight="bold"),
rx.input(type="password", value=AppState.couch_pass, on_change=AppState.set_couch_pass, width="100%"),
rx.text("Decryption Passphrase (Experimental)", weight="bold"),
rx.input(type="password", value=AppState.couch_passphrase, on_change=AppState.set_couch_passphrase, width="100%"),
rx.button("Save Changes", on_click=AppState.save_config, size="3", margin_top="4"),
spacing="4",
align_items="start",
padding="6"
),
width="100%",
max_width="800px",
margin_top="4"
),
value="couchdb"
),
defaultValue="general",
width="100%"
),
width="100%"
)
)

View File

@@ -0,0 +1,26 @@
import reflex as rx
from ..state.auth import AuthState
def login_page():
return rx.center(
rx.card(
rx.vstack(
rx.heading("Login", size="7", margin_bottom="4"),
rx.text("Username", size="2", weight="bold"),
rx.input(value=AuthState.username, on_change=AuthState.set_username, width="100%"),
rx.text("Password", size="2", weight="bold"),
rx.input(type="password", value=AuthState.password, on_change=AuthState.set_password, width="100%"),
rx.button("Sign In", size="3", width="100%", on_click=AuthState.check_login, margin_top="4"),
padding="6",
spacing="3",
align_items="start"
),
width="400px",
),
height="100vh",
bg="var(--gray-1)"
)

View File

@@ -0,0 +1,44 @@
import reflex as rx
from ..state.auth import AuthState
def setup_step(title: str, children: list):
return rx.vstack(
rx.heading(title, size="6", margin_bottom="4"),
*children,
width="100%",
max_width="500px",
spacing="4",
align_items="start"
)
def setup_page():
return rx.center(
rx.card(
rx.vstack(
rx.heading("Welcome to Obsidian Automator", size="8", color="var(--accent-9)"),
rx.text("Let's secure your agent and configure your vault.", color="gray.11", margin_bottom="6"),
rx.separator(margin_bottom="6"),
rx.text("Create Admin Account", weight="bold"),
rx.input(placeholder="Username", value=AuthState.username, on_change=AuthState.set_username, width="100%"),
rx.input(placeholder="Password", type="password", value=AuthState.password, on_change=AuthState.set_password, width="100%"),
rx.input(placeholder="Confirm Password", type="password", value=AuthState.confirm_password, on_change=AuthState.set_confirm_password, width="100%"),
rx.separator(margin_y="4"),
rx.text("Agent Configuration", weight="bold"),
rx.input(placeholder="Gemini API Key", value=AuthState.setup_api_key, on_change=AuthState.set_setup_api_key, width="100%", type="password"),
rx.input(placeholder="Vault Input Path", value=AuthState.setup_input_folder, on_change=AuthState.set_setup_input_folder, width="100%"),
rx.text_area(placeholder="Vault Philosophy (e.g. Zettelkasten rules)", value=AuthState.setup_philosophy, on_change=AuthState.set_setup_philosophy, width="100%", height="100px"),
rx.button("Complete Setup", size="4", width="100%", on_click=AuthState.create_admin_account, margin_top="4"),
padding="8",
),
size="4",
width="600px"
),
height="100vh",
bg="var(--gray-2)"
)