Initial commit.

This commit is contained in:
2025-08-18 17:14:54 +02:00
commit 9d1623c739
19 changed files with 2129 additions and 0 deletions

27
app/__init__.py Normal file
View File

@@ -0,0 +1,27 @@
from flask import Flask
from .config import load_config
def create_app(config_override=None) -> Flask:
app = Flask(
__name__,
static_folder="static",
template_folder="templates",
)
cfg = config_override or load_config()
# Map to Flask app.config for easy access in templates/routes
app.config["KB_VAULT_PATH"] = cfg.VAULT_PATH
app.config["SECRET_KEY"] = cfg.SECRET_KEY
app.config["DEBUG"] = cfg.DEBUG
# Register blueprints
from .routes.home import bp as home_bp
app.register_blueprint(home_bp)
# Simple health endpoint
@app.get("/healthz")
def healthz():
return {"status": "ok", "vault": app.config.get("KB_VAULT_PATH")}, 200
return app

22
app/config.py Normal file
View File

@@ -0,0 +1,22 @@
import os
from dataclasses import dataclass
from dotenv import load_dotenv
@dataclass
class AppConfig:
DEBUG: bool
SECRET_KEY: str
VAULT_PATH: str | None
def load_config(vault_override: str | None = None) -> AppConfig:
# Load .env if present
load_dotenv()
debug = os.getenv("FLASK_DEBUG", "0") in ("1", "true", "True")
secret = os.getenv("SECRET_KEY", "dev-secret-change-me")
vault_env = os.getenv("KB_VAULT_PATH")
vault = vault_override or vault_env
return AppConfig(DEBUG=debug, SECRET_KEY=secret, VAULT_PATH=vault)

1
app/routes/__init__.py Normal file
View File

@@ -0,0 +1 @@
# Package marker for routes

10
app/routes/home.py Normal file
View File

@@ -0,0 +1,10 @@
from flask import Blueprint, current_app, render_template
bp = Blueprint("home", __name__)
@bp.get("/")
def home():
vault_path = current_app.config.get("KB_VAULT_PATH")
has_vault = bool(vault_path)
return render_template("home.html", vault_path=vault_path, has_vault=has_vault)

5
app/static/css/input.css Normal file
View File

@@ -0,0 +1,5 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
/* You can add custom CSS here if needed */

18
app/static/js/app.js Normal file
View File

@@ -0,0 +1,18 @@
(function themeInit() {
try {
const html = document.documentElement;
const select = document.getElementById("theme-select");
const saved = localStorage.getItem("theme") || "light";
html.setAttribute("data-theme", saved);
if (select) {
select.value = saved;
select.addEventListener("change", () => {
const value = select.value;
html.setAttribute("data-theme", value);
localStorage.setItem("theme", value);
});
}
} catch (e) {
// no-op
}
})();

35
app/templates/base.html Normal file
View File

@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>{% block title %}PKM{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}" />
<script defer src="{{ url_for('static', filename='js/app.js') }}"></script>
</head>
<body class="min-h-screen bg-base-200">
<div class="navbar bg-base-100 shadow">
<div class="flex-1">
<a href="{{ url_for('home.home') }}" class="btn btn-ghost text-xl">PKM</a>
</div>
<div class="flex-none gap-2">
<label class="label mr-2"><span class="label-text">Theme</span></label>
<select id="theme-select" class="select select-sm select-bordered">
<option>light</option>
<option>dark</option>
<option>cupcake</option>
</select>
</div>
</div>
<main class="container mx-auto p-4">
{% block content %}{% endblock %}
</main>
<footer class="footer items-center p-4 bg-base-100 text-base-content border-t">
<aside class="grid-flow-col items-center">
<p>PKM — Flask + Tailwind + DaisyUI</p>
</aside>
</footer>
</body>
</html>

26
app/templates/home.html Normal file
View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}PKM — Welcome{% endblock %}
{% block content %}
<div class="card bg-base-100 shadow">
<div class="card-body">
<h2 class="card-title">Welcome</h2>
{% if has_vault %}
<p>Your vault path is configured:</p>
<code class="kbd kbd-sm">{{ vault_path }}</code>
<p class="mt-2">You're ready to proceed with indexing and note features in the next milestones.</p>
{% else %}
<div class="alert alert-warning">
<span>No vault path configured.</span>
</div>
<p class="mt-2">
Set KB_VAULT_PATH in your environment or run via the CLI with
<span class="kbd kbd-sm">pkm run --vault /path/to/vault</span>
</p>
{% endif %}
<div class="divider"></div>
<p class="text-sm opacity-70">
Tailwind + DaisyUI is active. Try switching theme in the navbar.
</p>
</div>
</div>
{% endblock %}