Changeset 3462124
- Timestamp:
- 02/16/2026 01:18:05 AM (3 days ago)
- Location:
- ai-alt-text-builder/trunk
- Files:
-
- 1 added
- 4 edited
-
admin/assets/css/admin.css (modified) (1 diff)
-
admin/assets/img/header-logo.png (added)
-
admin/settings-page.php (modified) (2 diffs)
-
ai-alt-text-builder.php (modified) (2 diffs)
-
readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
ai-alt-text-builder/trunk/admin/assets/css/admin.css
r3401714 r3462124 1 /* RankPilotAI — Admin UI 2 Shared styles for all settings pages; responsive-ready */ 1 /*! 2 * AI Alt Text Builder — Admin Styles 3 * Version: 1.0.7 4 * Modern UI for Media Library generate button, score badges & list table 5 */ 3 6 4 :root{ 5 --dark:#243746; 6 --blue:#0984e3; 7 --blue-light:#0b9dfb; 8 --border:#ddd; 9 --bg:#f9f9f9; 7 /* ========== GENERATE BUTTON (Media Library / Attachment) ========== */ 8 .aatb-gen { 9 display: inline-flex; 10 align-items: center; 11 justify-content: center; 12 gap: 6px; 13 padding: 8px 16px; 14 font-size: 13px; 15 font-weight: 600; 16 line-height: 1.4; 17 border: none; 18 border-radius: 6px; 19 cursor: pointer; 20 transition: all .2s ease; 21 background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); 22 color: #fff !important; 23 box-shadow: 0 1px 3px rgba(37, 99, 235, .25); 24 text-shadow: none; 25 } 26 .aatb-gen:hover { 27 background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); 28 box-shadow: 0 2px 8px rgba(37, 99, 235, .35); 29 transform: translateY(-1px); 30 color: #fff !important; 31 } 32 .aatb-gen:active { 33 transform: translateY(0); 34 box-shadow: 0 1px 2px rgba(37, 99, 235, .2); 35 } 36 .aatb-gen:disabled, 37 .aatb-gen[disabled] { 38 opacity: .65; 39 cursor: wait; 40 transform: none; 41 box-shadow: none; 42 animation: aatb-pulse 1.5s ease-in-out infinite; 10 43 } 11 44 12 /*──────── LAYOUT ────────*/ 13 .aissp-wrapper{ 14 max-width:1180px; 15 margin:25px 20px 40px 0; 16 display:flex; 17 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", Arial, sans-serif; 18 font-size:17px; 19 } 20 .aissp-sidebar{ 21 width:260px; 22 background:var(--dark); 23 border-radius:8px 0 0 8px; 24 padding:26px 22px; 25 color:#fff; 26 } 27 .aissp-sidebar h2{ 28 font-size:24px; 29 margin:0 0 20px; 30 font-weight:700; 31 border-bottom:1px solid rgba(255,255,255,.15); 32 padding-bottom:14px; 33 color:#fff; 34 } 35 .aissp-sidebar nav a{ 36 display:block; 37 padding:12px 14px; 38 border-radius:6px; 39 color:#dfe6e8; 40 text-decoration:none; 41 font-size:18px; 42 margin-bottom:10px; 43 transition:background .2s; 44 } 45 .aissp-sidebar nav a.active, 46 .aissp-sidebar nav a:hover{ 47 background:#2f4d64; 48 color:var(--blue); 49 } 50 .aissp-content{ 51 flex:1; 52 background:#fff; 53 border:1px solid var(--border); 54 border-left:none; 55 border-radius:0 8px 8px 0; 56 padding:34px; 57 } 58 .aissp-content h2{ 59 margin-top:0; 60 font-size:30px; 61 font-weight:700; 62 color:var(--dark); 63 line-height:1.15; 45 /* ========== SCORE BADGES ========== */ 46 .aatb-score-badge, 47 td.aatb_score span { 48 display: inline-flex; 49 align-items: center; 50 gap: 4px; 51 font-size: 12px; 52 padding: 4px 10px; 53 color: #fff; 54 border-radius: 6px; 55 font-weight: 700; 56 letter-spacing: 0.2px; 57 line-height: 1.4; 64 58 } 65 59 66 /*──────── INPUTS / BUTTONS ────────*/ 67 .regular-text{ 68 width:100%; 69 padding:12px; 70 font-size:17px; 71 background:var(--bg); 72 border:1px solid #ccc; 73 border-radius:4px; 74 } 75 .primary-btn{ 76 background:var(--blue); 77 color:#fff!important; 78 border:none; 79 border-radius:6px; 80 padding:12px 28px; 81 font-size:18px; 82 cursor:pointer; 83 transition:background .2s,transform .05s; 84 text-decoration:none; 85 display:inline-block; 86 } 87 .primary-btn:hover{ 88 background:var(--blue-light); 89 transform:translateY(-1px); 90 color:#fff!important; 60 /* ========== LIST TABLE SCORE COLUMN ========== */ 61 .column-aatb_score { 62 width: 100px; 91 63 } 92 64 93 .token-view{ 94 display:inline-block; 95 background:#eef2f6; 96 padding:6px 12px; 97 border-radius:4px; 98 font-size:18px; 65 /* ========== ATTACHMENT EDIT SCREEN ========== */ 66 .aatb-post-wrap { 67 margin-top: 8px; 68 display: flex; 69 align-items: center; 70 gap: 10px; 71 } 72 .aatb-post-wrap button { 73 min-width: 116px; 99 74 } 100 75 101 .desc,.intro-txt,.description{ 102 font-size:17px; 103 color:#555; 104 margin-top:12px; 105 margin-bottom:0; 76 /* ========== ANIMATIONS ========== */ 77 @keyframes aatb-pulse { 78 0%, 100% { opacity: 1; } 79 50% { opacity: .6; } 106 80 } 107 .linkpad{margin-bottom:18px;}108 .need-key{margin-left:8px;color:#666;font-size:17px;}109 110 .key-row{111 display:flex;112 align-items:center;113 gap:12px;114 margin-top:12px;115 max-width:540px;116 }117 .key-row input{flex:1;}118 119 .sub-head{120 margin:18px 0 6px;121 font-size:22px;122 color:var(--blue);123 font-weight:700;124 }125 126 /*──────── USAGE BOX ────────*/127 .usage-card{128 border:1px solid var(--border);129 background:#fff;130 border-radius:6px;131 padding:20px;132 margin-top:28px;133 max-width:820px;134 }135 .usage-card h3{136 margin:0 0 14px;137 font-size:22px;138 color:var(--blue);139 font-weight:700;140 }141 .usage-table{142 width:100%;143 border-collapse:collapse;144 font-size:17px;145 }146 .usage-table th,.usage-table td{147 border:1px solid var(--border);148 padding:10px;149 text-align:left;150 }151 .bar-bg{152 background:#dbeafe;153 height:14px;154 border-radius:7px;155 overflow:hidden;156 width:100%;157 }158 .bar-fill{159 background:#3b82f6;160 height:100%;161 }162 163 /*──────── FORM ────────*/164 .form-table th{165 width:260px;166 padding:10px 0;167 font-weight:600;168 color:var(--dark);169 }170 .form-table td{padding:10px 0;}171 textarea{font-family:inherit;}172 173 /*──────── MOBILE (<991px) ────────*/174 @media (max-width:991px){175 html,body{overflow-x:hidden;}176 .aissp-wrapper{177 flex-direction:column;178 font-size:15px;179 }180 .aissp-sidebar{181 width:100%;182 border-radius:8px 8px 0 0;183 padding:20px;184 }185 .aissp-content{186 padding:24px;187 border-radius:0 0 8px 8px;188 overflow-x:hidden;189 }190 .aissp-sidebar nav a{191 font-size:17px;192 margin-bottom:6px;193 padding:11px 12px;194 }195 .primary-btn{196 width:100%;197 text-align:center;198 margin-top:12px;199 }200 .key-row{201 flex-direction:column;202 gap:10px;203 }204 .key-row input{width:100%;}205 .form-table select{206 width:100%;207 font-size:15px;208 padding:10px;209 appearance:auto;210 -webkit-appearance:menulist;211 }212 .usage-card{padding:18px;}213 .usage-table,.usage-table thead{display:none;}214 .usage-table tbody{display:block;}215 .usage-table tr{216 display:block;217 border:1px solid var(--border);218 border-radius:6px;219 margin:0 0 18px;220 background:#fff;221 }222 .usage-table td{223 display:block;224 padding:12px 14px;225 border:none;226 }227 .usage-table td::before{228 display:block;229 font-weight:600;230 color:var(--dark);231 margin-bottom:4px;232 }233 .usage-table td:nth-of-type(1)::before{content:"Website";}234 .usage-table td:nth-of-type(2)::before{content:"Usage";}235 .usage-table td:nth-of-type(3)::before{content:"Limit";}236 .usage-table td:nth-of-type(4)::before{content:"Remaining";}237 .usage-table td:nth-of-type(5)::before{content:"Progress";}238 .usage-table td:nth-of-type(6)::before{content:"Action";}239 .usage-table td:nth-of-type(5) .bar-bg{width:100%;margin-top:2px;}240 .usage-table td:nth-of-type(6) .primary-btn{241 width:100%;242 margin:6px 0 0;243 }244 .form-table,.form-table tbody,.form-table tr,245 .form-table td,.form-table th{246 display:block;width:100%;247 }248 .form-table th{margin-top:18px;}249 }250 251 /*──────── GLOBAL select arrow fix ────────*/252 .aissp-content select,.form-table select{253 appearance:none;254 -webkit-appearance:none;255 -moz-appearance:none;256 background:#f9f9f9257 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23243746'%3E%3Cpath d='M7 10l5 5 5-5'/%3E%3C/svg%3E")258 no-repeat right 14px center;259 background-size:14px 14px;260 padding-right:48px;261 }262 .form-table textarea{width:100%!important}263 .aatb-post-wrap button{min-width:116px} /* prevent button shrinking; keep alignment */ -
ai-alt-text-builder/trunk/admin/settings-page.php
r3421891 r3462124 1 1 <?php 2 2 /* AI Alt Text Builder — Settings Page (Admin) 3 * Version: 1.0. 43 * Version: 1.0.7 4 4 * ----------------------------------------------------------- 5 5 * • Two tabs: (1) Site Key Management, (2) Alt-Text Settings … … 152 152 ? 'https://rankpilotai.com/ai-alt-text-builder-pricing/' 153 153 : 'https://rankpilotai.com/tokens-1/?plugin=ai-alt-text-builder'; 154 155 $dis = empty( $token ) ? 'disabled' : ''; 154 156 ?> 155 <div class="aissp-wrapper"> 156 <aside class="aissp-sidebar"> 157 <h2>AI Alt Text Builder</h2> 158 <nav> 159 <a href="<?php echo esc_url( add_query_arg('tab','site-key',admin_url('admin.php?page=ai-alt-text-builder')) ); ?>" 160 class="<?php echo esc_attr( $tab === 'site-key' ? 'active' : '' ); ?>"><?php echo esc_html__( 'Site Key Management', 'ai-alt-text-builder' ); ?></a> 161 <a href="<?php echo esc_url( add_query_arg('tab','alt-settings',admin_url('admin.php?page=ai-alt-text-builder')) ); ?>" 162 class="<?php echo esc_attr( $tab === 'alt-settings' ? 'active' : '' ); ?>"><?php echo esc_html__( 'Alt-Text Settings', 'ai-alt-text-builder' ); ?></a> 163 </nav> 164 </aside> 165 166 <main class="aissp-content"> 157 158 <div class="aatb-settings-wrap"> 159 160 <!-- HEADER --> 161 <div class="aatb-header"> 162 <div class="aatb-header-inner"> 163 <div class="aatb-header-left"> 164 <div class="aatb-logo-icon"> 165 <img src="<?php echo esc_url( AATB_URL . 'admin/assets/img/header-logo.png' ); ?>" alt="AI Alt Text Builder" width="36" height="36"> 166 </div> 167 <div> 168 <h1 class="aatb-header-title">AI Alt Text Builder</h1> 169 <p class="aatb-header-subtitle">Media Library ALT Text Generator</p> 170 </div> 171 </div> 172 <div class="aatb-header-right"> 173 <span class="aatb-version-badge">v<?php echo esc_html( AATB_VERSION ); ?></span> 174 </div> 175 </div> 176 </div> 177 178 <!-- LAYOUT --> 179 <div class="aatb-layout"> 180 181 <!-- SIDEBAR --> 182 <aside class="aatb-sidebar"> 183 <nav class="aatb-nav"> 184 <a href="<?php echo esc_url( add_query_arg('tab','site-key',admin_url('admin.php?page=ai-alt-text-builder')) ); ?>" 185 class="aatb-nav-item <?php echo $tab==='site-key' ? 'active' : ''; ?>"> 186 <span class="aatb-nav-icon"> 187 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 188 <path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/> 189 </svg> 190 </span> 191 <span>Site Key Management</span> 192 </a> 193 <a href="<?php echo esc_url( add_query_arg('tab','alt-settings',admin_url('admin.php?page=ai-alt-text-builder')) ); ?>" 194 class="aatb-nav-item <?php echo $tab==='alt-settings' ? 'active' : ''; ?>"> 195 <span class="aatb-nav-icon"> 196 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 197 <circle cx="12" cy="12" r="3"/> 198 <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/> 199 </svg> 200 </span> 201 <span>Alt-Text Settings</span> 202 </a> 203 </nav> 204 205 <div class="aatb-sidebar-info"> 206 <p>Generate SEO-friendly ALT text for your Media Library images with one click. Supports bulk generation and multiple languages.</p> 207 <a href="https://rankpilotai.com/ai-alt-text-builder/" target="_blank" rel="noopener" class="aatb-sidebar-link"> 208 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> 209 Documentation 210 </a> 211 </div> 212 </aside> 213 214 <!-- CONTENT --> 215 <main class="aatb-content"> 216 217 <?php /* ---- TAB 1: SITE KEY ---- */ ?> 218 <?php if ( $tab === 'site-key' ) : ?> 219 220 <div class="aatb-content-header"> 221 <h2>Site Key Management</h2> 222 <p>Connect your site to RankPilotAI by entering your Site Key below.</p> 223 </div> 224 225 <?php if ( ! $token ) : ?> 226 227 <div class="aatb-card"> 228 <div class="aatb-card-header"> 229 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg> 230 <h3>Enter Your Site Key</h3> 231 </div> 232 <form method="post" class="aatb-form"> 233 <?php wp_nonce_field('aatb_save_site_key'); ?> 234 <input type="hidden" name="aatb_action" value="aatb_save_site_key"> 235 <div class="aatb-field"> 236 <label for="aatb_site_token">Site Key</label> 237 <input type="text" id="aatb_site_token" name="site_token" placeholder="rp_xxxxxxxxxxxxxxxxx" required> 238 <p class="aatb-field-hint">Generate a Site Key in your account at 239 <a href="https://rankpilotai.com" target="_blank" rel="noopener">RankPilotAI.com</a></p> 240 </div> 241 <button type="submit" class="aatb-btn aatb-btn-primary"> 242 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg> 243 Save Site Key 244 </button> 245 </form> 246 </div> 247 248 <?php else : ?> 249 250 <!-- Active Key Card --> 251 <div class="aatb-card"> 252 <div class="aatb-card-header"> 253 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg> 254 <h3>Active Site Key</h3> 255 <span class="aatb-badge aatb-badge-success">Connected</span> 256 </div> 257 <div class="aatb-token-display"> 258 <code><?php echo esc_html( $token ); ?></code> 259 </div> 260 </div> 261 262 <?php if ( $usage !== null ) : ?> 263 <!-- Usage Card --> 264 <div class="aatb-card"> 265 <div class="aatb-card-header"> 266 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-4"/></svg> 267 <h3>Usage Overview</h3> 268 </div> 269 270 <div class="aatb-usage-grid"> 271 <div class="aatb-usage-stat"> 272 <span class="aatb-usage-label">Website</span> 273 <span class="aatb-usage-value"><?php echo esc_html( parse_url( home_url(), PHP_URL_HOST ) ); ?></span> 274 </div> 275 <div class="aatb-usage-stat"> 276 <span class="aatb-usage-label">Used</span> 277 <span class="aatb-usage-value aatb-usage-number"><?php echo esc_html( number_format_i18n( (int) $usage ) ); ?></span> 278 </div> 279 <div class="aatb-usage-stat"> 280 <span class="aatb-usage-label">Plan Limit</span> 281 <span class="aatb-usage-value aatb-usage-number"><?php echo esc_html( number_format_i18n( (int) $limit ) ); ?></span> 282 </div> 283 <div class="aatb-usage-stat"> 284 <span class="aatb-usage-label">Remaining</span> 285 <span class="aatb-usage-value aatb-usage-number <?php echo (int)$remain === 0 ? 'aatb-danger' : 'aatb-success'; ?>"> 286 <?php echo esc_html( number_format_i18n( (int) $remain ) ); ?> 287 </span> 288 </div> 289 </div> 290 291 <?php 292 $pct = $limit ? round( ( ( (int) $limit - (int) $remain ) / max( 1, (int) $limit ) ) * 100 ) : 0; 293 $pct = max( 0, min( 100, (int) $pct ) ); 294 $bar_color = ( (int) $remain === 0 ) ? '#ef4444' : '#3b82f6'; 295 ?> 296 <div class="aatb-progress-wrap"> 297 <div class="aatb-progress-bar"> 298 <div class="aatb-progress-fill" style="width:<?php echo (int) $pct; ?>%;background:<?php echo esc_attr( $bar_color ); ?>;"></div> 299 </div> 300 <span class="aatb-progress-label"><?php echo (int) $pct; ?>% used</span> 301 </div> 302 303 <div class="aatb-usage-cta"> 304 <a href="<?php echo esc_url( $btn_url ); ?>" target="_blank" rel="noopener" class="aatb-btn aatb-btn-primary"> 305 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> 306 <?php echo esc_html( $btn_label ); ?> 307 </a> 308 </div> 309 </div> 310 <?php endif; ?> 311 312 <!-- Update Key Card --> 313 <div class="aatb-card"> 314 <div class="aatb-card-header"> 315 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg> 316 <h3>Update Site Key</h3> 317 </div> 318 <form method="post" class="aatb-form"> 319 <?php wp_nonce_field('aatb_save_site_key'); ?> 320 <input type="hidden" name="aatb_action" value="aatb_save_site_key"> 321 <div class="aatb-field-row"> 322 <input type="text" name="site_token" value="<?php echo esc_attr( $token ); ?>" placeholder="rp_xxxxxxxxxxxxxxxxx"> 323 <button type="submit" class="aatb-btn aatb-btn-primary">Save</button> 324 </div> 325 </form> 326 </div> 327 328 <?php endif; ?> 329 330 <?php /* ---- TAB 2: ALT-TEXT SETTINGS ---- */ ?> 331 <?php else : ?> 332 333 <div class="aatb-content-header"> 334 <h2>Alt-Text Settings</h2> 335 <p>Configure how AI Alt Text Builder generates ALT text for your images.</p> 336 </div> 337 338 <?php if ( empty( $token ) ) : ?> 339 <div class="aatb-alert aatb-alert-warning"> 340 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg> 341 <div> 342 <strong>Site Key Required</strong> 343 <p>Please enter a Site Key in the <a href="<?php echo esc_url( add_query_arg('tab','site-key',admin_url('admin.php?page=ai-alt-text-builder')) ); ?>">Site Key Management</a> tab first.</p> 344 </div> 345 </div> 346 <?php endif; ?> 347 348 <form method="post"> 349 <?php wp_nonce_field('aatb_save_alt_settings'); ?> 350 <input type="hidden" name="aatb_action" value="aatb_save_alt_settings"> 351 352 <!-- Model Selection --> 353 <div class="aatb-card"> 354 <div class="aatb-card-header"> 355 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg> 356 <h3>AI Model</h3> 357 </div> 358 359 <div class="aatb-model-grid"> 360 <label class="aatb-model-card <?php echo ($model === 'gpt-4o-mini') ? 'selected' : ''; ?>"> 361 <input type="radio" name="model_choice" value="gpt-4o-mini" 362 <?php checked( $model, 'gpt-4o-mini' ); ?> <?php echo $dis; ?>> 363 <div class="aatb-model-card-inner"> 364 <span class="aatb-model-dot" style="background:#22c55e;"></span> 365 <div class="aatb-model-info"> 366 <strong>GPT-4o-mini</strong> 367 <span class="aatb-model-tag">Economical</span> 368 </div> 369 <span class="aatb-model-cost">1 token</span> 370 </div> 371 </label> 372 373 <label class="aatb-model-card <?php echo ($model === 'gpt-4.1') ? 'selected' : ''; ?> <?php echo !in_array('gpt-4.1',$allowed_models_ui,true) ? 'disabled' : ''; ?>"> 374 <input type="radio" name="model_choice" value="gpt-4.1" 375 <?php checked( $model, 'gpt-4.1' ); ?> 376 <?php echo (!in_array('gpt-4.1',$allowed_models_ui,true) || $dis) ? 'disabled' : ''; ?>> 377 <div class="aatb-model-card-inner"> 378 <span class="aatb-model-dot" style="background:#3b82f6;"></span> 379 <div class="aatb-model-info"> 380 <strong>GPT-4.1</strong> 381 <span class="aatb-model-tag">Balanced</span> 382 </div> 383 <span class="aatb-model-cost">3 tokens</span> 384 </div> 385 </label> 386 387 <label class="aatb-model-card <?php echo ($model === 'gpt-4o') ? 'selected' : ''; ?> <?php echo !in_array('gpt-4o',$allowed_models_ui,true) ? 'disabled' : ''; ?>"> 388 <input type="radio" name="model_choice" value="gpt-4o" 389 <?php checked( $model, 'gpt-4o' ); ?> 390 <?php echo (!in_array('gpt-4o',$allowed_models_ui,true) || $dis) ? 'disabled' : ''; ?>> 391 <div class="aatb-model-card-inner"> 392 <span class="aatb-model-dot" style="background:#a855f7;"></span> 393 <div class="aatb-model-info"> 394 <strong>GPT-4o</strong> 395 <span class="aatb-model-tag">Premium</span> 396 </div> 397 <span class="aatb-model-cost">5 tokens</span> 398 </div> 399 </label> 400 </div> 401 402 <p class="aatb-card-hint">All models support vision (image analysis). Some models may be unavailable on your current plan.</p> 403 </div> 404 405 <!-- Language Selection --> 406 <div class="aatb-card"> 407 <div class="aatb-card-header"> 408 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg> 409 <h3>Alt-Text Language</h3> 410 </div> 411 412 <div class="aatb-field"> 413 <select id="lang_choice" name="lang_choice" <?php echo $dis; ?>> 414 <option value="en" <?php selected($lang,'en'); ?>>English</option> 415 <option value="de" <?php selected($lang,'de'); ?>>Deutsch</option> 416 <option value="fr" <?php selected($lang,'fr'); ?>>Français</option> 417 <option value="es" <?php selected($lang,'es'); ?>>Español</option> 418 <option value="tr" <?php selected($lang,'tr'); ?>>Türkçe</option> 419 <option value="other" <?php if( ! in_array($lang,['en','de','fr','es','tr'],true) ) echo 'selected'; ?>> 420 Other / Custom 421 </option> 422 </select> 423 <input type="text" id="lang_custom" name="lang_custom" 424 placeholder="e.g. Italian, Dutch, Arabic" 425 value="<?php echo esc_attr( ! in_array($lang,['en','de','fr','es','tr'],true) ? $lang : '' ); ?>" 426 style="margin-top:8px;<?php echo in_array($lang,['en','de','fr','es','tr'],true) ? 'display:none;' : ''; ?>"> 427 <p class="aatb-field-hint">Select "Other / Custom" and type the language exactly as you'd like it.</p> 428 </div> 429 </div> 430 431 <!-- Custom Prompt --> 432 <div class="aatb-card"> 433 <div class="aatb-card-header"> 434 <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> 435 <h3>Custom Prompt</h3> 436 </div> 437 438 <div class="aatb-field"> 439 <textarea id="custom_prompt" name="custom_prompt" rows="4" 440 placeholder="e.g. Always mention the brand name first..." <?php echo $dis; ?>><?php 441 echo esc_textarea( $opt['custom_prompt'] ?? '' ); ?></textarea> 442 <p class="aatb-field-hint"> 443 Optional. Add brand or style guidance. Your note is appended to the built-in instructions 444 and takes priority over general rules; the 125-character limit always applies. 445 Leave blank to use defaults. 446 </p> 447 </div> 448 </div> 449 450 <!-- Save Button --> 451 <div class="aatb-form-actions"> 452 <button type="submit" class="aatb-btn aatb-btn-primary aatb-btn-lg" <?php echo $dis; ?>> 453 <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg> 454 <?php echo empty( $token ) ? 'Save (needs Site Key)' : 'Save Changes'; ?> 455 </button> 456 </div> 457 </form> 458 459 <?php endif; ?> 460 461 </main> 462 </div> 463 </div> 464 465 <!-- ========================================================= 466 SETTINGS PAGE CSS 467 ========================================================= --> 468 <style> 469 /* ========== RESET & BASE ========== */ 470 .aatb-settings-wrap{ 471 max-width:1200px; 472 margin:0 20px 40px 0; 473 font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Helvetica Neue",Arial,sans-serif; 474 font-size:14px; 475 color:#1e293b; 476 line-height:1.6; 477 } 478 .aatb-settings-wrap *{box-sizing:border-box;} 479 480 /* ========== HEADER ========== */ 481 .aatb-header{ 482 background:linear-gradient(135deg,#0f172a 0%,#1e3a5f 50%,#1e40af 100%); 483 border-radius:12px 12px 0 0; 484 padding:0; 485 margin-top:20px; 486 } 487 .aatb-header-inner{ 488 display:flex; 489 align-items:center; 490 justify-content:space-between; 491 padding:24px 32px; 492 } 493 .aatb-header-left{display:flex;align-items:center;gap:16px;} 494 .aatb-logo-icon{ 495 width:48px;height:48px; 496 background:rgba(255,255,255,.12); 497 border-radius:12px; 498 display:flex;align-items:center;justify-content:center; 499 color:#fff; 500 flex-shrink:0; 501 } 502 .aatb-logo-icon img{border-radius:6px;} 503 .aatb-header-title{ 504 font-size:22px;font-weight:700;color:#fff;margin:0;line-height:1.2; 505 } 506 .aatb-header-subtitle{ 507 font-size:13px;color:rgba(255,255,255,.65);margin:2px 0 0; 508 } 509 .aatb-version-badge{ 510 background:rgba(255,255,255,.15); 511 color:rgba(255,255,255,.85); 512 padding:4px 12px; 513 border-radius:20px; 514 font-size:12px; 515 font-weight:600; 516 } 517 518 /* ========== LAYOUT ========== */ 519 .aatb-layout{ 520 display:flex; 521 background:#f8fafc; 522 border:1px solid #e2e8f0; 523 border-top:none; 524 border-radius:0 0 12px 12px; 525 min-height:500px; 526 } 527 528 /* ========== SIDEBAR ========== */ 529 .aatb-sidebar{ 530 width:280px; 531 background:#fff; 532 border-right:1px solid #e2e8f0; 533 border-radius:0 0 0 12px; 534 padding:24px 16px; 535 display:flex; 536 flex-direction:column; 537 flex-shrink:0; 538 } 539 .aatb-nav{display:flex;flex-direction:column;gap:4px;} 540 .aatb-nav-item{ 541 display:flex;align-items:center;gap:12px; 542 padding:12px 16px; 543 border-radius:8px; 544 color:#475569; 545 text-decoration:none; 546 font-size:14px; 547 font-weight:500; 548 transition:all .15s ease; 549 } 550 .aatb-nav-item:hover{background:#f1f5f9;color:#1e293b;} 551 .aatb-nav-item.active{ 552 background:linear-gradient(135deg,#eff6ff,#dbeafe); 553 color:#1d4ed8; 554 font-weight:600; 555 box-shadow:0 0 0 1px rgba(59,130,246,.2); 556 } 557 .aatb-nav-icon{display:flex;align-items:center;flex-shrink:0;} 558 559 .aatb-sidebar-info{ 560 margin-top:auto; 561 padding:16px; 562 background:#f8fafc; 563 border-radius:8px; 564 border:1px solid #e2e8f0; 565 } 566 .aatb-sidebar-info p{ 567 font-size:12px;color:#64748b;margin:0 0 12px;line-height:1.5; 568 } 569 .aatb-sidebar-link{ 570 display:inline-flex;align-items:center;gap:6px; 571 font-size:12px;color:#3b82f6;text-decoration:none;font-weight:500; 572 } 573 .aatb-sidebar-link:hover{color:#1d4ed8;text-decoration:underline;} 574 575 /* ========== CONTENT ========== */ 576 .aatb-content{ 577 flex:1; 578 padding:32px; 579 min-width:0; 580 } 581 .aatb-content-header{margin-bottom:28px;} 582 .aatb-content-header h2{ 583 font-size:22px;font-weight:700;color:#0f172a;margin:0 0 6px; 584 } 585 .aatb-content-header p{ 586 font-size:14px;color:#64748b;margin:0; 587 } 588 589 /* ========== CARDS ========== */ 590 .aatb-card{ 591 background:#fff; 592 border:1px solid #e2e8f0; 593 border-radius:10px; 594 padding:24px; 595 margin-bottom:20px; 596 transition:box-shadow .2s ease; 597 } 598 .aatb-card:hover{box-shadow:0 1px 8px rgba(0,0,0,.04);} 599 .aatb-card-header{ 600 display:flex; 601 align-items:center; 602 gap:10px; 603 margin-bottom:20px; 604 padding-bottom:16px; 605 border-bottom:1px solid #f1f5f9; 606 color:#334155; 607 } 608 .aatb-card-header h3{ 609 font-size:16px;font-weight:600;margin:0;color:#0f172a;flex:1; 610 } 611 .aatb-card-hint{ 612 font-size:12px;color:#94a3b8;margin:16px 0 0;line-height:1.5; 613 } 614 .aatb-card-hint code{ 615 background:#f1f5f9;padding:1px 6px;border-radius:3px;font-size:11px; 616 } 617 618 /* ========== BADGES ========== */ 619 .aatb-badge{ 620 padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600;letter-spacing:.3px;text-transform:uppercase; 621 } 622 .aatb-badge-success{background:#dcfce7;color:#16a34a;} 623 624 /* ========== FORMS ========== */ 625 .aatb-form{display:flex;flex-direction:column;gap:20px;} 626 .aatb-field{display:flex;flex-direction:column;gap:6px;} 627 .aatb-field label{font-size:13px;font-weight:600;color:#334155;} 628 .aatb-field input[type="text"], 629 .aatb-field textarea, 630 .aatb-field select{ 631 width:100%; 632 padding:10px 14px; 633 font-size:14px; 634 border:1px solid #cbd5e1; 635 border-radius:8px; 636 background:#fff; 637 color:#1e293b; 638 transition:border-color .15s ease,box-shadow .15s ease; 639 font-family:inherit; 640 } 641 .aatb-field input[type="text"]:focus, 642 .aatb-field textarea:focus, 643 .aatb-field select:focus{ 644 outline:none; 645 border-color:#3b82f6; 646 box-shadow:0 0 0 3px rgba(59,130,246,.12); 647 } 648 .aatb-field textarea{resize:vertical;min-height:100px;} 649 .aatb-field select{ 650 appearance:none; 651 -webkit-appearance:none; 652 -moz-appearance:none; 653 background:#fff 654 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23334155'%3E%3Cpath d='M7 10l5 5 5-5'/%3E%3C/svg%3E") 655 no-repeat right 12px center; 656 background-size:14px 14px; 657 padding-right:40px; 658 } 659 .aatb-field-hint{ 660 font-size:12px;color:#94a3b8;margin:0;line-height:1.5; 661 } 662 .aatb-field-hint a{color:#3b82f6;text-decoration:none;} 663 .aatb-field-hint a:hover{text-decoration:underline;} 664 665 .aatb-field-row{ 666 display:flex;gap:10px;align-items:center; 667 } 668 .aatb-field-row input[type="text"]{ 669 flex:1; 670 padding:10px 14px; 671 font-size:14px; 672 border:1px solid #cbd5e1; 673 border-radius:8px; 674 background:#fff; 675 color:#1e293b; 676 transition:border-color .15s ease,box-shadow .15s ease; 677 } 678 .aatb-field-row input[type="text"]:focus{ 679 outline:none; 680 border-color:#3b82f6; 681 box-shadow:0 0 0 3px rgba(59,130,246,.12); 682 } 683 684 /* ========== BUTTONS ========== */ 685 .aatb-btn{ 686 display:inline-flex;align-items:center;justify-content:center;gap:8px; 687 padding:10px 20px; 688 font-size:14px;font-weight:600; 689 border:none;border-radius:8px; 690 cursor:pointer; 691 text-decoration:none; 692 transition:all .15s ease; 693 line-height:1.4; 694 } 695 .aatb-btn-primary{ 696 background:linear-gradient(135deg,#2563eb,#1d4ed8); 697 color:#fff !important; 698 box-shadow:0 1px 3px rgba(37,99,235,.3); 699 } 700 .aatb-btn-primary:hover{ 701 background:linear-gradient(135deg,#3b82f6,#2563eb); 702 box-shadow:0 2px 8px rgba(37,99,235,.35); 703 transform:translateY(-1px); 704 color:#fff !important; 705 } 706 .aatb-btn-primary:active{transform:translateY(0);} 707 .aatb-btn-primary:disabled,.aatb-btn-primary[disabled]{ 708 opacity:.5;cursor:not-allowed;transform:none; 709 } 710 .aatb-btn-lg{padding:12px 28px;font-size:15px;} 711 712 /* ========== TOKEN DISPLAY ========== */ 713 .aatb-token-display{ 714 background:#f8fafc; 715 border:1px solid #e2e8f0; 716 border-radius:8px; 717 padding:12px 16px; 718 } 719 .aatb-token-display code{ 720 font-size:14px;color:#334155;background:none; 721 word-break:break-all; 722 } 723 724 /* ========== USAGE ========== */ 725 .aatb-usage-grid{ 726 display:grid; 727 grid-template-columns:repeat(4,1fr); 728 gap:16px; 729 margin-bottom:20px; 730 } 731 .aatb-usage-stat{ 732 background:#f8fafc; 733 border:1px solid #e2e8f0; 734 border-radius:8px; 735 padding:14px 16px; 736 text-align:center; 737 } 738 .aatb-usage-label{ 739 display:block;font-size:11px;font-weight:600; 740 color:#94a3b8;text-transform:uppercase;letter-spacing:.5px; 741 margin-bottom:6px; 742 } 743 .aatb-usage-value{ 744 display:block;font-size:14px;font-weight:700;color:#0f172a; 745 word-break:break-all; 746 } 747 .aatb-usage-number{font-size:20px;} 748 .aatb-usage-value.aatb-danger{color:#ef4444;} 749 .aatb-usage-value.aatb-success{color:#22c55e;} 750 751 .aatb-progress-wrap{ 752 display:flex;align-items:center;gap:12px; 753 margin-bottom:20px; 754 } 755 .aatb-progress-bar{ 756 flex:1;height:10px; 757 background:#e2e8f0;border-radius:10px; 758 overflow:hidden; 759 } 760 .aatb-progress-fill{ 761 height:100%;border-radius:10px; 762 transition:width .6s ease; 763 } 764 .aatb-progress-label{ 765 font-size:12px;font-weight:600;color:#64748b; 766 white-space:nowrap; 767 } 768 .aatb-usage-cta{padding-top:4px;} 769 770 /* ========== MODEL CARDS ========== */ 771 .aatb-model-grid{ 772 display:grid; 773 grid-template-columns:repeat(3,1fr); 774 gap:12px; 775 } 776 .aatb-model-card{ 777 position:relative; 778 border:2px solid #e2e8f0; 779 border-radius:10px; 780 padding:16px; 781 cursor:pointer; 782 transition:all .15s ease; 783 background:#fff; 784 } 785 .aatb-model-card:hover:not(.disabled){ 786 border-color:#93c5fd; 787 background:#f8fafc; 788 } 789 .aatb-model-card.selected{ 790 border-color:#3b82f6; 791 background:linear-gradient(135deg,#eff6ff,#dbeafe); 792 box-shadow:0 0 0 1px rgba(59,130,246,.2); 793 } 794 .aatb-model-card.disabled{ 795 opacity:.45;cursor:not-allowed;pointer-events:none; 796 } 797 .aatb-model-card input[type="radio"]{ 798 position:absolute;opacity:0;width:0;height:0;pointer-events:none; 799 } 800 .aatb-model-card-inner{ 801 display:flex; 802 align-items:center; 803 gap:10px; 804 } 805 .aatb-model-dot{ 806 width:10px;height:10px; 807 border-radius:50%; 808 flex-shrink:0; 809 } 810 .aatb-model-info{ 811 flex:1;min-width:0; 812 } 813 .aatb-model-info strong{ 814 display:block;font-size:14px;color:#0f172a; 815 } 816 .aatb-model-tag{ 817 font-size:11px;color:#64748b; 818 } 819 .aatb-model-cost{ 820 font-size:12px;font-weight:600; 821 color:#3b82f6; 822 white-space:nowrap; 823 background:#eff6ff; 824 padding:3px 8px; 825 border-radius:6px; 826 } 827 828 /* ========== ALERT ========== */ 829 .aatb-alert{ 830 display:flex;align-items:flex-start;gap:12px; 831 padding:16px 20px; 832 border-radius:10px; 833 margin-bottom:24px; 834 } 835 .aatb-alert svg{flex-shrink:0;margin-top:2px;} 836 .aatb-alert strong{display:block;margin-bottom:4px;} 837 .aatb-alert p{margin:0;font-size:13px;} 838 .aatb-alert a{color:inherit;text-decoration:underline;} 839 .aatb-alert-warning{ 840 background:#fef3c7;border:1px solid #fde68a;color:#92400e; 841 } 842 .aatb-alert-warning svg{color:#f59e0b;} 843 844 /* ========== FORM ACTIONS ========== */ 845 .aatb-form-actions{ 846 padding-top:8px; 847 } 848 849 /* ========== RESPONSIVE ========== */ 850 @media (max-width:900px){ 851 .aatb-settings-wrap{margin:0 10px 30px 0;} 852 .aatb-header-inner{padding:20px 24px;} 853 .aatb-layout{flex-direction:column;border-radius:0 0 12px 12px;} 854 .aatb-sidebar{ 855 width:100%; 856 border-right:none; 857 border-bottom:1px solid #e2e8f0; 858 border-radius:0; 859 padding:20px 16px; 860 } 861 .aatb-nav{flex-direction:row;gap:8px;} 862 .aatb-nav-item{font-size:13px;padding:10px 14px;} 863 .aatb-sidebar-info{display:none;} 864 .aatb-content{padding:24px 20px;} 865 866 .aatb-usage-grid{grid-template-columns:repeat(2,1fr);} 867 .aatb-model-grid{grid-template-columns:1fr;} 868 .aatb-field-row{flex-direction:column;} 869 .aatb-field-row input[type="text"]{width:100%;} 870 .aatb-btn{width:100%;justify-content:center;} 871 } 872 873 @media (max-width:480px){ 874 .aatb-header-inner{flex-direction:column;align-items:flex-start;gap:12px;} 875 .aatb-header-right{align-self:flex-end;} 876 .aatb-usage-grid{grid-template-columns:1fr 1fr;} 877 .aatb-nav{flex-direction:column;} 878 } 879 </style> 880 <script> 881 (function(){ 882 var cards = document.querySelectorAll('.aatb-model-card'); 883 cards.forEach(function(card){ 884 var radio = card.querySelector('input[type="radio"]'); 885 if(!radio) return; 886 card.addEventListener('click', function(e){ 887 if(card.classList.contains('disabled')) return; 888 if(radio.disabled) return; 889 cards.forEach(function(c){ c.classList.remove('selected'); }); 890 card.classList.add('selected'); 891 radio.checked = true; 892 }); 893 }); 894 })(); 895 </script> 167 896 <?php 168 /* ───────────────────────────────────────── 169 * TAB 1 — SITE KEY 170 * ─────────────────────────────────────────*/ 171 if ( $tab === 'site-key' ) : ?> 172 173 <h2><?php echo esc_html__( 'RankPilotAI: Site Key Management', 'ai-alt-text-builder' ); ?></h2> 174 175 <?php if ( ! $token ) : ?> 176 <p class="intro-txt">Enter your Site Key below to get started.</p> 177 <form method="post" class="aissp-form"> 178 <?php wp_nonce_field('aatb_save_site_key'); ?> 179 <input type="hidden" name="aatb_action" value="aatb_save_site_key"> 180 <input type="text" name="site_token" class="regular-text" placeholder="rp_xxxxxxxxxxxxxxxxx" required> 181 <p class="desc linkpad">Generate your Site Key on 182 <a href="https://rankpilotai.com" target="_blank" rel="noopener">RankPilotAI.com</a></p> 183 <button class="primary-btn">Save Site Key</button> 184 </form> 185 186 <?php else : ?> 187 <p><strong>Your Active Site Key</strong></p> 188 <code class="token-view"><?php echo esc_html( $token ); ?></code> 189 190 <?php if ( $limit !== null ) : ?> 191 <div class="usage-card"> 192 <h3>Usage Overview</h3> 193 <table class="usage-table"><thead><tr> 194 <th>This Site</th> 195 <th>Usage</th> 196 <th>Plan Limit</th> 197 <th>Remaining</th> 198 <th>Progress</th> 199 <th></th> 200 </tr></thead><tbody><tr> 201 <td><?php echo esc_html( parse_url( home_url(), PHP_URL_HOST ) ); ?></td> 202 <td><?php echo esc_html( number_format_i18n( (int) $usage ) ); ?></td> 203 <td><?php echo esc_html( number_format_i18n( (int) $limit ) ); ?></td> 204 <td><?php echo esc_html( number_format_i18n( (int) $remain ) ); ?></td> 205 <td> 206 <?php 207 $pct = $limit ? round( ( ( (int) $limit - (int) $remain ) / max( 1, (int) $limit ) ) * 100 ) : 0; 208 $pct = max( 0, min( 100, (int) $pct ) ); 209 $bar = ( (int) $remain === 0 ) ? '#dc3232' : '#3b82f6'; 210 $style = sprintf( 211 'width:%d%%;background:%s', 212 $pct, 213 $bar 214 ); 215 ?> 216 <div class="bar-bg"> 217 <div class="bar-fill" style="<?php echo esc_attr( $style ); ?>"></div> 218 </div> 219 </td> 220 <td> 221 <a href="<?php echo esc_url( $btn_url ); ?>" target="_blank" class="primary-btn"> 222 <?php echo esc_html( $btn_label ); ?> 223 </a> 224 </td> 225 </tr></tbody></table> 226 </div> 227 <?php endif; ?> 228 229 <form method="post" class="aissp-form" style="margin-top:26px;"> 230 <?php wp_nonce_field('aatb_save_site_key'); ?> 231 <input type="hidden" name="aatb_action" value="aatb_save_site_key"> 232 <h3 class="sub-head">Update / Change Site Key</h3> 233 <div class="key-row"> 234 <input type="text" name="site_token" value="<?php echo esc_attr( $token ); ?>" class="regular-text"> 235 <button class="primary-btn">Save</button> 236 </div> 237 </form> 238 <?php endif; ?> 239 240 <?php 241 /* ───────────────────────────────────────── 242 * TAB 2 — ALT-TEXT SETTINGS 243 * ─────────────────────────────────────────*/ 244 else : ?> 245 246 <h2><?php echo esc_html__( 'Alt-Text Settings', 'ai-alt-text-builder' ); ?></h2> 247 248 <form method="post" class="aissp-form-wide"> 249 <?php wp_nonce_field('aatb_save_alt_settings'); ?> 250 <input type="hidden" name="aatb_action" value="aatb_save_alt_settings"> 251 <table class="form-table"> 252 253 <tr> 254 <th><label for="model_choice"><?php echo esc_html__( 'GPT Model', 'ai-alt-text-builder' ); ?></label></th> 255 <td> 256 <select id="model_choice" name="model_choice" <?php echo empty($token)?'disabled':''; ?>> 257 <option value="gpt-4o-mini" <?php selected($model,'gpt-4o-mini'); ?>> 258 <?php echo esc_html__( '🟢 Economical (gpt-4o-mini) - 1 token / alt-text', 'ai-alt-text-builder' ); ?> 259 </option> 260 <option value="gpt-4.1" <?php selected($model,'gpt-4.1'); ?> 261 <?php echo in_array('gpt-4.1',$allowed_models_ui,true)?'':'disabled'; ?>> 262 <?php echo esc_html__( '🔵 Balanced (gpt-4.1) - 3 tokens / alt-text', 'ai-alt-text-builder' ); ?> 263 </option> 264 <option value="gpt-4o" <?php selected($model,'gpt-4o'); ?> 265 <?php echo in_array('gpt-4o',$allowed_models_ui,true)?'':'disabled'; ?>> 266 <?php echo esc_html__( '🟣 Premium (gpt-4o) - 5 tokens / alt-text', 'ai-alt-text-builder' ); ?> 267 </option> 268 </select> 269 </td> 270 </tr> 271 272 <tr> 273 <th><label for="lang_choice"><?php echo esc_html__( 'Alt-Text Language', 'ai-alt-text-builder' ); ?></label></th> 274 <td> 275 <select id="lang_choice" name="lang_choice"> 276 <option value="en" <?php selected($lang,'en'); ?>>English</option> 277 <option value="de" <?php selected($lang,'de'); ?>>Deutsch</option> 278 <option value="fr" <?php selected($lang,'fr'); ?>>Français</option> 279 <option value="es" <?php selected($lang,'es'); ?>>Español</option> 280 <option value="tr" <?php selected($lang,'tr'); ?>>Türkçe</option> 281 <option value="other" <?php if( ! in_array($lang,['en','de','fr','es','tr'],true) ) echo 'selected'; ?>> 282 Other / Custom 283 </option> 284 </select> 285 <input type="text" id="lang_custom" name="lang_custom" 286 placeholder="e.g. Italian, Dutch, Arabic" 287 value="<?php echo esc_attr( ! in_array($lang,['en','de','fr','es','tr'],true) ? $lang : '' ); ?>" 288 style="margin-top:8px;<?php echo in_array($lang,['en','de','fr','es','tr'],true) ? 'display:none;' : ''; ?>"> 289 <p class="desc">Select “Other / Custom” and type the language exactly as you’d like it.</p> 290 </td> 291 </tr> 292 293 <tr> 294 <th><label for="custom_prompt"><?php echo esc_html__( 'Custom Prompt', 'ai-alt-text-builder' ); ?></label></th> 295 <td> 296 <textarea id="custom_prompt" name="custom_prompt" rows="3" class="regular-text" style="width:420px;"><?php 297 echo esc_textarea( $opt['custom_prompt'] ?? '' ); 298 ?></textarea> 299 <p class="description" style="margin-top:6px;"> 300 Optional. Add brand or style guidance. Your note is appended to the built-in instructions 301 and takes priority over general rules; the 125-character limit always applies. 302 Leave blank to use defaults. 303 </p> 304 </td> 305 </tr> 306 307 </table> 308 309 <p> 310 <button type="submit" class="primary-btn" <?php echo empty($token)?'disabled':''; ?>> 311 Save Changes 312 </button> 313 <?php if (empty($token)) : ?><span class="need-key">← enter a Site Key first</span><?php endif; ?> 314 </p> 315 </form> 316 317 <?php endif; ?> 318 </main> 319 </div> 320 <?php } 897 } -
ai-alt-text-builder/trunk/ai-alt-text-builder.php
r3441081 r3462124 3 3 Plugin Name: AI Alt Text Builder 4 4 Description: Generate SEO-friendly ALT text for Media Library images in one click, with scoring, bulk generation and language options. 5 Version: 1.0. 65 Version: 1.0.7 6 6 Author: RankPilotAI 7 7 Author URI: https://rankpilotai.com … … 16 16 if ( ! defined( 'ABSPATH' ) ) exit; 17 17 18 define( 'AATB_VERSION', '1.0. 6' );18 define( 'AATB_VERSION', '1.0.7' ); 19 19 define( 'AATB_PATH', plugin_dir_path( __FILE__ ) ); 20 20 define( 'AATB_URL', plugin_dir_url ( __FILE__ ) ); -
ai-alt-text-builder/trunk/readme.txt
r3441081 r3462124 5 5 Tested up to: 6.9 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 67 Stable tag: 1.0.7 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 79 79 == Changelog == 80 80 81 = 1.0.7 = 82 * UI: Redesigned settings page with modern card-based layout, gradient header, improved navigation and responsive design. 83 * UI: Settings header now displays the official AI Alt Text Builder logo. 84 * UI: Modernized admin CSS for generate button and score badges. 85 81 86 = 1.0.6 = 82 87 * Maintenance: minor version consistency updates and small documentation/copy cleanup. No functional changes.
Note: See TracChangeset
for help on using the changeset viewer.