| @@ -15,7 +15,7 @@ function CharCounter({ value, limit }: CharCounterProps) { | |||
| const color = overflow ? 'text-red-600 font-semibold' : near ? 'text-amber-600' : 'text-gray-400'; | |||
| return ( | |||
| <p className={`text-xs mt-1 text-right ${color}`}> | |||
| {len} / {limit} · {remaining < 0 ? `${Math.abs(remaining)} oltre il limite` : `${remaining} rimanenti`} | |||
| {len} / {limit} · {remaining < 0 ? `${Math.abs(remaining)} over limit` : `${remaining} remaining`} | |||
| </p> | |||
| ); | |||
| } | |||
| @@ -832,11 +832,13 @@ export default function AdminDashboard() { | |||
| {/* Logo Upload with Remove Button */} | |||
| <div> | |||
| <label className="block text-sm font-semibold text-gray-700 mb-1">Logo Image</label> | |||
| <label className="inline-block cursor-pointer bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'logoUrl', true)} hidden /> | |||
| Choose image… | |||
| </label> | |||
| {uploading['logoUrl'] && <span className="text-xs text-blue-500 ml-3">Uploading...</span>} | |||
| <div className="flex items-center gap-3 flex-wrap"> | |||
| <label className="cursor-pointer bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'logoUrl', true)} hidden /> | |||
| Choose image… | |||
| </label> | |||
| {uploading['logoUrl'] && <span className="text-xs text-blue-500">Uploading...</span>} | |||
| </div> | |||
| {portal.logoUrl && ( | |||
| <div className="mt-2 bg-gray-100 p-4 rounded inline-block relative border"> | |||
| <img src={withBasePath(portal.logoUrl)} className="h-16 object-contain" alt="Logo Preview" /> | |||
| @@ -849,11 +851,13 @@ export default function AdminDashboard() { | |||
| {/* Hero Upload with Remove Button */} | |||
| <div> | |||
| <label className="block text-sm font-semibold text-gray-700 mb-1">Hero Background Image</label> | |||
| <label className="inline-block cursor-pointer bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'heroImageUrl', true)} hidden /> | |||
| Choose image… | |||
| </label> | |||
| {uploading['heroImageUrl'] && <span className="text-xs text-blue-500 ml-3">Uploading...</span>} | |||
| <div className="flex items-center gap-3 flex-wrap"> | |||
| <label className="cursor-pointer bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'heroImageUrl', true)} hidden /> | |||
| Choose image… | |||
| </label> | |||
| {uploading['heroImageUrl'] && <span className="text-xs text-blue-500">Uploading...</span>} | |||
| </div> | |||
| {portal.heroImageUrl && ( | |||
| <div className="mt-2 relative rounded shadow border inline-block w-full"> | |||
| <img src={withBasePath(portal.heroImageUrl)} className="h-32 w-full object-cover rounded" alt="Hero Preview" /> | |||