diff --git a/apps/cockpit/src/components/Breadcrumb/Breadcrumb.tsx b/apps/cockpit/src/components/Breadcrumb/Breadcrumb.tsx index 898449c..e47f63e 100644 --- a/apps/cockpit/src/components/Breadcrumb/Breadcrumb.tsx +++ b/apps/cockpit/src/components/Breadcrumb/Breadcrumb.tsx @@ -16,7 +16,7 @@ export function Breadcrumb() { const matches = useMatches().filter((m) => m.staticData?.crumb); return ( -
+
{matches.map((item, index) => { if (!item.staticData?.crumb) return null; return ( diff --git a/apps/cockpit/src/components/ContentLayout/ContentLayout.tsx b/apps/cockpit/src/components/ContentArea/ContentArea.tsx similarity index 58% rename from apps/cockpit/src/components/ContentLayout/ContentLayout.tsx rename to apps/cockpit/src/components/ContentArea/ContentArea.tsx index 87e722b..184c7e6 100644 --- a/apps/cockpit/src/components/ContentLayout/ContentLayout.tsx +++ b/apps/cockpit/src/components/ContentArea/ContentArea.tsx @@ -1,10 +1,10 @@ import { type PropsWithChildren } from 'react'; import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb.tsx'; -export function ContentLayout({ children }: PropsWithChildren) { +export function ContentArea({ children }: PropsWithChildren) { return ( -
-
+
+
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
{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) { + return
{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 ( -
- {data && ( - <> - {data?.summary && ( - - - - )} - {error && ( -
- {error.message} -
- )} - - {loading &&

Loading transactions...

} - {/* Transaction list should have kind of toolbar + <> + {data?.summary && } + {error && ( +
+ {error.message} +
+ )} + + + {loading &&

Loading transactions...

} + {/* Transaction list should have kind of toolbar setDateRangeMonth(event.target.value)} /> */} - {data && } - - )} -
+ {data && } + ); } 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 ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ); +} 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) { - {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; +}