mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(atlas): visual empty stats state
This commit is contained in:
@@ -10,6 +10,10 @@ import MDancingTrek, { type TrekScene, type TrekMood } from '../../mobile/compon
|
||||
* so we map them onto the desktop palette here. Its `.trek-*` choreography is
|
||||
* global CSS, so it animates outside the shell as-is. `surface` should match the
|
||||
* background the state sits on so the cut-out eyes read as holes (default: card).
|
||||
*
|
||||
* `layout="row"` puts the mascot beside the title with tight padding, for short
|
||||
* content-sized panels (the Atlas glass pill) where the stacked look towers over
|
||||
* the sibling states.
|
||||
*/
|
||||
export default function EmptyState({
|
||||
scene = 'idle',
|
||||
@@ -17,6 +21,7 @@ export default function EmptyState({
|
||||
title,
|
||||
size = 104,
|
||||
surface = 'var(--bg-card)',
|
||||
layout = 'stack',
|
||||
className = '',
|
||||
action,
|
||||
}: {
|
||||
@@ -25,13 +30,17 @@ export default function EmptyState({
|
||||
title: string
|
||||
size?: number
|
||||
surface?: string
|
||||
layout?: 'stack' | 'row'
|
||||
className?: string
|
||||
/** Optional call to action under the title, for states that have an obvious next step. */
|
||||
action?: ReactNode
|
||||
}) {
|
||||
const layoutClasses = layout === 'row'
|
||||
? 'flex flex-row items-center justify-center gap-3 px-6 py-3'
|
||||
: 'flex flex-col items-center justify-center gap-3 px-6 py-12 text-center'
|
||||
return (
|
||||
<div
|
||||
className={`flex flex-col items-center justify-center gap-3 px-6 py-12 text-center ${className}`}
|
||||
className={`${layoutClasses} ${className}`}
|
||||
style={{ '--m-ink': 'var(--text-primary)', '--m-bg': surface } as CSSProperties}
|
||||
>
|
||||
<MDancingTrek scene={scene} mood={mood} size={size} />
|
||||
|
||||
@@ -525,7 +525,7 @@ function SidebarContent({ data, stats, countries, selectedCountry, countryDetail
|
||||
return (
|
||||
<>
|
||||
{tabBar}
|
||||
<EmptyState scene="atlas" title={t('atlas.noData')} />
|
||||
<EmptyState scene="atlas" title={t('atlas.noData')} layout="row" size={52} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
+4
-3
@@ -181,9 +181,10 @@ Ordered by value:
|
||||
'write' }` appears ~100+ times across `.mcp.ts` files as free strings. A typo'd group
|
||||
never matches a real scope: scoped tokens get denied (fail closed) but `scopes: null`
|
||||
sessions pass (fail open) — silent scope-model drift either way. Mechanism: derive a
|
||||
`ScopeGroup` union from `SCOPES` and type the decorator's `access.group` against it via
|
||||
the same `declare module '@trek/nest-mcp'` augmentation already used for `McpContext`
|
||||
(keeps nest-mcp extraction-clean); plus a **boot gate in the MCP registry**: at discovery
|
||||
`ScopeGroup` union from `SCOPES` and type the decorator's `access.group` against it
|
||||
(originally a `declare module '@trek/nest-mcp'` augmentation; since the 2026-08-22 fold
|
||||
the registries live directly in `server/src/nest-mcp/types.ts`); plus a **boot gate in
|
||||
the MCP registry**: at discovery
|
||||
time, refuse to boot on an `access.group`/tool-name/`when` combination that doesn't
|
||||
resolve against `SCOPES` — the body-contract ratchet pattern applied to the MCP surface.
|
||||
The registry the user-facing scopes UI reads (`SCOPE_INFO`) then serves decorators, the
|
||||
|
||||
Reference in New Issue
Block a user