feat(ledger): add bookkeeping workbench and transaction views
- Add transactions_dirty table and zero-tolerance cleansing action - Implement bookkeeping workbench (/bookkeeping) with searchable Combobox channel selector and card suffix / account identifier - Implement transaction ledger (/transactions) with date groupings, multi-currency metrics, and filters - Update AGENTS.md guidelines for Base UI Select and Combobox bindings
This commit is contained in:
+16
-22
@@ -1,4 +1,4 @@
|
||||
"use client";
|
||||
"use client"
|
||||
|
||||
import {
|
||||
ChevronsUpDownIcon,
|
||||
@@ -6,14 +6,10 @@ import {
|
||||
Settings2Icon,
|
||||
SparklesIcon,
|
||||
UserCogIcon,
|
||||
} from "lucide-react";
|
||||
import { signOut } from "next-auth/react";
|
||||
} from "lucide-react"
|
||||
import { signOut } from "next-auth/react"
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/components/ui/avatar";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -22,29 +18,27 @@ import {
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import {
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} from "@/components/ui/sidebar";
|
||||
} from "@/components/ui/sidebar"
|
||||
|
||||
export interface NavUserData {
|
||||
name: string;
|
||||
email: string;
|
||||
avatar?: string | null;
|
||||
name: string
|
||||
email: string
|
||||
avatar?: string | null
|
||||
}
|
||||
|
||||
export function NavUser({ user }: { user: NavUserData }) {
|
||||
const { isMobile } = useSidebar();
|
||||
const initials = (user.name || user.email || "U")
|
||||
.slice(0, 2)
|
||||
.toUpperCase();
|
||||
const { isMobile } = useSidebar()
|
||||
const initials = (user.name || user.email || "U").slice(0, 2).toUpperCase()
|
||||
|
||||
const handleSignOut = () => {
|
||||
signOut({ callbackUrl: "/login" });
|
||||
};
|
||||
signOut({ callbackUrl: "/login" })
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarMenu>
|
||||
@@ -62,7 +56,7 @@ export function NavUser({ user }: { user: NavUserData }) {
|
||||
{user.avatar ? (
|
||||
<AvatarImage src={user.avatar} alt={user.name} />
|
||||
) : null}
|
||||
<AvatarFallback className="rounded-lg font-medium text-xs">
|
||||
<AvatarFallback className="rounded-lg text-xs font-medium">
|
||||
{initials}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
@@ -89,7 +83,7 @@ export function NavUser({ user }: { user: NavUserData }) {
|
||||
{user.avatar ? (
|
||||
<AvatarImage src={user.avatar} alt={user.name} />
|
||||
) : null}
|
||||
<AvatarFallback className="rounded-lg font-medium text-xs">
|
||||
<AvatarFallback className="rounded-lg text-xs font-medium">
|
||||
{initials}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
@@ -140,5 +134,5 @@ export function NavUser({ user }: { user: NavUserData }) {
|
||||
</DropdownMenu>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user