A warmer, friendlier admin: first pass
- The INBUXA palette on warm surfaces, softer cards, buttons and inputs, and self-hosted Inter and Space Grotesk. - Each section's icon sits on a colored tile, colored by what the section is about. - The sidebar gets a guide line for sub-pages and a labeled Management / Settings / Account switch, and folds to a rail of tiles (remembered). - Every page has a header with its section's tile. - Fields and pages with no label of their own are spelled out in words (defaultCertificateId becomes Default certificate ID). - The dashboard greets you, and its stat cards wear colored tiles. - Unavailable live numbers are a calm note, not an error. - The cat appears in empty lists and while loading. - Chart colors work again: they were hex values wrapped in hsl().
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Coffey Labs
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuthStore } from '@/stores/authStore';
|
||||
import inbuxaMark from '@/assets/inbuxa-mark.png';
|
||||
|
||||
function partOfDay(hour: number): 'morning' | 'afternoon' | 'evening' {
|
||||
if (hour < 12) return 'morning';
|
||||
if (hour < 18) return 'afternoon';
|
||||
return 'evening';
|
||||
}
|
||||
|
||||
/** The dashboard's hello: whose server this is, and a nod to the time of day. */
|
||||
export function Greeting() {
|
||||
const { t } = useTranslation();
|
||||
const accounts = useAuthStore((s) => s.accounts);
|
||||
const activeAccountId = useAuthStore((s) => s.activeAccountId);
|
||||
const full = (activeAccountId && accounts[activeAccountId]?.name) || '';
|
||||
const name = full.split('@')[0];
|
||||
const part = partOfDay(new Date().getHours());
|
||||
const hello =
|
||||
part === 'morning'
|
||||
? t('greeting.morning', 'Good morning')
|
||||
: part === 'afternoon'
|
||||
? t('greeting.afternoon', 'Good afternoon')
|
||||
: t('greeting.evening', 'Good evening');
|
||||
return (
|
||||
<div className="flex items-center gap-4 rounded-2xl border bg-gradient-to-br from-accent/70 via-card to-card px-5 py-4 shadow-soft">
|
||||
<img src={inbuxaMark} alt="" className="h-12 w-auto drop-shadow-sm" />
|
||||
<div className="min-w-0">
|
||||
<h1 className="truncate text-2xl font-semibold">
|
||||
{hello}
|
||||
{name && `, ${name}`}
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('greeting.subtitle', "Here's how your mail server is doing.")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user