fix: v1.5.1 — 美化账号添加/编辑弹窗
- 头部:加紫色渐变圆形头像(首字母=用户名首字符)+ 标题+副标题 - 字段布局:标签/输入/提示文字分层堆叠,视觉更清晰 - GitHub 用户名(只读):从 input 改为带虚线边框的信息块, 「账号标识 · 不可修改」标签 + 等宽字体值 - Personal Access Token:上方单独显示「当前 Token」小行(绿点=已配/橙点=未配), 下方输入框改为「粘贴新 Token 以替换(留空不修改)」更清晰 - 私有复选框:独立一行整行可点(hover 反馈) - 输入框:1.5px 边框 + 浅灰底 + 紫色聚焦环,悬停加深边框 - 底部按钮:自定义「取消」(白底灰边)和「保存修改」/「验证并添加」 (紫渐变带阴影+hover 上移),布局更平衡 - 弹窗整体:更圆角、加 backdrop 模糊、进入动画更柔和 - 移动端(窄屏)适配:弹窗圆角和内边距自动收紧 - manifest 1.5.0 → 1.5.1
This commit is contained in:
@@ -959,25 +959,53 @@ h2 .h2sub{font-size:12px;font-weight:400;color:#8a919e;margin-left:10px}
|
||||
input[readonly]{background:#f6f8fa;color:#646a73;cursor:not-allowed}
|
||||
.b-icon{padding:5px 9px;min-width:auto;font-size:13px}
|
||||
/* ---------- 模态弹窗 ---------- */
|
||||
.modal{display:none;position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:1000;align-items:center;justify-content:center;padding:20px}
|
||||
.modal{display:none;position:fixed;inset:0;background:rgba(15,23,42,.5);z-index:1000;align-items:center;justify-content:center;padding:24px;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
|
||||
.modal.show{display:flex}
|
||||
.modal-box{background:#fff;border-radius:14px;width:100%;max-width:480px;box-shadow:0 20px 60px rgba(0,0,0,.25);max-height:90vh;overflow:auto;animation:modalIn .15s ease-out}
|
||||
@keyframes modalIn{from{transform:translateY(-8px);opacity:.6}to{transform:translateY(0);opacity:1}}
|
||||
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 22px;border-bottom:1px solid #eef0f3}
|
||||
.modal-head h3{font-size:17px;margin:0}
|
||||
.modal-close{background:none;border:none;font-size:24px;color:#646a73;cursor:pointer;padding:2px 10px;border-radius:6px;line-height:1}
|
||||
.modal-box{background:#fff;border-radius:16px;width:100%;max-width:520px;box-shadow:0 25px 70px rgba(15,23,42,.35),0 0 0 1px rgba(15,23,42,.04);max-height:90vh;overflow:auto;animation:modalIn .18s ease-out}
|
||||
@keyframes modalIn{from{transform:translateY(-12px) scale(.98);opacity:.5}to{transform:translateY(0) scale(1);opacity:1}}
|
||||
.modal-head{display:flex;align-items:center;gap:14px;padding:20px 24px;border-bottom:1px solid #f0f2f5}
|
||||
.modal-avatar{width:42px;height:42px;border-radius:50%;background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:700;flex:none;box-shadow:0 4px 10px rgba(124,58,237,.25)}
|
||||
.modal-head .titles{flex:1;min-width:0}
|
||||
.modal-head h3{font-size:17px;font-weight:700;color:#1f2329;margin:0;line-height:1.3}
|
||||
.modal-head .subtitle{font-size:12px;color:#8a919e;margin-top:2px;line-height:1.4}
|
||||
.modal-close{background:none;border:none;font-size:22px;color:#8a919e;cursor:pointer;padding:6px 10px;border-radius:8px;line-height:1;flex:none;transition:all .15s}
|
||||
.modal-close:hover{background:#f0f2f5;color:#1f2329}
|
||||
.modal-body{padding:22px;display:flex;flex-direction:column;gap:8px}
|
||||
.modal-body{padding:22px 24px;display:flex;flex-direction:column;gap:18px}
|
||||
.modal-field{display:flex;flex-direction:column;gap:6px}
|
||||
.modal-field label.mfl{font-size:13px;font-weight:600;color:#374151;display:flex;align-items:center;gap:6px}
|
||||
.modal-field .mfhint{font-size:12px;color:#8a919e;line-height:1.5;margin-top:-2px}
|
||||
.modal-body input[type=text],.modal-body input[type=password]{
|
||||
border:1px solid #d0d5dd;border-radius:10px;padding:11px 14px;font-size:14px;outline:none;width:100%;box-sizing:border-box;font-family:inherit}
|
||||
.modal-body input:focus{border-color:#7c3aed}
|
||||
.modal-foot{padding:14px 22px;border-top:1px solid #eef0f3;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||||
.modal-msg{font-size:13px;flex:1;min-width:0;word-break:break-word}
|
||||
border:1.5px solid #e5e8ec;border-radius:10px;padding:10px 14px;font-size:14px;outline:none;width:100%;box-sizing:border-box;font-family:inherit;background:#fafbfc;color:#1f2329;transition:all .15s}
|
||||
.modal-body input[type=text]:hover,.modal-body input[type=password]:hover{border-color:#c7cdd4;background:#fff}
|
||||
.modal-body input[type=text]:focus,.modal-body input[type=password]:focus{border-color:#7c3aed;background:#fff;box-shadow:0 0 0 3px rgba(124,58,237,.12)}
|
||||
.modal-body input[readonly]{background:#f4f5f7;color:#374151;cursor:default;border-style:dashed}
|
||||
.modal-body input[readonly]:hover{background:#f4f5f7;border-color:#e5e8ec}
|
||||
.mf-info{display:flex;align-items:center;gap:10px;padding:10px 14px;background:#f4f5f7;border:1.5px dashed #e0e3e8;border-radius:10px;color:#374151;font-size:14px}
|
||||
.mf-info .mfi-label{font-size:12px;color:#8a919e;font-weight:500;flex:none}
|
||||
.mf-info .mfi-value{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;word-break:break-all}
|
||||
.mf-token-current{display:flex;align-items:center;gap:8px;padding:8px 12px;background:#f4f5f7;border-radius:8px;font-size:12px;color:#646a73;margin-top:-2px}
|
||||
.mf-token-current code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:#374151}
|
||||
.mf-token-current .dot{width:6px;height:6px;border-radius:50%;background:#0a7d34;flex:none}
|
||||
.mf-token-current.none .dot{background:#b45309}
|
||||
.mf-token-current.none code{color:#b45309}
|
||||
.mf-token-current .none{color:#b45309;font-weight:500}
|
||||
.mf-row{display:flex;align-items:center;gap:8px;padding:10px 14px;background:#f4f5f7;border-radius:10px;cursor:pointer;transition:background .15s;min-height:42px}
|
||||
.mf-row:hover{background:#ebedf0}
|
||||
.mf-row input[type=checkbox]{width:18px;height:18px;flex:none}
|
||||
.modal-foot{padding:16px 24px;border-top:1px solid #f0f2f5;display:flex;align-items:center;gap:12px;background:#fafbfc;border-radius:0 0 16px 16px}
|
||||
.modal-foot .modal-msg{margin:0}
|
||||
.modal-foot .btn-cancel{background:#fff;border:1.5px solid #e5e8ec;color:#646a73;border-radius:10px;padding:10px 20px;font-size:14px;font-weight:600;cursor:pointer;transition:all .15s}
|
||||
.modal-foot .btn-cancel:hover{background:#f4f5f7;border-color:#c7cdd4;color:#1f2329}
|
||||
.modal-foot .btn-save{background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;border:none;border-radius:10px;padding:10px 24px;font-size:14px;font-weight:600;cursor:pointer;transition:all .15s;box-shadow:0 4px 12px rgba(124,58,237,.25);min-width:120px}
|
||||
.modal-foot .btn-save:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 6px 16px rgba(124,58,237,.35)}
|
||||
.modal-foot .btn-save:disabled{opacity:.6;cursor:not-allowed}
|
||||
.modal-msg{font-size:13px;flex:1;min-width:0;word-break:break-word;line-height:1.5}
|
||||
.modal-msg.ok{color:#0a7d34}
|
||||
.modal-msg.err{color:#b91c1c}
|
||||
.modal-msg:empty{display:none}
|
||||
@media (max-width:760px){
|
||||
.modal-box{max-width:none}
|
||||
.modal-box{max-width:none;border-radius:14px}
|
||||
.modal-head,.modal-body,.modal-foot{padding-left:18px;padding-right:18px}
|
||||
}
|
||||
table.hover tbody tr:hover{background:#f8fafc}
|
||||
td.ops{white-space:nowrap}
|
||||
@@ -1410,9 +1438,14 @@ function openEditModal(id, focusToken){
|
||||
if(!acc)return;
|
||||
document.getElementById('modalEdit').dataset.id=id;
|
||||
document.getElementById('editLabel').value=acc.label||'';
|
||||
document.getElementById('editUser').value=acc.gh_user||'';
|
||||
document.getElementById('editUser').textContent=acc.gh_user||'';
|
||||
document.getElementById('editAvatar').textContent=(acc.gh_user||'?').charAt(0).toUpperCase();
|
||||
// 当前 Token 显示块
|
||||
const tcur=document.getElementById('editTokenCurrent');
|
||||
const ttxt=document.getElementById('editTokenText');
|
||||
if(acc.token){ ttxt.textContent=acc.token; tcur.classList.remove('none'); }
|
||||
else { ttxt.textContent='(未配置 Token)'; tcur.classList.add('none'); }
|
||||
document.getElementById('editToken').value='';
|
||||
document.getElementById('editToken').placeholder=acc.token?'当前:'+acc.token:'(未配置)';
|
||||
document.getElementById('editPrivate').checked=!!acc.private;
|
||||
showModalMsg('editMsg','',null);
|
||||
document.getElementById('modalEdit').classList.add('show');
|
||||
@@ -1456,7 +1489,7 @@ async function saveEdit(){
|
||||
showModalMsg('editMsg', r.msg||'', !!r.ok);
|
||||
if(r.ok){ setTimeout(()=>{ closeModal('modalEdit'); refresh(); }, 700); }
|
||||
}catch(e){ showModalMsg('editMsg','请求失败: '+e, false); }
|
||||
finally{ b.disabled=false; b.textContent='保存'; }
|
||||
finally{ b.disabled=false; b.textContent='保存修改'; }
|
||||
}
|
||||
async function switchAcc(id){
|
||||
const r=await (await fetch('api/accounts/switch',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({id})})).json();
|
||||
@@ -1499,22 +1532,36 @@ refresh();
|
||||
<div class="modal" id="modalAdd">
|
||||
<div class="modal-box">
|
||||
<div class="modal-head">
|
||||
<h3>添加 GitHub 账号</h3>
|
||||
<div class="modal-avatar">+</div>
|
||||
<div class="titles">
|
||||
<h3>添加 GitHub 账号</h3>
|
||||
<div class="subtitle">用 Personal Access Token 验证后即可推送</div>
|
||||
</div>
|
||||
<button class="modal-close" onclick="closeModal('modalAdd')" aria-label="关闭">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label class="flabel" style="margin-top:0">备注名<span class="sub">方便自己识别,可留空</span></label>
|
||||
<input id="addLabel" placeholder="如:我的主账号" autocomplete="off">
|
||||
<label class="flabel">GitHub 用户名<span class="sub">留空则按 Token 自动识别</span></label>
|
||||
<input id="addUser" placeholder="如 cbb2625274797" autocomplete="off">
|
||||
<label class="flabel">Personal Access Token</label>
|
||||
<input id="addToken" type="password" placeholder="ghp_ 开头" autocomplete="off">
|
||||
<label class="chk" style="margin-top:8px"><input type="checkbox" id="addPrivate" checked> 自动创建的仓库设为私有(推荐)</label>
|
||||
<div class="modal-field">
|
||||
<label class="mfl" for="addLabel">备注名</label>
|
||||
<input id="addLabel" placeholder="如:我的主账号" autocomplete="off">
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<label class="mfl" for="addUser">GitHub 用户名</label>
|
||||
<input id="addUser" placeholder="如 cbb2625274797" autocomplete="off">
|
||||
<div class="mfhint">留空则按 Token 自动识别</div>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<label class="mfl" for="addToken">Personal Access Token</label>
|
||||
<input id="addToken" type="password" placeholder="ghp_ 开头" autocomplete="off">
|
||||
<div class="mfhint">需 <code>repo</code> 权限(即可自动创建仓库并推送)</div>
|
||||
</div>
|
||||
<div class="mf-row">
|
||||
<label class="chk" style="flex:1;cursor:pointer"><input type="checkbox" id="addPrivate" checked> 自动创建的仓库设为 <b>私有</b>(推荐)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<div class="modal-msg" id="addMsg"></div>
|
||||
<button class="b-mini" onclick="closeModal('modalAdd')">取消</button>
|
||||
<button class="b-add" id="btnAddSave" onclick="saveAdd()">✓ 验证并添加</button>
|
||||
<button class="btn-cancel" onclick="closeModal('modalAdd')">取消</button>
|
||||
<button class="btn-save" id="btnAddSave" onclick="saveAdd()">✓ 验证并添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1523,22 +1570,42 @@ refresh();
|
||||
<div class="modal" id="modalEdit">
|
||||
<div class="modal-box">
|
||||
<div class="modal-head">
|
||||
<h3>编辑 GitHub 账号</h3>
|
||||
<div class="modal-avatar" id="editAvatar">E</div>
|
||||
<div class="titles">
|
||||
<h3>编辑 GitHub 账号</h3>
|
||||
<div class="subtitle" id="editSubtitle">修改备注、私有仓库设置,或更换 Token</div>
|
||||
</div>
|
||||
<button class="modal-close" onclick="closeModal('modalEdit')" aria-label="关闭">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label class="flabel" style="margin-top:0">备注名</label>
|
||||
<input id="editLabel" autocomplete="off">
|
||||
<label class="flabel">GitHub 用户名<span class="sub">账号标识,不可修改</span></label>
|
||||
<input id="editUser" readonly tabindex="-1">
|
||||
<label class="flabel">Personal Access Token<span class="sub">留空则保留当前 Token</span></label>
|
||||
<input id="editToken" type="password" placeholder="ghp_ 开头(留空不修改)" autocomplete="off">
|
||||
<label class="chk" style="margin-top:8px"><input type="checkbox" id="editPrivate"> 自动创建的仓库设为私有(推荐)</label>
|
||||
<div class="modal-field">
|
||||
<label class="mfl" for="editLabel">备注名</label>
|
||||
<input id="editLabel" autocomplete="off">
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<label class="mfl">GitHub 用户名</label>
|
||||
<div class="mf-info">
|
||||
<span class="mfi-label">账号标识 · 不可修改</span>
|
||||
<span class="mfi-value" id="editUser">—</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<label class="mfl" for="editToken">Personal Access Token</label>
|
||||
<div class="mf-token-current" id="editTokenCurrent">
|
||||
<span class="dot"></span>
|
||||
<span>当前 Token:<code id="editTokenText">—</code></span>
|
||||
</div>
|
||||
<input id="editToken" type="password" placeholder="粘贴新 Token 以替换(留空则不修改)" autocomplete="off">
|
||||
<div class="mfhint">留空则保留当前 Token</div>
|
||||
</div>
|
||||
<div class="mf-row">
|
||||
<label class="chk" style="flex:1;cursor:pointer"><input type="checkbox" id="editPrivate"> 自动创建的仓库设为 <b>私有</b>(推荐)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<div class="modal-msg" id="editMsg"></div>
|
||||
<button class="b-mini" onclick="closeModal('modalEdit')">取消</button>
|
||||
<button class="b-add" id="btnEditSave" onclick="saveEdit()">保存</button>
|
||||
<button class="btn-cancel" onclick="closeModal('modalEdit')">取消</button>
|
||||
<button class="btn-save" id="btnEditSave" onclick="saveEdit()">保存修改</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user