From b8beb6a2b942d35309335702b8afc50b7f7277af Mon Sep 17 00:00:00 2001 From: paul2212 Date: Wed, 18 Mar 2026 17:47:53 +0100 Subject: [PATCH] 0.1.31 --- fichero_printer/CHANGELOG.md | 17 ++ fichero_printer/config.yaml | 2 +- fichero_printer/fichero/api.py | 57 +++-- fichero_printer/fichero/index.html | 322 +++++++++++++++++++++++++---- pyproject.toml | 2 +- 5 files changed, 348 insertions(+), 52 deletions(-) diff --git a/fichero_printer/CHANGELOG.md b/fichero_printer/CHANGELOG.md index a52b579..016af9e 100644 --- a/fichero_printer/CHANGELOG.md +++ b/fichero_printer/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project are documented in this file. The format is based on Keep a Changelog and this project uses Semantic Versioning. +## [0.1.31] - 2026-03-18 + +### Added +- **Web UI**: Completely modernized and responsive design with improved mobile support, smooth animations, and professional styling. +- **Web UI**: Enhanced debug scan section with loading indicators, signal strength visualization, and helpful troubleshooting tips. +- **Web UI**: Added loading spinners, status indicators, and better error messages throughout the interface. + +### Changed +- **Web UI**: Updated CSS with modern design system including CSS variables, transitions, and responsive breakpoints. +- **Web UI**: Improved button styling, card hover effects, and overall visual hierarchy. +- **Web UI**: Better mobile responsiveness with optimized touch targets and single-column layouts on small screens. + +### Fixed +- **Web UI**: Fixed scan section visibility and positioning - now properly integrated into main content area. +- **Web UI**: Improved scan button styling to match the modern design language. +- **Web UI**: Added proper CSS styling for the scan section instead of inline styles. + ## [0.1.30] - 2026-03-16 ### Fixed diff --git a/fichero_printer/config.yaml b/fichero_printer/config.yaml index c647577..7b626ef 100644 --- a/fichero_printer/config.yaml +++ b/fichero_printer/config.yaml @@ -1,5 +1,5 @@ name: "Fichero Printer" -version: "0.1.30" +version: "0.1.31" slug: "fichero_printer" description: "REST API for the Fichero D11s (AiYin) thermal label printer over Bluetooth" url: "https://git.leuschner.dev/Tobias/Fichero" diff --git a/fichero_printer/fichero/api.py b/fichero_printer/fichero/api.py index fbedf20..87b5072 100644 --- a/fichero_printer/fichero/api.py +++ b/fichero_printer/fichero/api.py @@ -77,7 +77,7 @@ async def lifespan(app: FastAPI): # noqa: ARG001 app = FastAPI( title="Fichero Printer API", description="REST API for the Fichero D11s (AiYin) thermal label printer.", - version = "0.1.30", + version = "0.1.31", lifespan=lifespan, docs_url=None, redoc_url=None, @@ -123,43 +123,74 @@ def _ui_html() -> str: # Inject debug scan section and script scan_html = """ -
+

Debug Scan

-

Scans for all nearby BLE devices to help with debugging connection issues.

- -

+            

Scans for all nearby BLE devices to help with debugging connection issues.

+ +

         
""" scan_script = r''' ''' - # Inject before the closing tag - if "" in template: + # Inject after the main content but before scripts + if "" in template: + parts = template.split("", 1) + template = parts[0] + "" + scan_html + parts[1] + elif "" in template: parts = template.split("", 1) template = parts[0] + scan_html + scan_script + "" + parts[1] else: - # Fallback if no body tag + # Fallback if no main or body tag template += scan_html + scan_script return template diff --git a/fichero_printer/fichero/index.html b/fichero_printer/fichero/index.html index a0f927e..7e011b6 100644 --- a/fichero_printer/fichero/index.html +++ b/fichero_printer/fichero/index.html @@ -13,99 +13,347 @@ --muted: #6c6258; --accent: #b55e33; --accent-2: #245b4b; + --success: #2e8b57; + --warning: #cd853f; + --shadow-sm: 0 1px 3px rgba(45, 36, 29, 0.1); + --shadow-md: 0 4px 12px rgba(45, 36, 29, 0.1); + --shadow-lg: 0 12px 24px rgba(45, 36, 29, 0.15); + --transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } - * { box-sizing: border-box; } + + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + body { margin: 0; - font-family: "Noto Sans", system-ui, sans-serif; + font-family: "Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", system-ui, sans-serif; color: var(--ink); background: radial-gradient(circle at top left, #fff8ed 0, transparent 35%), linear-gradient(180deg, #efe4d3 0%, var(--bg) 100%); + min-height: 100vh; + line-height: 1.6; } + main { - max-width: 980px; + max-width: 1200px; margin: 0 auto; - padding: 24px 16px 40px; + padding: 2rem 1rem 3rem; } + .hero { - margin-bottom: 20px; - padding: 24px; + margin-bottom: 2rem; + padding: 2rem; border: 1px solid var(--line); - border-radius: 18px; - background: rgba(255, 250, 242, 0.92); - backdrop-filter: blur(4px); + border-radius: 20px; + background: rgba(255, 250, 242, 0.95); + backdrop-filter: blur(6px); + box-shadow: var(--shadow-md); + position: relative; + overflow: hidden; } - h1, h2 { margin: 0 0 12px; } - .muted { color: var(--muted); } + + .hero::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 4px; + background: linear-gradient(90deg, var(--accent), var(--accent-2)); + } + + h1 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 0.5rem; + display: flex; + align-items: center; + gap: 0.5rem; + } + + h2 { + font-size: 1.5rem; + font-weight: 600; + margin-bottom: 1rem; + color: var(--ink); + border-bottom: 2px solid var(--line); + padding-bottom: 0.5rem; + } + + h3 { + font-size: 1.25rem; + font-weight: 600; + margin-bottom: 1rem; + color: var(--ink); + } + + .muted { + color: var(--muted); + font-size: 0.9rem; + } + .grid { display: grid; - gap: 16px; - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + margin-bottom: 2rem; } + .card { - padding: 18px; + padding: 1.5rem; border: 1px solid var(--line); border-radius: 16px; background: var(--panel); - box-shadow: 0 8px 24px rgba(45, 36, 29, 0.06); + box-shadow: var(--shadow-sm); + transition: var(--transition); } + + .card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-2px); + } + + .card h3 { + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--line); + } + label { display: block; - margin: 10px 0 6px; - font-size: 0.92rem; + margin: 0.75rem 0 0.5rem; + font-size: 0.9rem; font-weight: 600; + color: var(--ink); } - input, select, textarea, button { + + input, select, textarea { width: 100%; border-radius: 10px; border: 1px solid var(--line); - padding: 10px 12px; + padding: 0.75rem 1rem; font: inherit; + font-size: 0.95rem; + background: white; + transition: var(--transition); } - textarea { min-height: 110px; resize: vertical; } + + input:focus, select:focus, textarea:focus { + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 2px rgba(181, 94, 51, 0.1); + } + + textarea { + min-height: 120px; + resize: vertical; + font-family: inherit; + } + .row { display: grid; - gap: 12px; + gap: 1rem; grid-template-columns: repeat(2, minmax(0, 1fr)); + margin-top: 0.5rem; } + .inline { display: flex; - gap: 10px; + gap: 0.75rem; align-items: center; - margin-top: 12px; + margin-top: 1rem; } - .inline input[type="checkbox"] { width: auto; } + + .inline input[type="checkbox"] { + width: auto; + transform: scale(1.2); + } + button { cursor: pointer; - font-weight: 700; - color: #fff; + font-weight: 600; + color: white; background: var(--accent); border: none; + border-radius: 10px; + padding: 0.75rem 1.5rem; + font-size: 0.95rem; + transition: var(--transition); + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; } - button.alt { background: var(--accent-2); } + + button:hover { + background: #a1542d; + transform: translateY(-1px); + } + + button:active { + transform: translateY(0); + } + + button.alt { + background: var(--accent-2); + } + + button.alt:hover { + background: #1f4e41; + } + + button.secondary { + background: var(--line); + color: var(--ink); + } + + button.secondary:hover { + background: #c5b8a8; + } + pre { overflow: auto; - margin: 0; - padding: 12px; + margin: 1rem 0; + padding: 1rem; border-radius: 12px; background: #241f1a; color: #f7efe4; - min-height: 140px; + min-height: 160px; + font-size: 0.9rem; + position: relative; } + + pre::before { + content: '$'; + position: absolute; + left: 1rem; + top: 1rem; + color: var(--muted); + font-weight: bold; + } + .actions { display: flex; - gap: 10px; + gap: 0.75rem; flex-wrap: wrap; - margin-top: 12px; + margin-top: 1.5rem; } + .actions button { - width: auto; - min-width: 140px; + flex: 1; + min-width: 160px; } - @media (max-width: 640px) { - .row { grid-template-columns: 1fr; } - .actions button { width: 100%; } + + @media (max-width: 768px) { + main { + padding: 1.5rem 1rem 2.5rem; + } + + .hero { + padding: 1.5rem; + } + + h1 { + font-size: 1.75rem; + } + + .grid { + grid-template-columns: 1fr; + } + + .row { + grid-template-columns: 1fr; + } + + .actions button { + width: 100%; + } + } + + @media (max-width: 480px) { + h1 { + font-size: 1.5rem; + } + + h2 { + font-size: 1.25rem; + } + + button { + padding: 0.6rem 1rem; + font-size: 0.9rem; + } + } + + /* Loading spinner */ + .loading { + display: inline-block; + width: 20px; + height: 20px; + border: 3px solid rgba(255, 255, 255, 0.3); + border-radius: 50%; + border-top-color: white; + animation: spin 1s ease-in-out infinite; + } + + @keyframes spin { + to { transform: rotate(360deg); } + } + + /* Status indicators */ + .status { + display: inline-block; + padding: 0.25rem 0.5rem; + border-radius: 12px; + font-size: 0.8rem; + font-weight: 600; + margin-left: 0.5rem; + } + + .status.success { + background: rgba(46, 139, 87, 0.2); + color: var(--success); + } + + .status.error { + background: rgba(205, 133, 63, 0.2); + color: var(--warning); + } + + /* Tabs */ + .tabs { + display: flex; + gap: 0.5rem; + margin-bottom: 1.5rem; + border-bottom: 1px solid var(--line); + } + + .tab { + padding: 0.75rem 1rem; + cursor: pointer; + border: none; + background: transparent; + color: var(--muted); + font-weight: 500; + border-bottom: 2px solid transparent; + transition: var(--transition); + } + + .tab.active { + color: var(--ink); + border-bottom-color: var(--accent); + } + + .tab-content { + display: none; + } + + .tab-content.active { + display: block; } diff --git a/pyproject.toml b/pyproject.toml index 62905d7..66698b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "fichero-printer" -version = "0.1.30" +version = "0.1.31" description = "Web GUI, Python CLI, and protocol documentation for the Fichero D11s thermal label printer." readme = "README.md" requires-python = ">=3.10"