diff --git a/main.py b/main.py index 988f53b..7af4f60 100644 --- a/main.py +++ b/main.py @@ -45,6 +45,14 @@ async def index(): async def graphs(): with open("templates/graphs.html", "r", encoding="utf-8") as f: return HTMLResponse(f.read()) + +# ----------------------- +# PAGE 3: /portgraphs +# ----------------------- +@app.get("/port") +async def port(): + with open("templates/portfoliograph.html", "r", encoding="utf-8") as f: + return HTMLResponse(f.read()) # ----------------------- @@ -67,7 +75,7 @@ async def api_data(): # ----------------------- # API 2 (used by /graphs) # ----------------------- -from fastapi import Depends, Query + @app.get("/api/graphs") async def api_graphs( @@ -103,6 +111,39 @@ async def api_graphs( return results +@app.get("/api/portfolio") +async def api_folio( + ticker: str = Query(...), + uuid: int = Query(0), +): + tickers = [t.strip().upper() for t in ticker.split(",") if t.strip()] + + with engine.connect() as conn: + results = {} + + for t in tickers: + query = text(""" + SELECT + p.*, + s.CurPrice, + (s.CurPrice * p.SharesOwned) AS CurrentValue + FROM STOCKMARKET_PORTFOLIO p + JOIN STOCKMARKET_STOCKS s + ON s.Ticker = p.Ticker + WHERE p.Ticker = :ticker + AND p.UUID = :uuid; + """) + + result = conn.execute(query, { + "ticker": t, + "uuid": uuid + }) + + rows = [dict(r._mapping) for r in result] + results[t] = rows + + return results + # ----------------------- # RUN # ----------------------- diff --git a/static/style.css b/static/style.css index 060296f..75c5258 100644 --- a/static/style.css +++ b/static/style.css @@ -1,14 +1,74 @@ +/* ========================= + BASE / GLOBAL +========================= */ + html, body { height: 100%; margin: 0; padding: 0; - background: #ffffff; - color: #ffffff; + background: #0f1115; + color: #e6e6e6; font-family: Arial, sans-serif; - overflow: hidden; /* prevents page scroll messing with chart height */ + overflow: hidden; } -/* Header area */ +/* ========================= + LAYOUT SYSTEM +========================= */ + +.layout { + display: flex; + height: 100vh; +} + +.content { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.page { + flex: 1; + overflow: hidden; + padding: 20px; + display: flex; + flex-direction: column; +} + +/* ========================= + SIDEBAR +========================= */ + +.sidebar { + width: 220px; + background: #1a1d23; + padding: 15px; + border-right: 1px solid #2a2f3a; +} + +.nav-item { + padding: 10px; + border-radius: 6px; + cursor: pointer; + margin-bottom: 6px; + color: #b5b5b5; +} + +.nav-item:hover { + background: #2a2f3a; + color: #fff; +} + +.nav-item.active { + background: #3a3f4b; + color: white; +} + +/* ========================= + TYPOGRAPHY +========================= */ + h2 { margin: 10px 15px 5px 15px; } @@ -24,18 +84,226 @@ a:hover { text-decoration: underline; } -/* FULL SCREEN CHART CONTAINER */ +.section-title { + font-size: 18px; + margin-bottom: 15px; +} + +/* ========================= + CHART (IMPORTANT) +========================= */ + .chart-container { width: 100%; - height: calc(100vh - 80px); /* subtract header space */ + flex: 1; display: flex; padding: 10px 15px; box-sizing: border-box; } -/* CRITICAL: canvas must stretch */ #chart { width: 100% !important; height: 100% !important; display: block; +} + +/* ========================= + EDITOR PANEL +========================= */ + +.editor { + width: 420px; + background: #1a1d23; + border: 1px solid #2a2f3a; + border-radius: 10px; + padding: 20px; +} + +.center-wrap { + display: flex; + height: 100%; + justify-content: center; + align-items: flex-start; +} + +/* ========================= + FORMS +========================= */ + +.form-block { + display: flex; + flex-direction: column; + padding: 10px; + border: 1px solid #2a2f3a; + border-radius: 8px; + background: #151922; + margin-bottom: 10px; +} + +.form-label { + font-size: 12px; + color: #9aa4b2; + margin-bottom: 5px; +} + +input, select { + width: 100%; + box-sizing: border-box; + padding: 8px; + background: #0f1115; + border: 1px solid #2a2f3a; + border-radius: 6px; + color: white; +} + +/* ========================= + BUTTONS +========================= */ + +button { + padding: 8px 12px; + border: none; + border-radius: 6px; + cursor: pointer; + background: #5865f2; + color: white; +} + +button:hover { + background: #4752c4; +} + +.small-btn { + background: #3a3f4b; + margin-left: 10px; +} + +/* ========================= + ADMIN PANEL +========================= */ + +.admin-container { + display: flex; + height: 100%; + gap: 15px; +} + +.admin-left { + width: 320px; + display: flex; + flex-direction: column; + background: #1a1d23; + border: 1px solid #2a2f3a; + border-radius: 10px; + padding: 10px; +} + +.admin-right { + flex: 1; + display: flex; + justify-content: center; + align-items: flex-start; +} + +/* ========================= + SEARCH / USERS +========================= */ + +.search-box { + width: 100%; + box-sizing: border-box; + padding: 8px; + margin-bottom: 10px; + background: #0f1115; + border: 1px solid #2a2f3a; + border-radius: 6px; + color: white; +} + +.user-list { + flex: 1; + overflow-y: auto; +} + +.user-card { + padding: 10px; + border-radius: 6px; + border: 1px solid #2a2f3a; + margin-bottom: 8px; + cursor: pointer; +} + +.user-card:hover { + background: #2a2f3a; +} + +.user-card.active { + background: #3a3f4b; +} + +/* ========================= + INFO BLOCKS +========================= */ + +.info-block { + display: flex; + justify-content: space-between; + padding: 10px; + border: 1px solid #2a2f3a; + border-radius: 8px; + background: #151922; + margin-bottom: 10px; +} + +.info-label { + color: #9aa4b2; +} + +/* ========================= + TOASTS +========================= */ + +.toast { + position: fixed; + bottom: 20px; + right: 20px; + padding: 10px 14px; + border-radius: 8px; + font-size: 13px; + color: white; + background: #2a2f3a; + border: 1px solid #3a3f4b; + opacity: 0; + transform: translateY(10px); + transition: all 0.25s ease; + pointer-events: none; + z-index: 9999; +} + +.toast.show { + opacity: 1; + transform: translateY(0); +} + +.toast.success { + background: #1f3b2c; + border-color: #2f6b4f; +} + +.toast.error { + background: #3b1f1f; + border-color: #6b2f2f; +} + +/* ========================= + HEADERS +========================= */ + +.edit-header { + font-size: 16px; + margin-bottom: 15px; +} + +.edit-header span { + text-decoration: underline; } \ No newline at end of file diff --git a/templates/graphs.html b/templates/graphs.html index 0e52b1b..221b507 100644 --- a/templates/graphs.html +++ b/templates/graphs.html @@ -8,11 +8,30 @@ -

Graphs

-Back +
-
- + + + + +
+ +
+ +

Graphs

+ Back + +
+ +
+ +
+ +
+ + + \ No newline at end of file