mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-12 18:15:48 +00:00
fix(ui): remove stale dashboard footer gap
This commit is contained in:
1 parent
8e90404774
commit
0d59c7a3af
12 files changed
+51
-13
No files matched your search
@@ -55,7 +55,7 @@ export function AccountsPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="h-[calc(100vh-100px)] hidden lg:flex">
|
<div className="hidden h-full min-h-0 lg:flex">
|
||||||
{/* Left action column */}
|
{/* Left action column */}
|
||||||
<div className="w-80 border-r flex flex-col bg-muted/20 shrink-0">
|
<div className="w-80 border-r flex flex-col bg-muted/20 shrink-0">
|
||||||
<div className="p-4 border-b bg-background space-y-2">
|
<div className="p-4 border-b bg-background space-y-2">
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ export function ApiPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] flex flex-col">
|
<div className="flex h-full min-h-0 flex-col overflow-hidden">
|
||||||
<OpenRouterBanner onCreateClick={() => setCreateDialogOpen(true)} />
|
<OpenRouterBanner onCreateClick={() => setCreateDialogOpen(true)} />
|
||||||
<div className="flex-1 flex min-h-0">
|
<div className="flex-1 flex min-h-0">
|
||||||
<div className="w-80 border-r flex flex-col bg-muted/30">
|
<div className="w-80 border-r flex flex-col bg-muted/30">
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ export function ClaudeExtensionPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-[calc(100vh-100px)] min-h-0">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
<div className="flex w-[348px] shrink-0 flex-col border-r bg-muted/30 xl:w-[372px]">
|
<div className="flex w-[348px] shrink-0 flex-col border-r bg-muted/30 xl:w-[372px]">
|
||||||
<div className="border-b bg-background p-4">
|
<div className="border-b bg-background p-4">
|
||||||
<div className="flex items-start justify-between gap-3">
|
<div className="flex items-start justify-between gap-3">
|
||||||
|
|||||||
@@ -1462,7 +1462,7 @@ export function CliproxyAiProvidersPage() {
|
|||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-[calc(100vh-100px)] min-h-0">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
<Skeleton className="h-full w-80 rounded-none" />
|
<Skeleton className="h-full w-80 rounded-none" />
|
||||||
<Skeleton className="h-full flex-1 rounded-none" />
|
<Skeleton className="h-full flex-1 rounded-none" />
|
||||||
</div>
|
</div>
|
||||||
@@ -1476,7 +1476,7 @@ export function CliproxyAiProvidersPage() {
|
|||||||
: 'Failed to load CLIProxy AI providers. Check the local server and try again.';
|
: 'Failed to load CLIProxy AI providers. Check the local server and try again.';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-[calc(100vh-100px)] min-h-0 items-center justify-center bg-muted/10 p-6">
|
<div className="flex h-full min-h-0 items-center justify-center bg-muted/10 p-6">
|
||||||
<div className="w-full max-w-2xl rounded-xl border bg-card p-6 shadow-sm">
|
<div className="w-full max-w-2xl rounded-xl border bg-card p-6 shadow-sm">
|
||||||
<div className="flex items-start gap-4">
|
<div className="flex items-start gap-4">
|
||||||
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-destructive/10">
|
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-destructive/10">
|
||||||
@@ -1549,7 +1549,7 @@ export function CliproxyAiProvidersPage() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div className="flex h-[calc(100vh-100px)] min-h-0">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
<div className="flex w-80 flex-col border-r bg-muted/30">
|
<div className="flex w-80 flex-col border-r bg-muted/30">
|
||||||
<div className="border-b bg-background p-4">
|
<div className="border-b bg-background p-4">
|
||||||
<div className="mb-1 flex items-center justify-between">
|
<div className="mb-1 flex items-center justify-between">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { ControlPanelEmbed } from '@/components/cliproxy/control-panel-embed';
|
|||||||
|
|
||||||
export function CliproxyControlPanelPage() {
|
export function CliproxyControlPanelPage() {
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] flex flex-col">
|
<div className="flex h-full min-h-0 flex-col overflow-hidden">
|
||||||
<ControlPanelEmbed />
|
<ControlPanelEmbed />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ export function CliproxyPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] flex">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
{/* Left Sidebar */}
|
{/* Left Sidebar */}
|
||||||
<div className="w-80 border-r flex flex-col bg-muted/30">
|
<div className="w-80 border-r flex flex-col bg-muted/30">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export function CopilotPage() {
|
|||||||
} = useCopilot();
|
} = useCopilot();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] flex">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
{/* Left Sidebar - Status Overview */}
|
{/* Left Sidebar - Status Overview */}
|
||||||
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
|
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ export function CursorPage() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="h-[calc(100vh-100px)] flex">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
|
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
|
||||||
<div className="p-4 border-b bg-background">
|
<div className="p-4 border-b bg-background">
|
||||||
<div className="flex items-center justify-between mb-1">
|
<div className="flex items-center justify-between mb-1">
|
||||||
|
|||||||
@@ -694,7 +694,7 @@ export function DroidPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] overflow-hidden">
|
<div className="h-full min-h-0 overflow-hidden">
|
||||||
<PanelGroup direction="horizontal" className="h-full">
|
<PanelGroup direction="horizontal" className="h-full">
|
||||||
<Panel defaultSize={45} minSize={35}>
|
<Panel defaultSize={45} minSize={35}>
|
||||||
<div className="h-full border-r bg-muted/20">{renderOverview()}</div>
|
<div className="h-full border-r bg-muted/20">{renderOverview()}</div>
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ function SettingsPageInner() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)]">
|
<div className="h-full min-h-0">
|
||||||
{/* Mobile View - Stacked vertically */}
|
{/* Mobile View - Stacked vertically */}
|
||||||
<div className="md:hidden h-full flex flex-col">
|
<div className="md:hidden h-full flex flex-col">
|
||||||
<div className="border-b bg-background p-4">
|
<div className="border-b bg-background p-4">
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export function UpdatesPage() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-[calc(100vh-100px)] flex overflow-hidden">
|
<div className="flex h-full min-h-0 overflow-hidden">
|
||||||
<div className="w-80 border-r bg-muted/30 flex flex-col overflow-hidden">
|
<div className="w-80 border-r bg-muted/30 flex flex-col overflow-hidden">
|
||||||
<div className="p-4 border-b bg-background space-y-3">
|
<div className="p-4 border-b bg-background space-y-3">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
const testDir = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
const projectRoot = path.resolve(testDir, '../../../../');
|
||||||
|
|
||||||
|
const layoutManagedRouteFiles = [
|
||||||
|
'src/pages/index.tsx',
|
||||||
|
'src/pages/analytics/index.tsx',
|
||||||
|
'src/pages/updates.tsx',
|
||||||
|
'src/pages/api.tsx',
|
||||||
|
'src/pages/cliproxy.tsx',
|
||||||
|
'src/pages/cliproxy-ai-providers.tsx',
|
||||||
|
'src/pages/cliproxy-control-panel.tsx',
|
||||||
|
'src/pages/copilot.tsx',
|
||||||
|
'src/pages/cursor.tsx',
|
||||||
|
'src/pages/claude-extension.tsx',
|
||||||
|
'src/pages/droid.tsx',
|
||||||
|
'src/pages/accounts.tsx',
|
||||||
|
'src/pages/settings/index.tsx',
|
||||||
|
'src/pages/health.tsx',
|
||||||
|
'src/pages/shared.tsx',
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const forbiddenViewportHeightPattern = /\b(?:h-screen|min-h-screen)\b|calc\(100(?:d|l|s)?vh/i;
|
||||||
|
|
||||||
|
describe('dashboard route height contract', () => {
|
||||||
|
it.each(layoutManagedRouteFiles)(
|
||||||
|
'%s relies on the shared layout for viewport height',
|
||||||
|
(relativePath) => {
|
||||||
|
const source = readFileSync(path.join(projectRoot, relativePath), 'utf8');
|
||||||
|
|
||||||
|
expect(source).not.toMatch(forbiddenViewportHeightPattern);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user