mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
fix(ui): remove stale dashboard footer gap
This commit is contained in:
@@ -55,7 +55,7 @@ export function AccountsPage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="h-[calc(100vh-100px)] hidden lg:flex">
|
||||
<div className="hidden h-full min-h-0 lg:flex">
|
||||
{/* Left action column */}
|
||||
<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">
|
||||
|
||||
@@ -206,7 +206,7 @@ export function ApiPage() {
|
||||
};
|
||||
|
||||
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)} />
|
||||
<div className="flex-1 flex min-h-0">
|
||||
<div className="w-80 border-r flex flex-col bg-muted/30">
|
||||
|
||||
@@ -405,7 +405,7 @@ export function ClaudeExtensionPage() {
|
||||
}
|
||||
|
||||
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="border-b bg-background p-4">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
|
||||
@@ -1462,7 +1462,7 @@ export function CliproxyAiProvidersPage() {
|
||||
|
||||
if (isLoading) {
|
||||
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 flex-1 rounded-none" />
|
||||
</div>
|
||||
@@ -1476,7 +1476,7 @@ export function CliproxyAiProvidersPage() {
|
||||
: 'Failed to load CLIProxy AI providers. Check the local server and try again.';
|
||||
|
||||
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="flex items-start gap-4">
|
||||
<div className="flex h-11 w-11 items-center justify-center rounded-lg bg-destructive/10">
|
||||
@@ -1549,7 +1549,7 @@ export function CliproxyAiProvidersPage() {
|
||||
</div>
|
||||
);
|
||||
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="border-b bg-background p-4">
|
||||
<div className="mb-1 flex items-center justify-between">
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ControlPanelEmbed } from '@/components/cliproxy/control-panel-embed';
|
||||
|
||||
export function CliproxyControlPanelPage() {
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)] flex flex-col">
|
||||
<div className="flex h-full min-h-0 flex-col overflow-hidden">
|
||||
<ControlPanelEmbed />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -338,7 +338,7 @@ export function CliproxyPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)] flex">
|
||||
<div className="flex h-full min-h-0 overflow-hidden">
|
||||
{/* Left Sidebar */}
|
||||
<div className="w-80 border-r flex flex-col bg-muted/30">
|
||||
{/* Header */}
|
||||
|
||||
@@ -116,7 +116,7 @@ export function CopilotPage() {
|
||||
} = useCopilot();
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)] flex">
|
||||
<div className="flex h-full min-h-0 overflow-hidden">
|
||||
{/* Left Sidebar - Status Overview */}
|
||||
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
|
||||
{/* Header */}
|
||||
|
||||
@@ -633,7 +633,7 @@ export function CursorPage() {
|
||||
|
||||
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="p-4 border-b bg-background">
|
||||
<div className="flex items-center justify-between mb-1">
|
||||
|
||||
@@ -694,7 +694,7 @@ export function DroidPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)] overflow-hidden">
|
||||
<div className="h-full min-h-0 overflow-hidden">
|
||||
<PanelGroup direction="horizontal" className="h-full">
|
||||
<Panel defaultSize={45} minSize={35}>
|
||||
<div className="h-full border-r bg-muted/20">{renderOverview()}</div>
|
||||
|
||||
@@ -121,7 +121,7 @@ function SettingsPageInner() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-[calc(100vh-100px)]">
|
||||
<div className="h-full min-h-0">
|
||||
{/* Mobile View - Stacked vertically */}
|
||||
<div className="md:hidden h-full flex flex-col">
|
||||
<div className="border-b bg-background p-4">
|
||||
|
||||
@@ -102,7 +102,7 @@ export function UpdatesPage() {
|
||||
);
|
||||
|
||||
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="p-4 border-b bg-background space-y-3">
|
||||
<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