feat(odin): personalized greeting hero on the new-conversation screen
Time-based Czech greeting + the user's first name (e.g. "Dobrý večer, Admin") above the big gradient "Odin" wordmark, with a stylish description line. Drop the redundant mark from the hero (it lives on the nav item + thinking state). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,10 +62,26 @@ function summaryNote(reviews: ReviewInvoice[]): string {
|
||||
export default function OdinChat() {
|
||||
const alert = useAlert();
|
||||
const qc = useQueryClient();
|
||||
const { hasPermission } = useAuth();
|
||||
const { user, hasPermission } = useAuth();
|
||||
// Saving an extracted invoice hits /received-invoices (needs invoices.create);
|
||||
// Odin itself only needs ai.use, so the Save affordance is gated separately.
|
||||
const canSave = hasPermission("invoices.create");
|
||||
// Time-based Czech greeting + the user's first name (client-local time).
|
||||
const greeting = (() => {
|
||||
const h = new Date().getHours();
|
||||
const part =
|
||||
h < 9
|
||||
? "Dobré ráno"
|
||||
: h < 12
|
||||
? "Dobrý den"
|
||||
: h < 18
|
||||
? "Dobré odpoledne"
|
||||
: "Dobrý večer";
|
||||
const name = (user?.fullName || user?.username || "")
|
||||
.trim()
|
||||
.split(/\s+/)[0];
|
||||
return name ? `${part}, ${name}` : part;
|
||||
})();
|
||||
const { data: usage } = useQuery(aiUsageOptions());
|
||||
const { data: convData, isPending: convPending } = useQuery(
|
||||
aiConversationsOptions(),
|
||||
@@ -425,6 +441,7 @@ export default function OdinChat() {
|
||||
turns={turns}
|
||||
busy={busy}
|
||||
loading={messagesLoading}
|
||||
greeting={greeting}
|
||||
threadRef={threadRef}
|
||||
/>
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ interface OdinThreadProps {
|
||||
turns: ChatTurn[];
|
||||
busy: boolean;
|
||||
loading: boolean;
|
||||
greeting?: string;
|
||||
threadRef: React.RefObject<HTMLDivElement | null>;
|
||||
}
|
||||
|
||||
@@ -37,6 +38,7 @@ export default function OdinThread({
|
||||
turns,
|
||||
busy,
|
||||
loading,
|
||||
greeting,
|
||||
threadRef,
|
||||
}: OdinThreadProps) {
|
||||
return (
|
||||
@@ -79,34 +81,50 @@ export default function OdinThread({
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: 2.5,
|
||||
gap: 1.25,
|
||||
textAlign: "center",
|
||||
px: 2,
|
||||
}}
|
||||
>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||
<OdinMark size={52} />
|
||||
<Box
|
||||
component="span"
|
||||
sx={(t) => ({
|
||||
fontSize: "clamp(2rem, 1.2rem + 2.4vw, 2.75rem)",
|
||||
fontWeight: 700,
|
||||
lineHeight: 1.1,
|
||||
letterSpacing: "-0.02em",
|
||||
backgroundImage: `linear-gradient(120deg, ${t.vars!.palette.primary.light}, ${t.vars!.palette.primary.main})`,
|
||||
WebkitBackgroundClip: "text",
|
||||
backgroundClip: "text",
|
||||
WebkitTextFillColor: "transparent",
|
||||
})}
|
||||
{greeting && (
|
||||
<Typography
|
||||
component="div"
|
||||
sx={{
|
||||
color: "text.secondary",
|
||||
fontWeight: 500,
|
||||
fontSize: "clamp(1rem, 0.85rem + 0.6vw, 1.25rem)",
|
||||
}}
|
||||
>
|
||||
Odin
|
||||
</Box>
|
||||
{greeting}
|
||||
</Typography>
|
||||
)}
|
||||
<Box
|
||||
component="span"
|
||||
sx={(t) => ({
|
||||
fontSize: "clamp(2.25rem, 1.4rem + 2.6vw, 3rem)",
|
||||
fontWeight: 800,
|
||||
lineHeight: 1.05,
|
||||
letterSpacing: "-0.03em",
|
||||
backgroundImage: `linear-gradient(120deg, ${t.vars!.palette.primary.light}, ${t.vars!.palette.primary.main})`,
|
||||
WebkitBackgroundClip: "text",
|
||||
backgroundClip: "text",
|
||||
WebkitTextFillColor: "transparent",
|
||||
})}
|
||||
>
|
||||
Odin
|
||||
</Box>
|
||||
<Typography
|
||||
variant="body2"
|
||||
sx={{ color: "text.secondary", maxWidth: 440 }}
|
||||
component="div"
|
||||
sx={{
|
||||
color: "text.secondary",
|
||||
maxWidth: 460,
|
||||
mt: 0.5,
|
||||
fontSize: "0.95rem",
|
||||
lineHeight: 1.5,
|
||||
}}
|
||||
>
|
||||
Zeptejte se, nebo přiložte fakturu (PDF) k automatickému importu.
|
||||
Váš firemní AI asistent. Zeptejte se, nebo přiložte fakturu (PDF) k
|
||||
importu.
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user