feat(quota): optimize quota lookup list layout
This commit is contained in:
1 parent
eab80af225
commit
3c5114ebbb
2 files changed
+75
-1
No files matched your search
@@ -21,3 +21,71 @@
|
||||
line-height: 1.4;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
/* Dense account list inspired by the quota overview reference. */
|
||||
.quota-page .quota-group-list { gap: 14px; }
|
||||
.quota-page .quota-table-head {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(220px, 1.35fr) minmax(100px, .65fr) minmax(110px, .7fr) minmax(280px, 2fr) minmax(112px, .7fr);
|
||||
align-items: center;
|
||||
gap: 18px;
|
||||
padding: 0 18px 6px;
|
||||
color: var(--theme-7a746c);
|
||||
font-size: var(--font-size-meta);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
}
|
||||
.quota-page .quota-provider-group { gap: 7px; }
|
||||
.quota-page .quota-group-heading { min-height: 24px; padding: 0 3px; }
|
||||
.quota-page .quota-group-heading h2 { font-size: var(--font-size-label); color: var(--theme-7a746c); }
|
||||
.quota-page .quota-group-heading .provider-logo { width: 18px; height: 18px; }
|
||||
.quota-page .quota-provider-count { padding: 2px 7px; font-size: 11px; }
|
||||
.quota-page .real-quota-grid { display: grid; gap: 8px; }
|
||||
.quota-page .real-quota-card {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(220px, 1.35fr) minmax(100px, .65fr) minmax(110px, .7fr) minmax(280px, 2fr) minmax(112px, .7fr);
|
||||
align-items: center;
|
||||
gap: 14px 18px;
|
||||
min-height: 104px;
|
||||
padding: 14px 18px;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 9px;
|
||||
background: var(--bg-card);
|
||||
box-shadow: 0 1px 2px rgb(40 45 55 / 3%);
|
||||
}
|
||||
.quota-page .real-quota-card:hover { border-color: #b7c9ed; box-shadow: 0 3px 12px rgb(55 95 180 / 8%); }
|
||||
.quota-page .real-quota-card-header { display: contents; }
|
||||
.quota-page .quota-identity { display: flex; align-items: center; gap: 10px; min-width: 0; }
|
||||
.quota-page .quota-identity > div { display: grid; gap: 4px; min-width: 0; }
|
||||
.quota-page .quota-account-icon { width: 30px; height: 30px; flex: 0 0 auto; }
|
||||
.quota-page .real-quota-card-header strong { color: var(--theme-2d2a26); font-size: var(--font-size-body); }
|
||||
.quota-page .real-quota-card-header span { font-size: var(--font-size-meta); }
|
||||
.quota-page .quota-plan, .quota-page .quota-status { display: grid; gap: 4px; min-width: 0; }
|
||||
.quota-page .quota-plan strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.quota-page .quota-plan span, .quota-page .quota-status small { color: var(--theme-7a746c); font-size: var(--font-size-meta); }
|
||||
.quota-page .quota-status-badge { width: fit-content; padding: 3px 8px; border-radius: 6px; background: var(--theme-f4f1ea); color: var(--theme-7a746c); font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); }
|
||||
.quota-page .quota-status-badge.ready { background: #e8f8ee; color: #149447; }
|
||||
.quota-page .quota-status-badge.error { background: #fff0ee; color: #d94b42; }
|
||||
.quota-page .quota-row-list { grid-column: 4; gap: 9px; min-width: 0; }
|
||||
.quota-page .real-quota-row { gap: 5px; }
|
||||
.quota-page .real-quota-row > div:first-child { font-size: var(--font-size-meta); }
|
||||
.quota-page .real-quota-track { height: 7px; background: #edf0f4; }
|
||||
.quota-page .real-quota-track span { background: #20bf62; }
|
||||
.quota-page .real-quota-row small { font-size: 11px; }
|
||||
.quota-page .quota-card-actions { grid-column: 5; grid-row: 1; justify-content: flex-end; align-self: center; flex-wrap: wrap; }
|
||||
.quota-page .quota-card-actions .icon-button { width: 30px; height: 30px; border-radius: 7px; background: #eef4ff; color: #347df4; }
|
||||
.quota-page .quota-card-message, .quota-page .quota-card-error, .quota-page .quota-action-feedback, .quota-page .quota-reset-credit-summary { grid-column: 1 / -1; }
|
||||
.quota-page .quota-card-message { min-height: 36px; }
|
||||
.quota-page .quota-card-error { min-height: 36px; }
|
||||
|
||||
@media (max-width: 980px) {
|
||||
.quota-page .quota-table-head { display: none; }
|
||||
.quota-page .real-quota-card { grid-template-columns: minmax(180px, 1fr) minmax(100px, .7fr) minmax(100px, .7fr) 38px; }
|
||||
.quota-page .quota-row-list { grid-column: 1 / -1; }
|
||||
.quota-page .quota-card-actions { grid-column: 4; }
|
||||
}
|
||||
@media (max-width: 640px) {
|
||||
.quota-page .real-quota-card { grid-template-columns: 1fr auto; padding: 13px; }
|
||||
.quota-page .quota-plan, .quota-page .quota-status { grid-column: 1 / -1; }
|
||||
.quota-page .quota-card-actions { grid-column: 2; grid-row: 1; }
|
||||
.quota-page .quota-row-list { grid-column: 1 / -1; }
|
||||
}
|
||||
@@ -166,6 +166,7 @@ export function QuotaPage() {
|
||||
<div className="management-empty"><AlertCircle size={24} /><strong>{t('quota.empty.title')}</strong><span>{t('quota.empty.description')}</span></div>
|
||||
) : (
|
||||
<div className="quota-group-list">
|
||||
<div className="quota-table-head" aria-hidden="true"><span>{t('authFiles.list.credential')}</span><span>{t('authFiles.list.plan')}</span><span>{t('authFiles.list.status')}</span><span>{t('authFiles.list.quota')}</span><span>{t('authFiles.list.actions')}</span></div>
|
||||
{grouped.map(([provider, items]) => (
|
||||
<section className="quota-provider-group" key={provider}>
|
||||
<div className="quota-group-heading">
|
||||
@@ -193,7 +194,12 @@ export function QuotaCard({ file, quota, onRefresh, onReset }: { file: AuthFile;
|
||||
return (
|
||||
<article className="panel real-quota-card">
|
||||
<div className="real-quota-card-header">
|
||||
<div><strong title={name}>{name}</strong><span>{provider ? providerMeta[provider].label : t('quota.unknownProvider')}{quota.plan ? ' · ' + quota.plan : ''}</span></div>
|
||||
<div className="quota-identity">
|
||||
<img src={provider ? providerMeta[provider].icon : ''} alt="" className="quota-account-icon" />
|
||||
<div><strong title={name}>{name}</strong><span>{provider ? providerMeta[provider].label : t('quota.unknownProvider')}</span></div>
|
||||
</div>
|
||||
<div className="quota-plan"><strong>{quota.plan || '—'}</strong><span>{quota.subscriptionActiveUntil ? formatQuotaTimestamp(quota.subscriptionActiveUntil, locale) : ''}</span></div>
|
||||
<div className="quota-status"><span className={quota.status === 'success' ? 'quota-status-badge ready' : quota.status === 'error' ? 'quota-status-badge error' : 'quota-status-badge'}>{quota.status === 'success' ? t('common.enabled') : quota.status === 'loading' ? t('quota.querying') : quota.status === 'error' ? t('common.unavailable') : t('quota.notFetched')}</span><small>{t('authFiles.settings.priority')} 0</small></div>
|
||||
<div className="quota-card-actions">
|
||||
{onReset && (quota.resetCredits ?? 0) > 0 ? <button type="button" className="secondary-button compact-button" onClick={onReset} disabled={!canResetCodexQuota(file, quota)} title={t('quota.reset')}>{t('quota.reset')}</button> : null}
|
||||
<button type="button" className="icon-button quiet" onClick={onRefresh} disabled={disabled || quota.status === 'loading'} title={disabled ? t('quota.fileDisabled') : t('quota.refresh')} aria-label={disabled ? t('quota.fileDisabled') : t('quota.refresh')}><RefreshCw size={16} className={quota.status === 'loading' ? 'spin' : ''} aria-hidden="true" /></button>
|
||||
|
||||
Reference in new issue
Block a user