mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 14:36:31 +00:00
feat(settings,admin): every tab and popup in the planner's design
This commit is contained in:
@@ -2,6 +2,9 @@ import { useEffect, useState } from 'react'
|
||||
import { History, RefreshCw } from 'lucide-react'
|
||||
import { pluginsApi } from '../../api/client'
|
||||
import { useTranslation } from '../../i18n'
|
||||
import { Tooltip } from '../shared/Tooltip'
|
||||
import { fs } from '../shared/DialogShell'
|
||||
import { SettingsCard, SettingsHint, SETTINGS_ICON_BUTTON } from './settingsKit'
|
||||
|
||||
interface ActivityRow {
|
||||
ts: string
|
||||
@@ -23,6 +26,9 @@ function codeTone(code: string): string {
|
||||
return 'bg-warning-soft text-warning'
|
||||
}
|
||||
|
||||
const TH = 'whitespace-nowrap px-3 py-2.5 text-left font-geist font-bold uppercase tracking-[.08em] text-content-faint'
|
||||
const TD = 'px-3 py-3 align-middle'
|
||||
|
||||
/**
|
||||
* The signed-in user's own plugin activity log — every host-mediated action a
|
||||
* plugin took while bound to them, newest first. The user-facing half of the
|
||||
@@ -50,54 +56,52 @@ export default function PluginActivityPanel() {
|
||||
return Number.isNaN(d.getTime()) ? ts : d.toLocaleString(locale)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-edge bg-surface-card overflow-hidden">
|
||||
<div className="px-5 py-4 border-b border-edge-secondary flex items-center gap-3">
|
||||
<History className="w-4 h-4 flex-shrink-0 text-content-secondary" />
|
||||
<div className="flex-1 min-w-0">
|
||||
<h3 className="text-sm font-semibold text-content">{t('settings.pluginActivity.title')}</h3>
|
||||
<p className="text-xs text-content-muted mt-0.5">{t('settings.pluginActivity.description')}</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={load}
|
||||
disabled={loading}
|
||||
className="inline-flex items-center gap-1.5 rounded-lg border border-edge px-2.5 py-1.5 text-xs font-medium text-content-secondary hover:text-content disabled:opacity-60"
|
||||
>
|
||||
<RefreshCw className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`} />
|
||||
{t('settings.pluginActivity.refresh')}
|
||||
</button>
|
||||
</div>
|
||||
const refreshLabel = t('settings.pluginActivity.refresh')
|
||||
|
||||
return (
|
||||
<SettingsCard
|
||||
icon={History}
|
||||
title={t('settings.pluginActivity.title')}
|
||||
hint={t('settings.pluginActivity.description')}
|
||||
action={
|
||||
<Tooltip label={refreshLabel}>
|
||||
<button type="button" onClick={load} disabled={loading} aria-label={refreshLabel} className={SETTINGS_ICON_BUTTON}>
|
||||
<RefreshCw size={14} className={loading ? 'animate-spin' : undefined} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
{rows.length === 0 ? (
|
||||
<p className="px-5 py-6 text-sm text-content-muted">
|
||||
<SettingsHint>
|
||||
{loading ? t('common.loading') : t('settings.pluginActivity.empty')}
|
||||
</p>
|
||||
</SettingsHint>
|
||||
) : (
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm border-collapse">
|
||||
<div className={`overflow-x-auto rounded-[12px] border border-edge-faint bg-surface-card ${loading ? 'opacity-60' : ''}`}>
|
||||
<table className="w-full border-collapse" style={fs(12.5, 'body')}>
|
||||
<thead>
|
||||
<tr className="text-left text-xs uppercase tracking-wide text-content-faint border-b border-edge-secondary">
|
||||
<th className="font-medium px-5 py-2">{t('settings.pluginActivity.columns.plugin')}</th>
|
||||
<th className="font-medium px-3 py-2">{t('settings.pluginActivity.columns.action')}</th>
|
||||
<th className="font-medium px-3 py-2">{t('settings.pluginActivity.columns.resource')}</th>
|
||||
<th className="font-medium px-3 py-2 whitespace-nowrap">{t('settings.pluginActivity.columns.when')}</th>
|
||||
<th className="font-medium px-5 py-2 text-right">{t('settings.pluginActivity.columns.status')}</th>
|
||||
<tr className="border-b border-edge-faint bg-surface-secondary" style={fs(10)}>
|
||||
<th className={`${TH} pl-3.5`}>{t('settings.pluginActivity.columns.plugin')}</th>
|
||||
<th className={TH}>{t('settings.pluginActivity.columns.action')}</th>
|
||||
<th className={TH}>{t('settings.pluginActivity.columns.resource')}</th>
|
||||
<th className={TH}>{t('settings.pluginActivity.columns.when')}</th>
|
||||
<th className={`${TH} pr-3.5 text-right`}>{t('settings.pluginActivity.columns.status')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody className="divide-y divide-edge-faint">
|
||||
{rows.map((r, i) => (
|
||||
<tr key={i} className="border-b border-edge-secondary last:border-b-0">
|
||||
<td className="px-5 py-2.5 text-content align-top">{r.plugin_name || r.plugin_id}</td>
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="font-mono text-xs text-content-secondary">{r.method}</span>
|
||||
<tr key={i}>
|
||||
<td className={`${TD} max-w-[200px] pl-3.5`}>
|
||||
<span className="block truncate font-medium text-content">{r.plugin_name || r.plugin_id}</span>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 align-top">
|
||||
<span className="font-mono text-xs text-content-muted">{r.resource || '—'}</span>
|
||||
<td className={TD}>
|
||||
<span className="font-mono text-content-secondary" style={fs(11.5)}>{r.method}</span>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 align-top whitespace-nowrap text-content-muted">{fmtWhen(r.ts)}</td>
|
||||
<td className="px-5 py-2.5 align-top text-right">
|
||||
<span className={`inline-block rounded-full px-2 py-0.5 text-[11px] font-medium ${codeTone(r.code)}`}>
|
||||
<td className={`${TD} max-w-[220px]`}>
|
||||
<span className="block truncate font-mono text-content-muted" style={fs(11.5)} title={r.resource || undefined}>{r.resource || '—'}</span>
|
||||
</td>
|
||||
<td className={`${TD} whitespace-nowrap font-geist tabular-nums text-content-muted`}>{fmtWhen(r.ts)}</td>
|
||||
<td className={`${TD} pr-3.5 text-right`}>
|
||||
<span className={`inline-block whitespace-nowrap rounded-full px-2 py-[2px] font-geist font-semibold ${codeTone(r.code)}`} style={fs(11)}>
|
||||
{r.code}
|
||||
</span>
|
||||
</td>
|
||||
@@ -107,6 +111,6 @@ export default function PluginActivityPanel() {
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</SettingsCard>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user