mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
feat(dashboard): tendências top 10 e padronização de espaçamento do inbox
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ export function CategoryTrendsWidget({
|
|||||||
(a, b) =>
|
(a, b) =>
|
||||||
Math.abs(b.percentageChange ?? 0) - Math.abs(a.percentageChange ?? 0),
|
Math.abs(b.percentageChange ?? 0) - Math.abs(a.percentageChange ?? 0),
|
||||||
)
|
)
|
||||||
.slice(0, 6);
|
.slice(0, 10);
|
||||||
|
|
||||||
if (trending.length === 0) {
|
if (trending.length === 0) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export function InboxWidget({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-1">
|
<div className="flex flex-col">
|
||||||
{snapshot.recentItems.map((item) => {
|
{snapshot.recentItems.map((item) => {
|
||||||
const displayName = item.parsedName ?? item.originalText.slice(0, 40);
|
const displayName = item.parsedName ?? item.originalText.slice(0, 40);
|
||||||
const parsedAmount =
|
const parsedAmount =
|
||||||
@@ -174,58 +174,59 @@ export function InboxWidget({
|
|||||||
const displayLogo = logoSrc ?? DEFAULT_INBOX_APP_LOGO;
|
const displayLogo = logoSrc ?? DEFAULT_INBOX_APP_LOGO;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={item.id} className="-mx-2 rounded-md p-2">
|
<div
|
||||||
<div className="flex items-center gap-2">
|
key={item.id}
|
||||||
|
className="flex items-center justify-between py-1.5"
|
||||||
|
>
|
||||||
|
<div className="flex min-w-0 flex-1 items-center gap-2 py-1">
|
||||||
<Image
|
<Image
|
||||||
src={displayLogo}
|
src={displayLogo}
|
||||||
alt={item.sourceAppName ?? ""}
|
alt={item.sourceAppName ?? ""}
|
||||||
width={36}
|
width={38}
|
||||||
height={36}
|
height={38}
|
||||||
className="size-9 shrink-0 rounded-full object-contain"
|
className="size-9.5 shrink-0 rounded-full object-contain"
|
||||||
unoptimized
|
unoptimized
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0">
|
||||||
<p className="truncate text-sm font-medium text-foreground">
|
<p className="truncate text-sm font-medium text-foreground">
|
||||||
{displayName}
|
{displayName}
|
||||||
</p>
|
</p>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2 text-xs text-muted-foreground">
|
||||||
{item.sourceAppName && (
|
{item.sourceAppName && <span>{item.sourceAppName}</span>}
|
||||||
<span className="text-xs text-muted-foreground">
|
<span className="text-muted-foreground/60">
|
||||||
{item.sourceAppName}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
<span className="text-xs text-muted-foreground/60">
|
|
||||||
{relativeTime(item.createdAt)}
|
{relativeTime(item.createdAt)}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex items-center">
|
|
||||||
<Button
|
|
||||||
size="icon-sm"
|
|
||||||
variant="ghost"
|
|
||||||
className="size-6 text-muted-foreground hover:text-foreground"
|
|
||||||
onClick={() => handleProcessRequest(item)}
|
|
||||||
aria-label="Processar notificação"
|
|
||||||
title="Processar"
|
|
||||||
>
|
|
||||||
<RiCheckLine className="size-3.5" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
size="icon-sm"
|
|
||||||
variant="ghost"
|
|
||||||
className="size-6 text-muted-foreground hover:text-destructive"
|
|
||||||
onClick={() => handleDiscardRequest(item)}
|
|
||||||
aria-label="Descartar notificação"
|
|
||||||
title="Descartar"
|
|
||||||
>
|
|
||||||
<RiDeleteBinLine className="size-3.5" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex shrink-0 flex-col items-end">
|
||||||
{amount !== null && (
|
{amount !== null && (
|
||||||
<MoneyValues className="font-medium" amount={amount} />
|
<MoneyValues className="font-medium" amount={amount} />
|
||||||
)}
|
)}
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Button
|
||||||
|
size="icon-sm"
|
||||||
|
variant="ghost"
|
||||||
|
className="size-6 text-muted-foreground hover:text-foreground"
|
||||||
|
onClick={() => handleProcessRequest(item)}
|
||||||
|
aria-label="Processar notificação"
|
||||||
|
title="Processar"
|
||||||
|
>
|
||||||
|
<RiCheckLine className="size-3.5" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="icon-sm"
|
||||||
|
variant="ghost"
|
||||||
|
className="size-6 text-muted-foreground hover:text-destructive"
|
||||||
|
onClick={() => handleDiscardRequest(item)}
|
||||||
|
aria-label="Descartar notificação"
|
||||||
|
title="Descartar"
|
||||||
|
>
|
||||||
|
<RiDeleteBinLine className="size-3.5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export const widgetsConfig: WidgetConfig[] = [
|
|||||||
{
|
{
|
||||||
id: "category-trends",
|
id: "category-trends",
|
||||||
title: "Tendências de Categorias",
|
title: "Tendências de Categorias",
|
||||||
subtitle: "Top 6 maiores variações vs. mês anterior",
|
subtitle: "Top 10 maiores variações vs. mês anterior",
|
||||||
icon: <RiLineChartLine className="size-4" />,
|
icon: <RiLineChartLine className="size-4" />,
|
||||||
component: ({ data }) => (
|
component: ({ data }) => (
|
||||||
<CategoryTrendsWidget
|
<CategoryTrendsWidget
|
||||||
|
|||||||
Reference in New Issue
Block a user