feat(key-value-list-component): KeyValueList für Detail-Views [tsc:fail]

This commit is contained in:
Dennis (via Claude+Gemma) 2026-05-23 10:14:44 +02:00
parent c0d1586d9a
commit 155499c063
3 changed files with 88 additions and 2 deletions

View File

@ -1,8 +1,9 @@
{ {
"completed_features": [], "completed_features": [],
"current_feature": "image-gallery-component", "current_feature": "key-value-list-component",
"started_at": "2026-05-23T10:13:25.521406", "started_at": "2026-05-23T10:13:25.521406",
"attempted_features": [ "attempted_features": [
"file-upload-component" "file-upload-component",
"image-gallery-component"
] ]
} }

View File

@ -4150,3 +4150,21 @@ src/index.ts(27,25): error TS2769: No overload matches this call.
Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>,
- `10:14:25` **INFO** Committed feature image-gallery-component
- `10:14:25` **INFO** Pushed: rc=0
## Phase-3 Feature: key-value-list-component (2026-05-23 10:14:25)
- `10:14:25` **INFO** Description: KeyValueList für Detail-Views
- `10:14:25` **INFO** Generating apps/web/src/components/KeyValueList.tsx (KeyValueList-Component. Props: items (array {key, value: ReactNode, co…)
- `10:14:42` **INFO** wrote 1957 chars in 16.9s (attempt 1)
- `10:14:42` **INFO** Running tsc --noEmit on api…
- `10:14:44` **WARN** tsc errors:
src/db/schema.ts(37,14): error TS7022: 'customers' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
src/db/schema.ts(45,59): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
src/db/schema.ts(49,14): error TS7022: 'projects' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
src/db/schema.ts(53,56): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
src/index.ts(27,25): error TS2769: No overload matches this call.
Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>,

View File

@ -0,0 +1,67 @@
import React, { useState } from 'react';
import { Copy, Check } from 'lucide-react';
import type { ReactNode } from 'react';
interface KeyValueItem {
key: string;
value: ReactNode;
copyable?: boolean;
}
interface KeyValueListProps {
items: KeyValueItem[];
layout?: 'horizontal' | 'vertical';
className?: string;
}
export default function KeyValueList({
items,
layout = 'horizontal',
className = ''
}: KeyValueListProps) {
return (
<div className={`space-y-2 ${className}`}>
{items.map((item, idx) => (
<KeyValueRow key={`${item.key}-${idx}`} item={item} layout={layout} />
))}
</div>
);
}
function KeyValueRow({ item, layout }: { item: KeyValueItem; layout: 'horizontal' | 'vertical' }) {
const [copied, setCopied] = useState(false);
const handleCopy = async () => {
if (typeof item.value === 'string') {
await navigator.clipboard.writeText(item.value);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
};
const containerClasses = layout === 'horizontal'
? 'grid grid-cols-[auto_1fr] gap-2 items-center'
: 'flex flex-col gap-1';
const keyClasses = layout === 'horizontal'
? 'text-muted-foreground font-medium'
: 'text-xs uppercase tracking-wider text-muted-foreground font-semibold';
return (
<div className={containerClasses}>
<span className={keyClasses}>{item.key}</span>
<div className="flex items-center gap-2">
<span className="text-foreground">{item.value}</span>
{item.copyable && typeof item.value === 'string' && (
<button
onClick={handleCopy}
className="p-1 hover:bg-accent rounded transition-colors text-muted-foreground hover:text-foreground"
title="Copy to clipboard"
>
{copied ? <Check size={14} className="text-green-500" /> : <Copy size={14} />}
</button>
)}
</div>
</div>
);
}