style: synchronize icons for categories and items v1.2.5
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"last_build": "2026-04-11-1146",
|
"last_build": "2026-04-11-1200",
|
||||||
"commit": "b6e3f",
|
"commit": "c8f1a",
|
||||||
"changelog": [
|
"changelog": [
|
||||||
|
"v1.2.5: Synchronized icons across UI (Layers for Categories, Package for Item Types)",
|
||||||
"v1.2.4: Offline LDAP auth support and UI affordance improvements (Dropdown chevrons, soft password dots)",
|
"v1.2.4: Offline LDAP auth support and UI affordance improvements (Dropdown chevrons, soft password dots)",
|
||||||
"v1.2.3: System-wide UI consistency (standardized font sizes, removed uppercase)",
|
"v1.2.3: System-wide UI consistency (standardized font sizes, removed uppercase)",
|
||||||
"v1.2.2: UI Readability refactor (Removed uppercase/tracking, increased font sizes)",
|
"v1.2.2: UI Readability refactor (Removed uppercase/tracking, increased font sizes)",
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
### [2026-04-11 11:45] v1.2.4: Offline Auth & UX Polish
|
### [2026-04-11 11:58] v1.2.5: UI Icon Synchronization
|
||||||
**Purpose:** Implemented local password hash caching for LDAP users to allow login in no-network environments (basements/subsoils). Refined UI by softening password field dots and adding visual indicators (chevrons) to all dropdowns for better affordance.
|
**Purpose:** Unified iconography across the system for better visual association. Substituted `Tag` with `Layers` for all Category references and added the green `Package` icon to all item listing instances. Refined AI Onboarding and Admin panels for total consistency.
|
||||||
**Modified Files:**
|
**Modified Files:**
|
||||||
- `backend/routers/users.py` (LDAP offline cache)
|
- `frontend/app/inventory/page.tsx`
|
||||||
- `frontend/app/admin/page.tsx` (Password/Dropdown UI)
|
- `frontend/app/admin/page.tsx`
|
||||||
- `frontend/app/login/page.tsx` (Password UI)
|
- `frontend/components/AdminOverlay.tsx`
|
||||||
- `frontend/app/inventory/page.tsx` (Dropdown UI)
|
- `frontend/components/AIOnboarding.tsx`
|
||||||
- `frontend/app/page.tsx` (Dropdown UI)
|
|
||||||
- `frontend/components/IdentityCheckOverlay.tsx` (Password UI)
|
|
||||||
- `VERSION.json`
|
- `VERSION.json`
|
||||||
|
|
||||||
|
### [2026-04-11 11:45] v1.2.4: Offline Auth & UX Polish
|
||||||
|
|
||||||
### [2026-04-11 11:30] v1.2.3: System-Wide UI Homogenization
|
### [2026-04-11 11:30] v1.2.3: System-Wide UI Homogenization
|
||||||
|
|
||||||
### [2026-04-11 11:21] v1.2.2: UI Readability & Density Optimization
|
### [2026-04-11 11:21] v1.2.2: UI Readability & Density Optimization
|
||||||
|
|||||||
1
frontend/app/.#page.tsx
Symbolic link
1
frontend/app/.#page.tsx
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
danielbedeleanu@Daniels-MacBook-Pro-14-M1.local.30836
|
||||||
@@ -286,7 +286,7 @@ export default function AdminPage() {
|
|||||||
<section className="space-y-6">
|
<section className="space-y-6">
|
||||||
<div className="flex items-center justify-between px-2">
|
<div className="flex items-center justify-between px-2">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<Tag size={20} className="text-primary" />
|
<Layers size={20} className="text-primary" />
|
||||||
<h2 className="text-lg font-black text-white">Category Groups</h2>
|
<h2 className="text-lg font-black text-white">Category Groups</h2>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -304,8 +304,8 @@ export default function AdminPage() {
|
|||||||
categories.map(cat => (
|
categories.map(cat => (
|
||||||
<div key={cat.id} className="flex items-center justify-between p-4 hover:bg-slate-800/30 transition-all group">
|
<div key={cat.id} className="flex items-center justify-between p-4 hover:bg-slate-800/30 transition-all group">
|
||||||
<div className="flex items-center gap-4 min-w-0 flex-1">
|
<div className="flex items-center gap-4 min-w-0 flex-1">
|
||||||
<div className="p-2.5 bg-slate-800 text-slate-500 rounded-xl border border-slate-700 shadow-inner group-hover:text-primary transition-all shrink-0">
|
<div className="p-2.5 bg-slate-800 text-slate-500 rounded-xl border border-slate-700 shadow-inner group-hover:text-primary group-hover:bg-primary/5 transition-all shrink-0">
|
||||||
<Tag size={16} />
|
<Layers size={16} />
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<p className="text-sm font-bold text-white group-hover:text-primary transition-colors truncate">{cat.name}</p>
|
<p className="text-sm font-bold text-white group-hover:text-primary transition-colors truncate">{cat.name}</p>
|
||||||
|
|||||||
@@ -245,8 +245,8 @@ export default function InventoryPage() {
|
|||||||
onClick={() => setExpandedCategory(expandedCategory === cat ? null : cat)}
|
onClick={() => setExpandedCategory(expandedCategory === cat ? null : cat)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="w-10 h-10 rounded-2xl bg-slate-800 flex items-center justify-center text-slate-400 group-hover:text-primary transition-colors">
|
<div className="w-10 h-10 rounded-2xl bg-primary/10 flex items-center justify-center text-primary transition-colors">
|
||||||
<Tag size={20} />
|
<Layers size={20} />
|
||||||
</div>
|
</div>
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<h3 className="font-bold text-lg">{cat}</h3>
|
<h3 className="font-bold text-lg">{cat}</h3>
|
||||||
@@ -286,9 +286,14 @@ export default function InventoryPage() {
|
|||||||
onClick={() => setSelectedItem(item)}
|
onClick={() => setSelectedItem(item)}
|
||||||
className="bg-slate-950/40 border border-slate-800/50 p-4 rounded-2xl flex items-center justify-between hover:border-primary/40 cursor-pointer transition-all active:scale-[0.98]"
|
className="bg-slate-950/40 border border-slate-800/50 p-4 rounded-2xl flex items-center justify-between hover:border-primary/40 cursor-pointer transition-all active:scale-[0.98]"
|
||||||
>
|
>
|
||||||
<div className="flex-1 min-w-0 pr-4">
|
<div className="flex items-center gap-3 flex-1 min-w-0 pr-4">
|
||||||
<h4 className="font-bold text-slate-200 truncate">{item.name}</h4>
|
<div className="w-8 h-8 rounded-xl bg-green-500/10 flex items-center justify-center text-green-500 shrink-0">
|
||||||
<p className="text-[10px] text-slate-500 truncate mt-0.5">{item.specs}</p>
|
<Package size={14} />
|
||||||
|
</div>
|
||||||
|
<div className="truncate">
|
||||||
|
<h4 className="font-bold text-slate-200 truncate">{item.name}</h4>
|
||||||
|
<p className="text-[10px] text-slate-500 truncate mt-0.5">{item.specs}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right shrink-0">
|
<div className="text-right shrink-0">
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { useState, useRef } from 'react';
|
import { useState, useRef } from 'react';
|
||||||
import { toast } from 'react-hot-toast';
|
import { toast } from 'react-hot-toast';
|
||||||
import { Camera, Check, RefreshCw, X, Image as ImageIcon, Sparkles, Hash, Layout } from 'lucide-react';
|
import { Camera, Check, RefreshCw, X, Image as ImageIcon, Sparkles, Hash, Layout, Layers, Package, ChevronDown } from 'lucide-react';
|
||||||
import { inventoryApi } from '@/lib/api';
|
import { inventoryApi } from '@/lib/api';
|
||||||
|
|
||||||
interface AIOnboardingProps {
|
interface AIOnboardingProps {
|
||||||
@@ -176,20 +176,29 @@ export default function AIOnboarding({ onCancel, onComplete, categories }: AIOnb
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="bg-slate-900/80 p-5 rounded-[1.5rem] border border-slate-800 focus-within:border-primary/50 transition-colors group">
|
<div className="bg-slate-900/80 p-5 rounded-[1.5rem] border border-slate-800 focus-within:border-primary/50 transition-colors group">
|
||||||
<label className="text-xs text-slate-500 font-bold mb-1 block group-focus-within:text-primary transition-colors">Category Group</label>
|
<div className="flex items-center gap-1.5 mb-1 ml-1 group-focus-within:text-primary transition-colors">
|
||||||
<select
|
<Layers size={12} />
|
||||||
value={extractedData.category || ''}
|
<label className="text-xs text-slate-500 font-bold">Category Group</label>
|
||||||
onChange={(e) => setExtractedData({...extractedData, category: e.target.value})}
|
</div>
|
||||||
className="bg-transparent w-full font-bold outline-none text-slate-200"
|
<div className="relative flex items-center">
|
||||||
>
|
<select
|
||||||
<option value="" className="bg-slate-900 font-bold">Other / New</option>
|
value={extractedData.category || ''}
|
||||||
{categories.map(c => (
|
onChange={(e) => setExtractedData({...extractedData, category: e.target.value})}
|
||||||
<option key={c.id} value={c.name} className="bg-slate-900">{c.name}</option>
|
className="bg-transparent w-full font-bold outline-none text-slate-200 appearance-none"
|
||||||
))}
|
>
|
||||||
</select>
|
<option value="" className="bg-slate-900 font-bold">Other / New</option>
|
||||||
|
{categories.map(c => (
|
||||||
|
<option key={c.id} value={c.name} className="bg-slate-900">{c.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<ChevronDown size={14} className="absolute right-0 text-slate-500 pointer-events-none" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-slate-900/80 p-5 rounded-[1.5rem] border border-slate-800 focus-within:border-primary/50 transition-colors group">
|
<div className="bg-slate-900/80 p-5 rounded-[1.5rem] border border-slate-800 focus-within:border-primary/50 transition-colors group">
|
||||||
<label className="text-xs text-slate-500 font-bold mb-1 block group-focus-within:text-primary transition-colors">Item Type</label>
|
<div className="flex items-center gap-1.5 mb-1 ml-1 group-focus-within:text-primary transition-colors">
|
||||||
|
<Package size={12} />
|
||||||
|
<label className="text-xs text-slate-500 font-bold">Item Type</label>
|
||||||
|
</div>
|
||||||
<input
|
<input
|
||||||
value={extractedData.type || ''}
|
value={extractedData.type || ''}
|
||||||
onChange={(e) => setExtractedData({...extractedData, type: e.target.value})}
|
onChange={(e) => setExtractedData({...extractedData, type: e.target.value})}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { X, Shield, UserPlus, User, Trash2, Tag, Plus, AlertTriangle, LogOut } from 'lucide-react';
|
import { X, Shield, UserPlus, User, Trash2, Tag, Plus, AlertTriangle, LogOut, Layers } from 'lucide-react';
|
||||||
import { inventoryApi } from '@/lib/api';
|
import { inventoryApi } from '@/lib/api';
|
||||||
import { toast } from 'react-hot-toast';
|
import { toast } from 'react-hot-toast';
|
||||||
|
|
||||||
@@ -124,8 +124,8 @@ export default function AdminOverlay({
|
|||||||
{categories.map(cat => (
|
{categories.map(cat => (
|
||||||
<div key={cat.id} className="bg-slate-800/40 border border-slate-800 p-4 rounded-2xl flex items-center justify-between">
|
<div key={cat.id} className="bg-slate-800/40 border border-slate-800 p-4 rounded-2xl flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="p-2 bg-slate-700 rounded-lg text-slate-400">
|
<div className="p-2 bg-primary/10 rounded-lg text-primary">
|
||||||
<Tag size={16} />
|
<Layers size={16} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-sm font-bold text-white">{cat.name}</p>
|
<p className="text-sm font-bold text-white">{cat.name}</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user