+
+
diff --git a/apps/cockpit/src/components/ContentLayout/GridLayout.tsx b/apps/cockpit/src/components/ContentLayout/GridLayout.tsx
new file mode 100644
index 0000000..577b288
--- /dev/null
+++ b/apps/cockpit/src/components/ContentLayout/GridLayout.tsx
@@ -0,0 +1,5 @@
+import type { PropsWithChildren } from 'react';
+
+export function GridLayout({ children }: PropsWithChildren) {
+ return
+
) {
+ return
- {children}
+ {children}
{Devtools ? : null}
diff --git a/apps/cockpit/src/routes/finance/transactions.tsx b/apps/cockpit/src/routes/finance/transactions.tsx
index 1e0b92d..0260e64 100644
--- a/apps/cockpit/src/routes/finance/transactions.tsx
+++ b/apps/cockpit/src/routes/finance/transactions.tsx
@@ -1,5 +1,6 @@
import { createFileRoute } from '@tanstack/react-router';
import { Transactions } from '@/domain/finance/transactions/Transactions.tsx';
+import { GridLayout } from '@/components/ContentLayout/GridLayout.tsx';
export const Route = createFileRoute('/finance/transactions')({
component: TransactionsRoute,
@@ -9,5 +10,9 @@ export const Route = createFileRoute('/finance/transactions')({
});
function TransactionsRoute() {
- return ;
+ return (
+
+
+
+ );
}
diff --git a/apps/cockpit/src/routes/index.tsx b/apps/cockpit/src/routes/index.tsx
index 43db789..23ad53b 100644
--- a/apps/cockpit/src/routes/index.tsx
+++ b/apps/cockpit/src/routes/index.tsx
@@ -1,19 +1,25 @@
import { createFileRoute } from '@tanstack/react-router';
import { WeatherWidget } from '@/domain/weather/WeatherWidget.tsx';
-import { LOCATION_MOESSINGEN, LOCATION_OBERNHEIM } from '@/domain/weather/model/model.ts';
+import { LOCATION_MOESSINGEN, LOCATION_OBERNHEIM, LOCATION_TUEBINGEN } from '@/domain/weather/model/model.ts';
+import { GridLayout } from '@/components/ContentLayout/GridLayout.tsx';
+import { Section } from '@/components/Section/Section.tsx';
export const Route = createFileRoute('/')({
- component: App,
+ component: Overview,
});
-function App() {
+function Overview() {
return (
- <>
-
-
- {/*
-
- */}
- >
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/apps/cockpit/src/styles.css b/apps/cockpit/src/styles.css
index d64eb99..c4ec04d 100644
--- a/apps/cockpit/src/styles.css
+++ b/apps/cockpit/src/styles.css
@@ -11,6 +11,7 @@
--color-section-border: #d6dde6;
--color-sem-positive: oklch(59.6% 0.145 163.225);
--color-sem-negative: oklch(58.6% 0.253 17.585);
+ --color-skeleton: #e6e6e6;
}
@media (prefers-color-scheme: dark) {
@@ -25,6 +26,7 @@
--color-section-border: #272727;
--color-sem-positive: oklch(84.5% 0.143 164.978);
--color-sem-negative: oklch(71.2% 0.194 13.428);
+ --color-skeleton: #272727;
}
}
@@ -53,3 +55,11 @@ code {
.animate-rainbow {
animation: rainbow 30s linear infinite;
}
+
+.grid-layout {
+ @apply grid gap-4 grid-cols-2 md:grid-cols-4 lg:grid-cols-6 2xl:grid-cols-12;
+}
+
+.section-base {
+ @apply transition-all self-start w-full h-full bg-(--color-bg) flex p-4 rounded-lg border border-(--color-section-border) @container;
+}
{children}
;
+}
diff --git a/apps/cockpit/src/components/KPI/KPISection.tsx/KPISection.tsx b/apps/cockpit/src/components/KPI/KPISection.tsx/KPISection.tsx
index 88a69d8..7bb8145 100644
--- a/apps/cockpit/src/components/KPI/KPISection.tsx/KPISection.tsx
+++ b/apps/cockpit/src/components/KPI/KPISection.tsx/KPISection.tsx
@@ -9,7 +9,7 @@ interface Props {
export function KPISection({ label, value, tone }: Props) {
return (
- {label}
- {children}
-
- );
+interface Props {
+ className?: string;
+}
+
+export function Section({ children, className }: PropsWithChildren{children}
;
}
diff --git a/apps/cockpit/src/components/Transition/FadeTransition.tsx b/apps/cockpit/src/components/Transition/FadeTransition.tsx
index f4a0caf..987d332 100644
--- a/apps/cockpit/src/components/Transition/FadeTransition.tsx
+++ b/apps/cockpit/src/components/Transition/FadeTransition.tsx
@@ -47,7 +47,12 @@ export function FadeTransition({ children, transitionKey, durationMs = 300, clas
return (
{visibleChildren}
diff --git a/apps/cockpit/src/domain/finance/transactions/Transactions.tsx b/apps/cockpit/src/domain/finance/transactions/Transactions.tsx
index 8424456..ea80c79 100644
--- a/apps/cockpit/src/domain/finance/transactions/Transactions.tsx
+++ b/apps/cockpit/src/domain/finance/transactions/Transactions.tsx
@@ -25,7 +25,6 @@ import {
} from 'src/domain/finance/transactions/model.ts';
import { useTransactions } from '@/domain/finance/transactions/data.ts';
import { useDateRange } from '@/utils/useDateRange.ts';
-import { Grid } from '@/components/Grid/Grid.tsx';
import { SummaryStrip } from '@/domain/finance/transactions/SummaryStrip.tsx';
import { Section } from '@/components/Section/Section.tsx';
import { Input } from '@/components/Input/Input.tsx';
@@ -99,41 +98,34 @@ export function Transactions() {
};
return (
- }
+ >
);
}
diff --git a/apps/cockpit/src/domain/weather/WeatherWidget.tsx b/apps/cockpit/src/domain/weather/WeatherWidget.tsx
index 76216dd..2c0e1eb 100644
--- a/apps/cockpit/src/domain/weather/WeatherWidget.tsx
+++ b/apps/cockpit/src/domain/weather/WeatherWidget.tsx
@@ -1,5 +1,3 @@
-import { FadeTransition } from '@/components/Transition/FadeTransition.tsx';
-import { Section } from '@/components/Section/Section.tsx';
import { WeatherCurrentSummary } from '@/domain/weather/WeatherCurrentSummary.tsx';
import type { WeatherDataLoaded, WeatherLocation } from '@/domain/weather/model/model.ts';
import { Header } from '@/domain/weather/Header.tsx';
@@ -12,16 +10,11 @@ type WeatherWidgetProps = {
export function WeatherWidget({ location }: WeatherWidgetProps) {
const weather = useWeatherSnapshot(location);
- return (
-
- {weather.status === 'error' && {weather.errorMessage} }
- {weather.status === 'loaded' && (
-
-
-
- )}
-
- );
+ if (weather.status === 'loading') return ;
+
+ if (weather.status === 'error') return weather.errorMessage;
+
+ return ;
}
type WeatherWidgetContentProps = {
@@ -37,3 +30,23 @@ function WeatherWidgetContent({ location, weather }: WeatherWidgetContentProps)
);
}
+
+function Skeleton() {
+ return (
+
- {data && (
- <>
- {data?.summary && (
-
-
-
- )}
- {error && (
-
- {loading && }
+ {error && (
+
+ {loading && }
- >
- )}
-
+ {data &&
- {error.message}
-
- )}
- Loading transactions...
} - {/* Transaction list should have kind of toolbar + <> + {data?.summary &&
+ {error.message}
+
+ )}
+
+ Loading transactions...
} + {/* Transaction list should have kind of toolbar setDateRangeMonth(event.target.value)} /> */} - {data &&
+
+ );
+}
diff --git a/apps/cockpit/src/domain/weather/model/model.ts b/apps/cockpit/src/domain/weather/model/model.ts
index 9908e64..00279c5 100644
--- a/apps/cockpit/src/domain/weather/model/model.ts
+++ b/apps/cockpit/src/domain/weather/model/model.ts
@@ -22,6 +22,14 @@ export const LOCATION_OBERNHEIM: WeatherLocation = {
timezone: 'Europe/Berlin',
};
+export const LOCATION_TUEBINGEN: WeatherLocation = {
+ id: 'tuebingen',
+ label: 'Tübingen',
+ latitude: 48.52,
+ longitude: 9.06,
+ timezone: 'Europe/Berlin',
+};
+
export interface HourlyTemperaturePoint {
timeIso: string;
temperatureC: number;
diff --git a/apps/cockpit/src/routes/__root.tsx b/apps/cockpit/src/routes/__root.tsx
index 4b4b266..b2ad656 100644
--- a/apps/cockpit/src/routes/__root.tsx
+++ b/apps/cockpit/src/routes/__root.tsx
@@ -3,7 +3,7 @@ import { createRootRoute, HeadContent, Scripts } from '@tanstack/react-router';
import appCss from '../styles.css?url';
import { PageLayout } from '@/components/PageLayout/PageLayout.tsx';
import { Section } from '@/components/Section/Section.tsx';
-import { ContentLayout } from '@/components/ContentLayout/ContentLayout.tsx';
+import { ContentArea } from '@/components/ContentArea/ContentArea.tsx';
import { Navigation } from '@/components/Navigation/Navigation.tsx';
import { MdOutlineHome as HomeIcon } from 'react-icons/md';
@@ -33,7 +33,7 @@ function RootDocument({ children }: PropsWithChildren) {
+
+
+
+
+
+
+
+
+
+
+
+
+