- Integrated CreditOverview and RecentTransactions components into the dashboard for better credit visibility. - Updated canvas toolbar to display current credit balance using CreditDisplay. - Improved AI image and prompt nodes to show credit costs and handle credit availability checks during image generation. - Added new queries for fetching recent transactions and monthly usage statistics to support dashboard features. - Refactored existing code to streamline credit-related functionalities across components.
107 lines
2.5 KiB
TypeScript
107 lines
2.5 KiB
TypeScript
"use client";
|
|
|
|
import { useRef } from "react";
|
|
|
|
import { CreditDisplay } from "@/components/canvas/credit-display";
|
|
import { ExportButton } from "@/components/canvas/export-button";
|
|
import { useCanvasPlacement } from "@/components/canvas/canvas-placement-context";
|
|
|
|
const nodeTemplates = [
|
|
{
|
|
type: "image",
|
|
label: "Bild",
|
|
width: 280,
|
|
height: 180,
|
|
defaultData: {},
|
|
},
|
|
{
|
|
type: "text",
|
|
label: "Text",
|
|
width: 256,
|
|
height: 120,
|
|
defaultData: { content: "" },
|
|
},
|
|
{
|
|
type: "prompt",
|
|
label: "Prompt",
|
|
width: 320,
|
|
height: 220,
|
|
defaultData: { prompt: "", model: "", aspectRatio: "1:1" },
|
|
},
|
|
{
|
|
type: "note",
|
|
label: "Notiz",
|
|
width: 220,
|
|
height: 120,
|
|
defaultData: { content: "" },
|
|
},
|
|
{
|
|
type: "frame",
|
|
label: "Frame",
|
|
width: 360,
|
|
height: 240,
|
|
defaultData: { label: "Untitled", exportWidth: 1080, exportHeight: 1080 },
|
|
},
|
|
{
|
|
type: "compare",
|
|
label: "Compare",
|
|
width: 500,
|
|
height: 380,
|
|
defaultData: {},
|
|
},
|
|
] as const;
|
|
|
|
interface CanvasToolbarProps {
|
|
canvasName?: string;
|
|
}
|
|
|
|
export default function CanvasToolbar({
|
|
canvasName,
|
|
}: CanvasToolbarProps) {
|
|
const { createNodeWithIntersection } = useCanvasPlacement();
|
|
const nodeCountRef = useRef(0);
|
|
|
|
const handleAddNode = async (
|
|
type: (typeof nodeTemplates)[number]["type"],
|
|
data: (typeof nodeTemplates)[number]["defaultData"],
|
|
width: number,
|
|
height: number,
|
|
) => {
|
|
const offset = (nodeCountRef.current % 8) * 24;
|
|
nodeCountRef.current += 1;
|
|
await createNodeWithIntersection({
|
|
type,
|
|
position: { x: 100 + offset, y: 100 + offset },
|
|
width,
|
|
height,
|
|
data,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="absolute top-4 left-1/2 z-10 flex -translate-x-1/2 items-center gap-1 rounded-xl border bg-card/90 p-1.5 shadow-lg backdrop-blur-sm">
|
|
{nodeTemplates.map((template) => (
|
|
<button
|
|
key={template.type}
|
|
onClick={() =>
|
|
void handleAddNode(
|
|
template.type,
|
|
template.defaultData,
|
|
template.width,
|
|
template.height,
|
|
)
|
|
}
|
|
className="rounded-lg px-3 py-1.5 text-sm transition-colors hover:bg-accent"
|
|
title={`${template.label} hinzufuegen`}
|
|
type="button"
|
|
>
|
|
{template.label}
|
|
</button>
|
|
))}
|
|
<div className="ml-1 h-6 w-px bg-border" />
|
|
<CreditDisplay />
|
|
<ExportButton canvasName={canvasName ?? "canvas"} />
|
|
</div>
|
|
);
|
|
}
|