Skip to content

Commit c0708f6

Browse files
committed
Add sticky footer
1 parent da1fd57 commit c0708f6

4 files changed

Lines changed: 230 additions & 213 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useTranslation } from "react-i18next";
2+
import { Card, CardContent } from "@/components/ui/card";
3+
4+
interface FooterProps {
5+
className?: string;
6+
}
7+
8+
export function Footer({ className }: FooterProps) {
9+
const { t } = useTranslation();
10+
11+
return (
12+
<Card className={className}>
13+
<CardContent>
14+
<div className="text-center space-y-2">
15+
<h3 className="font-semibold">{t("settings.footer.title")}</h3>
16+
<p className="text-sm text-muted-foreground">
17+
{t("settings.footer.description")}
18+
</p>
19+
</div>
20+
</CardContent>
21+
</Card>
22+
);
23+
}

packages/web/src/i18n/en.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,7 @@
286286
},
287287
"footer": {
288288
"title": "Shelly Manager",
289-
"description": "A modern web interface for managing Shelly IoT devices",
290-
"builtWith": "Built with React + TypeScript",
291-
"poweredBy": "Powered by Vite",
292-
"uiBy": "UI by shadcn/ui"
289+
"description": "A modern web interface for locally managing Shelly IoT devices"
293290
},
294291
"messages": {
295292
"settingsSaved": "Settings saved successfully",

packages/web/src/pages/dashboard.tsx

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { toast } from "sonner";
66
import { ScanForm, type ScanFormData } from "@/components/dashboard/scan-form";
77
import { DeviceTable } from "@/components/dashboard/device-table";
88
import { BulkActionsDialog } from "@/components/dashboard/bulk-actions-dialog";
9+
import { Footer } from "@/components/ui/footer";
910
import { deviceApi, handleApiError } from "@/lib/api";
1011
import type { Device } from "@/types/api";
1112

@@ -46,31 +47,37 @@ export function Dashboard() {
4647
};
4748

4849
return (
49-
<div className="space-y-8">
50-
{/* Header */}
51-
<div>
52-
<h1 className="text-3xl font-bold tracking-tight">
53-
{t("dashboard.title")}
54-
</h1>
55-
<p className="text-muted-foreground">{t("dashboard.subtitle")}</p>
56-
</div>
50+
<div className="min-h-[calc(100vh-8rem)] flex flex-col">
51+
{/* Main Content */}
52+
<div className="flex-1 space-y-8">
53+
{/* Header */}
54+
<div>
55+
<h1 className="text-3xl font-bold tracking-tight">
56+
{t("dashboard.title")}
57+
</h1>
58+
<p className="text-muted-foreground">{t("dashboard.subtitle")}</p>
59+
</div>
5760

58-
{/* Scan Form */}
59-
<ScanForm onSubmit={handleScan} isLoading={scanMutation.isPending} />
61+
{/* Scan Form */}
62+
<ScanForm onSubmit={handleScan} isLoading={scanMutation.isPending} />
6063

61-
{/* Error Display */}
62-
{scanMutation.error && (
63-
<div className="p-4 border border-destructive/50 bg-destructive/10 rounded-lg">
64-
<p className="text-sm text-destructive">
65-
{handleApiError(scanMutation.error)}
66-
</p>
67-
</div>
68-
)}
64+
{/* Error Display */}
65+
{scanMutation.error && (
66+
<div className="p-4 border border-destructive/50 bg-destructive/10 rounded-lg">
67+
<p className="text-sm text-destructive">
68+
{handleApiError(scanMutation.error)}
69+
</p>
70+
</div>
71+
)}
72+
73+
{/* Device Table */}
74+
{devices.length > 0 && (
75+
<DeviceTable devices={devices} onBulkAction={handleBulkAction} />
76+
)}
77+
</div>
6978

70-
{/* Device Table */}
71-
{devices.length > 0 && (
72-
<DeviceTable devices={devices} onBulkAction={handleBulkAction} />
73-
)}
79+
{/* Sticky Footer */}
80+
<Footer className="mt-8" />
7481

7582
{/* Bulk Actions Dialog */}
7683
<BulkActionsDialog

0 commit comments

Comments
 (0)