Build [v1.14.32]

This commit is contained in:
2026-04-26 14:45:54 +03:00
parent ba54820daa
commit cb1abe4d9c
11 changed files with 124 additions and 49 deletions

View File

@@ -160,7 +160,8 @@
"Bash(/data/programare_AI/tfm_ainventory/venv/bin/python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8916)", "Bash(/data/programare_AI/tfm_ainventory/venv/bin/python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8916)",
"Bash(curl -s http://localhost:8916/users/)", "Bash(curl -s http://localhost:8916/users/)",
"Bash(pkill -9 -f \"uvicorn.*backend.main\" sleep 2 /data/programare_AI/tfm_ainventory/venv/bin/python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8916)", "Bash(pkill -9 -f \"uvicorn.*backend.main\" sleep 2 /data/programare_AI/tfm_ainventory/venv/bin/python3 -m uvicorn backend.main:app --host 0.0.0.0 --port 8916)",
"Bash(curl -s http://localhost:8916/users/auth-mode)" "Bash(curl -s http://localhost:8916/users/auth-mode)",
"Bash(pkill -9 -f \"next-server|node.*next\" sleep 2 python3 scripts/run_standalone.py restart)"
] ]
} }
} }

View File

@@ -1,2 +1,3 @@
105655 127238
105674 127239
127256

View File

@@ -43,12 +43,19 @@
- `/users/auth-mode` — GET public endpoint to detect mode (returns `{mode, ldap_enabled}`) - `/users/auth-mode` — GET public endpoint to detect mode (returns `{mode, ldap_enabled}`)
- `/users/ldap-config` — GET admin-only (full LDAP configuration) - `/users/ldap-config` — GET admin-only (full LDAP configuration)
### Next Steps ### ✅ All Fixes Verified (2026-04-26, 14:00)
1. Test LDAP login with actual LDAP user credentials 1. ✅ Checkbox styling: 20px, 2px border, proper CSS variables
2. Verify local user login still works (if any local-only users exist) 2. ✅ CSS compilation: No PostCSS errors, page loads correctly
3. Run version bump: `python3 scripts/save_version.py` 3. ✅ Frontend server: Next.js 15.5.15 running on port 8917
4. ✅ Backend server: FastAPI/uvicorn running on port 8916
5. ✅ Auth-mode detection: LDAP enabled, both login modes available
6. ✅ TokenResponse schema: Includes user object
7. ✅ Standalone script: Uses venv python correctly
### Remaining Task
- Run version bump: `python3 scripts/save_version.py` to finalize all session changes
## Git Status ## Git Status
- Branch: dev - Branch: dev
- Commits: 51716faf + 62c592d6 + dc999991 - Commits: 51716faf + 62c592d6 + dc999991 + CSS fix
- All LDAP login issues resolved - All LDAP login, UI, checkbox, and script issues resolved

View File

@@ -1,6 +1,6 @@
{ {
"version": "1.14.31", "version": "1.14.32",
"last_build": "2026-04-25-1253", "last_build": "2026-04-26-1445",
"codename": "ConfigCore", "codename": "ConfigCore",
"commit": "d0f166a3" "commit": "ba54820d"
} }

View File

@@ -5,7 +5,7 @@
@tailwind utilities; @tailwind utilities;
@layer base { @layer base {
:root { :root {
/* Base colors from DESIGN.md - AUTO-GENERATED from colors.mjs */ /* Base colors from DESIGN.md - AUTO-GENERATED from colors.mjs */
/* Base colors from DESIGN.md */ /* Base colors from DESIGN.md */
@@ -97,6 +97,14 @@
* { * {
@@ -122,17 +130,22 @@
/* Checkbox styling - proper, usable checkboxes */ /* Checkbox styling - proper, usable checkboxes */
input[type="checkbox"] { input[type="checkbox"] {
@apply w-5 h-5 cursor-pointer accent-primary border-2 border-outline; width: 20px;
height: 20px;
cursor: pointer;
accent-color: var(--primary-DEFAULT);
border: 2px solid var(--outline);
border-radius: 3px; border-radius: 3px;
appearance: auto; appearance: auto;
} }
input[type="checkbox"]:hover { input[type="checkbox"]:hover {
@apply border-primary; border-color: var(--primary-DEFAULT);
} }
input[type="checkbox"]:focus { input[type="checkbox"]:focus {
@apply ring-2 ring-primary outline-none; outline: 2px solid var(--primary-DEFAULT);
outline-offset: 2px;
} }
h1 { h1 {
@@ -170,7 +183,7 @@
color: var(--primary-foreground); color: var(--primary-foreground);
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
@apply inline-flex items-center justify-center gap-2 transition-opacity hover:opacity-90; @apply inline-flex items-center justify-center gap-2 transition-opacity hover:opacity-90;
border-radius: 0 !important; border-radius: 5px !important;
} }
.btn-secondary { .btn-secondary {
@@ -179,7 +192,7 @@
color: var(--secondary-DEFAULT); color: var(--secondary-DEFAULT);
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
@apply inline-flex items-center justify-center gap-2 transition-colors; @apply inline-flex items-center justify-center gap-2 transition-colors;
border-radius: 0 !important; border-radius: 5px !important;
} }
.btn-secondary:hover { .btn-secondary:hover {
@@ -255,6 +268,71 @@
border-radius: 0 !important; border-radius: 0 !important;
} }
/* ── Pill Toggle — replaces all input[type="checkbox"] ── */
.toggle-pill {
-webkit-appearance: none !important;
appearance: none !important;
width: 42px !important;
height: 24px !important;
border-radius: 999px !important;
background: var(--surface-bright) !important;
border: 1.5px solid var(--outline) !important;
position: relative !important;
cursor: pointer !important;
flex-shrink: 0 !important;
transition: background 0.22s ease, border-color 0.22s ease !important;
outline: none !important;
accent-color: transparent !important;
}
.toggle-pill::after {
content: '' !important;
position: absolute !important;
top: 3px !important;
left: 3px !important;
width: 16px !important;
height: 16px !important;
border-radius: 50% !important;
background: var(--secondary) !important;
transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.22s !important;
box-shadow: 0 1px 3px rgba(0,0,0,0.4) !important;
display: block !important;
}
.toggle-pill:checked {
background: var(--primary-DEFAULT) !important;
border-color: var(--primary-DEFAULT) !important;
}
.toggle-pill:checked::after {
transform: translateX(18px) !important;
background: var(--primary-foreground) !important;
}
.toggle-pill:focus-visible {
outline: 2px solid var(--primary-DEFAULT) !important;
outline-offset: 2px !important;
}
.toggle-pill:disabled {
opacity: 0.4 !important;
cursor: not-allowed !important;
}
.toggle-pill.sm {
width: 34px !important;
height: 19px !important;
}
.toggle-pill.sm::after {
width: 13px !important;
height: 13px !important;
}
.toggle-pill.sm:checked::after {
transform: translateX(15px) !important;
}
.headline-lg { .headline-lg {
@apply text-5xl font-normal; @apply text-5xl font-normal;
letter-spacing: -0.02em; letter-spacing: -0.02em;

View File

@@ -357,7 +357,7 @@ export default function CreateItemPage() {
setCropBounds(null); setCropBounds(null);
} }
}} }}
className="w-4 h-4 rounded border-outline accent-primary" className="toggle-pill"
/> />
<label htmlFor="use-full-photo" className="text-sm font-normal text-[#CCCCCC]"> <label htmlFor="use-full-photo" className="text-sm font-normal text-[#CCCCCC]">
Use full photo (skip cropping) Use full photo (skip cropping)

View File

@@ -159,9 +159,9 @@ export default function LogsPage() {
: "bg-surface/70 text-secondary border-border hover:border-border" : "bg-surface/70 text-secondary border-border hover:border-border"
)} )}
> >
All Streams &nbsp; All Streams &nbsp;
</button> </button>
{['ADD', 'REMOVE', 'ADJUST', 'DELETE', 'LOGIN'].map((f) => ( {['Add', 'Remove', 'Adjust', 'Delete', 'Login'].map((f) => (
<button <button
key={f} key={f}
onClick={() => setFilterAction(f)} onClick={() => setFilterAction(f)}
@@ -172,7 +172,7 @@ export default function LogsPage() {
: "bg-surface/70 text-secondary border-border hover:border-border" : "bg-surface/70 text-secondary border-border hover:border-border"
)} )}
> >
{f} &nbsp; {f} &nbsp;
</button> </button>
))} ))}
</div> </div>

View File

@@ -256,7 +256,7 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento
id="save-photo-check" id="save-photo-check"
checked={!extractedItems[editingIndex]._skipPhoto} checked={!extractedItems[editingIndex]._skipPhoto}
onChange={(e) => updateEditingItem({ _skipPhoto: !e.target.checked })} onChange={(e) => updateEditingItem({ _skipPhoto: !e.target.checked })}
className="w-4 h-4 rounded border-outline accent-primary cursor-pointer" className="toggle-pill"
/> />
<label htmlFor="save-photo-check" className="text-xs text-[#CCCCCC] font-normal cursor-pointer"> <label htmlFor="save-photo-check" className="text-xs text-[#CCCCCC] font-normal cursor-pointer">
Save this photo with the item Save this photo with the item

View File

@@ -300,7 +300,7 @@ export function ImageAdjustmentModal({ imageUrl, onConfirm, onCancel }: ImageAdj
type="checkbox" type="checkbox"
checked={useImage} checked={useImage}
onChange={(e) => setUseImage(e.target.checked)} onChange={(e) => setUseImage(e.target.checked)}
className="w-4 h-4" className="toggle-pill"
/> />
Use this image Use this image
</label> </label>

View File

@@ -13,7 +13,7 @@ export default function StatCard({ label, value, icon: Icon }: StatCardProps) {
<div className="flex items-center gap-2.5 min-w-0"> <div className="flex items-center gap-2.5 min-w-0">
{Icon && <Icon className="w-5 h-5 text-primary flex-shrink-0" aria-hidden="true" />} {Icon && <Icon className="w-5 h-5 text-primary flex-shrink-0" aria-hidden="true" />}
<span className="text-base md:text-lg text-secondary font-normal truncate"> <span className="text-base md:text-lg text-secondary font-normal truncate">
{label} &nbsp; {label}
</span> </span>
</div> </div>

View File

@@ -43,18 +43,12 @@ export default function LdapManager({
</p> </p>
</div> </div>
</div> </div>
<button <input
onClick={() => setLdapConfig({...ldapConfig, ldap_enabled: !ldapConfig.ldap_enabled})} type="checkbox"
className={cn( checked={ldapConfig.ldap_enabled}
"w-10 h-5 relative transition-all duration-300 border", onChange={(e) => setLdapConfig({...ldapConfig, ldap_enabled: e.target.checked})}
ldapConfig.ldap_enabled ? "bg-primary border-primary" : "bg-surface-bright border-border" className="toggle-pill"
)} />
>
<div className={cn(
"absolute top-0.5 w-3.5 h-3.5 bg-surface-container-lowest transition-all",
ldapConfig.ldap_enabled ? "right-0.5" : "left-0.5"
)} />
</button>
</div> </div>
<div className="grid sm:grid-cols-2 gap-3"> <div className="grid sm:grid-cols-2 gap-3">
@@ -130,18 +124,12 @@ export default function LdapManager({
</p> </p>
</div> </div>
</div> </div>
<button <input
onClick={() => setLdapConfig({...ldapConfig, use_tls: !ldapConfig.use_tls})} type="checkbox"
className={cn( checked={ldapConfig.use_tls}
"w-10 h-5 relative transition-all duration-300 border", onChange={(e) => setLdapConfig({...ldapConfig, use_tls: e.target.checked})}
ldapConfig.use_tls ? "bg-primary border-primary" : "bg-surface-bright border-border" className="toggle-pill"
)} />
>
<div className={cn(
"absolute top-0.5 w-3.5 h-3.5 bg-surface-container-lowest transition-all",
ldapConfig.use_tls ? "right-0.5" : "left-0.5"
)} />
</button>
</div> </div>
<div className="flex gap-2 pt-0"> <div className="flex gap-2 pt-0">