| @@ -832,8 +832,11 @@ 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> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'logoUrl', true)} className="block w-full text-sm text-gray-900 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:bg-gray-100 cursor-pointer" /> | |||
| {uploading['logoUrl'] && <span className="text-xs text-blue-500">Uploading...</span>} | |||
| <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>} | |||
| {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" /> | |||
| @@ -846,8 +849,11 @@ 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> | |||
| <input type="file" accept="image/*" onChange={e => handleUpload(e, 'heroImageUrl', true)} className="block w-full text-sm text-gray-900 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:bg-gray-100 cursor-pointer" /> | |||
| {uploading['heroImageUrl'] && <span className="text-xs text-blue-500">Uploading...</span>} | |||
| <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>} | |||
| {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" /> | |||
| @@ -1091,12 +1097,15 @@ export default function AdminDashboard() { | |||
| : <>Cover Image <span className="text-gray-400 font-normal text-xs">(shown in grid)</span></>} | |||
| </label> | |||
| <div className="border-2 border-dashed border-gray-300 rounded-lg p-3 hover:bg-gray-50 transition-colors"> | |||
| <input | |||
| type="file" | |||
| accept={isEditing.cardType === 'FULLSCREEN_LOCK' ? 'image/*,video/mp4,video/webm,.mp4,.webm,.mov,.m4v' : 'image/*'} | |||
| onChange={e => handleUpload(e, 'imageUrl')} | |||
| className="block w-full text-sm text-gray-700 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 cursor-pointer" | |||
| /> | |||
| <label className="inline-block cursor-pointer bg-blue-50 hover:bg-blue-100 text-blue-700 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input | |||
| type="file" | |||
| accept={isEditing.cardType === 'FULLSCREEN_LOCK' ? 'image/*,video/mp4,video/webm,.mp4,.webm,.mov,.m4v' : 'image/*'} | |||
| onChange={e => handleUpload(e, 'imageUrl')} | |||
| hidden | |||
| /> | |||
| {isEditing.cardType === 'FULLSCREEN_LOCK' ? 'Choose image or video…' : 'Choose image…'} | |||
| </label> | |||
| {uploading['imageUrl'] && <p className="mt-2 text-sm text-blue-600 font-medium">Uploading...</p>} | |||
| </div> | |||
| {isEditing.imageUrl && ( | |||
| @@ -1129,13 +1138,16 @@ export default function AdminDashboard() { | |||
| Gallery Media <span className="text-gray-400 font-normal text-xs">(images, videos or PDFs — PDF pages become images)</span> | |||
| </label> | |||
| <div className="border-2 border-dashed border-gray-300 rounded-lg p-3 hover:bg-gray-50 transition-colors"> | |||
| <input | |||
| type="file" | |||
| accept="image/*,video/*,application/pdf,.pdf,.mov,.qt,.mkv,.avi,.divx,.wmv,.asf,.flv,.f4v,.3gp,.3gpp,.3g2,.mts,.m2ts,.ts,.mpg,.mpeg,.vob,.mxf,.ogv,.ogg" | |||
| multiple | |||
| onChange={handleUploadExtraMedia} | |||
| className="block w-full text-sm text-gray-700 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-purple-50 file:text-purple-700 hover:file:bg-purple-100 cursor-pointer" | |||
| /> | |||
| <label className="inline-block cursor-pointer bg-purple-50 hover:bg-purple-100 text-purple-700 font-semibold text-sm px-4 py-2 rounded-full transition-colors"> | |||
| <input | |||
| type="file" | |||
| accept="image/*,video/*,application/pdf,.pdf,.mov,.qt,.mkv,.avi,.divx,.wmv,.asf,.flv,.f4v,.3gp,.3gpp,.3g2,.mts,.m2ts,.ts,.mpg,.mpeg,.vob,.mxf,.ogv,.ogg" | |||
| multiple | |||
| onChange={handleUploadExtraMedia} | |||
| hidden | |||
| /> | |||
| Choose files… | |||
| </label> | |||
| {uploading['extraMedia'] && !pdfProgress && <p className="mt-2 text-sm text-purple-600 font-medium">Uploading...</p>} | |||
| {pdfProgress && ( | |||
| <p className="mt-2 text-sm text-purple-600 font-medium"> | |||