Files
Codewalkers/apps/web/src/components/review/FileCard.tsx
Lukas May 34578d39c6 refactor: Restructure monorepo to apps/server/ and apps/web/ layout
Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt
standard monorepo conventions (apps/ for runnable apps, packages/
for reusable libraries). Update all config files, shared package
imports, test fixtures, and documentation to reflect new paths.

Key fixes:
- Update workspace config to ["apps/*", "packages/*"]
- Update tsconfig.json rootDir/include for apps/server/
- Add apps/web/** to vitest exclude list
- Update drizzle.config.ts schema path
- Fix ensure-schema.ts migration path detection (3 levels up in dev,
  2 levels up in dist)
- Fix tests/integration/cli-server.test.ts import paths
- Update packages/shared imports to apps/server/ paths
- Update all docs/ files with new paths
2026-03-03 11:22:53 +01:00

87 lines
2.7 KiB
TypeScript

import { useState } from "react";
import { ChevronDown, ChevronRight, Plus, Minus } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import type { FileDiff, DiffLine, ReviewComment } from "./types";
import { HunkRows } from "./HunkRows";
interface FileCardProps {
file: FileDiff;
comments: ReviewComment[];
onAddComment: (
filePath: string,
lineNumber: number,
lineType: DiffLine["type"],
body: string,
) => void;
onResolveComment: (commentId: string) => void;
onUnresolveComment: (commentId: string) => void;
}
export function FileCard({
file,
comments,
onAddComment,
onResolveComment,
onUnresolveComment,
}: FileCardProps) {
const [expanded, setExpanded] = useState(true);
const commentCount = comments.length;
return (
<div className="rounded-lg border border-border overflow-hidden">
{/* File header */}
<button
className="flex w-full items-center gap-2 px-3 py-2 bg-muted/50 hover:bg-muted text-left text-sm font-mono transition-colors"
onClick={() => setExpanded(!expanded)}
>
{expanded ? (
<ChevronDown className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
) : (
<ChevronRight className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
)}
<span className="truncate flex-1">{file.newPath}</span>
<span className="flex items-center gap-2 shrink-0 text-xs">
{file.additions > 0 && (
<span className="flex items-center gap-0.5 text-green-600">
<Plus className="h-3 w-3" />
{file.additions}
</span>
)}
{file.deletions > 0 && (
<span className="flex items-center gap-0.5 text-red-600">
<Minus className="h-3 w-3" />
{file.deletions}
</span>
)}
{commentCount > 0 && (
<Badge variant="secondary" className="text-[10px] px-1.5 py-0">
{commentCount}
</Badge>
)}
</span>
</button>
{/* Diff content */}
{expanded && (
<div className="overflow-x-auto">
<table className="w-full text-xs font-mono border-collapse">
<tbody>
{file.hunks.map((hunk, hi) => (
<HunkRows
key={hi}
hunk={hunk}
filePath={file.newPath}
comments={comments}
onAddComment={onAddComment}
onResolveComment={onResolveComment}
onUnresolveComment={onUnresolveComment}
/>
))}
</tbody>
</table>
</div>
)}
</div>
);
}