소스 검색

Aggiunge campo hex editabile accanto al color picker del theme

Il selettore browser nativo varia per OS e non sempre ha un campo hex visibile.
Affianco al picker ora c'e' un input testuale font-mono che accetta direttamente
una stringa #RRGGBB (es. copia/incolla da Figma o brand book). La validazione e'
in tempo reale: durante la digitazione il valore resta libero (con bordo rosso
se non e' ancora un hex valido) e committa su portal.themeColor solo quando
matcha /^#[0-9a-fA-F]{6}$/. Sull'onBlur, se il campo e' rimasto invalido,
ripristina l'ultimo valore noto. Editing via picker aggiorna il campo testo
tramite effect sincronizzato.
main
부모
커밋
b3e4d3945a
1개의 변경된 파일26개의 추가작업 그리고 1개의 파일을 삭제
  1. +26
    -1
      app/admin/page.tsx

+ 26
- 1
app/admin/page.tsx 파일 보기

@@ -259,6 +259,13 @@ export default function AdminDashboard() {
const [savingPortal, setSavingPortal] = useState(false);
const [uploading, setUploading] = useState<{ [key: string]: boolean }>({});
// Hex input per il theme color: stato locale che resta libero durante la digitazione,
// committa su portal.themeColor solo quando la stringa e' un hex completo valido.
const [hexInput, setHexInput] = useState<string>('#1e3a8a');
useEffect(() => {
if (portal.themeColor) setHexInput(portal.themeColor);
}, [portal.themeColor]);
// NEW UI STATES: Toast and Confirm Dialog
const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null);
const [confirmDialog, setConfirmDialog] = useState<{ message: string, onConfirm: () => void } | null>(null);
@@ -836,7 +843,25 @@ export default function AdminDashboard() {
<label className="block text-sm font-semibold text-gray-700 mb-1">Theme Color</label>
<div className="flex items-center gap-4">
<input type="color" value={portal.themeColor || '#1e3a8a'} onChange={e => setPortal({...portal, themeColor: e.target.value})} className="h-12 w-12 rounded cursor-pointer border-0 p-0" />
<span className="text-gray-900 font-mono font-medium">{portal.themeColor || '#1e3a8a'}</span>
<input
type="text"
value={hexInput}
onChange={e => {
const v = e.target.value;
setHexInput(v);
// Commit a portal.themeColor solo se la stringa e' un hex pieno e valido.
if (/^#[0-9a-fA-F]{6}$/.test(v)) setPortal({ ...portal, themeColor: v.toLowerCase() });
}}
onBlur={() => {
// Se l'utente esce dal campo con un valore non valido, ripristina l'ultimo valore noto.
if (!/^#[0-9a-fA-F]{6}$/.test(hexInput)) setHexInput(portal.themeColor || '#1e3a8a');
}}
maxLength={7}
spellCheck={false}
placeholder="#RRGGBB"
aria-label="Theme color hex"
className={`font-mono text-sm px-3 py-2 rounded border outline-none focus:ring-2 focus:ring-blue-500 w-32 ${/^#[0-9a-fA-F]{6}$/.test(hexInput) ? 'border-gray-300 text-gray-900' : 'border-red-500 text-red-600'}`}
/>
</div>
</div>


불러오는 중...
취소
저장