Code rabbit feedback

This commit is contained in:
Developer
2025-10-10 18:30:12 -04:00
parent 8ff39fa1d5
commit 20c57acb00
7 changed files with 105 additions and 62 deletions

View File

@@ -129,11 +129,12 @@ export function MainLayout({ children, className }: MainLayoutProps) {
}, [isBackendError, backendError, showToast]);
return (
<div className={cn("relative min-h-screen bg-white dark:bg-black overflow-hidden", className)}>
<div className={cn("relative min-h-screen overflow-hidden", className)}>
{/* TEMPORARY: Show backend startup error using old component */}
{backendStartupFailed && <BackendStartupError />}
{/* Fixed full-page background grid that doesn't scroll */}
{/* Fixed full-page background - grid pattern on dark background */}
<div className="fixed inset-0 bg-white dark:bg-black pointer-events-none -z-10" />
<div className="fixed inset-0 neon-grid pointer-events-none z-0" />
{/* Floating Navigation */}
@@ -143,7 +144,7 @@ export function MainLayout({ children, className }: MainLayoutProps) {
</div>
{/* Main Content Area - matches old layout exactly */}
<div className="relative flex-1 pl-[100px] z-10">
<div className="relative flex-1 pl-[100px]">
<div className="container mx-auto px-8 relative">
<div className="min-h-screen pt-8 pb-16">{children}</div>
</div>

View File

@@ -84,6 +84,12 @@ export const DocsTab = ({ project }: DocsTabProps) => {
setDocumentToDelete(null);
};
// Reset state when project changes
useEffect(() => {
setSelectedDocument(null);
setSearchQuery("");
}, [projectId]);
// Auto-select first document when documents load
useEffect(() => {
if (documents.length > 0 && !selectedDocument) {

View File

@@ -9,8 +9,12 @@ import {
DialogHeader,
DialogTitle,
Input,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "../../../ui/primitives";
import { cn } from "../../../ui/primitives/styles";
interface AddDocumentModalProps {
open: boolean;
@@ -48,7 +52,13 @@ export const AddDocumentModal = ({ open, onOpenChange, onAdd }: AddDocumentModal
setError(null);
onOpenChange(false);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to create document");
setError(
typeof err === "string"
? err
: err instanceof Error
? err.message
: "Failed to create document"
);
} finally {
setIsAdding(false);
}
@@ -89,25 +99,18 @@ export const AddDocumentModal = ({ open, onOpenChange, onAdd }: AddDocumentModal
<label htmlFor="document-type" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Document Type
</label>
<select
id="document-type"
value={type}
onChange={(e) => setType(e.target.value)}
disabled={isAdding}
className={cn(
"w-full px-3 py-2 rounded-md",
"bg-white/50 dark:bg-black/30",
"border border-gray-300 dark:border-gray-700",
"text-gray-900 dark:text-white",
"focus:outline-none focus:border-cyan-400 focus:ring-2 focus:ring-cyan-400/20"
)}
>
<option value="spec">Specification</option>
<option value="api">API Documentation</option>
<option value="guide">Guide</option>
<option value="note">Note</option>
<option value="design">Design</option>
</select>
<Select value={type} onValueChange={setType} disabled={isAdding}>
<SelectTrigger className="w-full" color="cyan">
<SelectValue placeholder="Select a document type" />
</SelectTrigger>
<SelectContent color="cyan">
<SelectItem value="spec" color="cyan">Specification</SelectItem>
<SelectItem value="api" color="cyan">API Documentation</SelectItem>
<SelectItem value="guide" color="cyan">Guide</SelectItem>
<SelectItem value="note" color="cyan">Note</SelectItem>
<SelectItem value="design" color="cyan">Design</SelectItem>
</SelectContent>
</Select>
</div>
</div>

View File

@@ -102,7 +102,13 @@ export const DocumentCard = memo(({ document, isActive, onSelect, onDelete }: Do
};
return (
<div
<Card
blur="none"
transparency="light"
glowColor={isActive ? (typeColors.glow as any) : "none"}
glowType="inner"
glowSize="md"
size="sm"
role="button"
tabIndex={0}
onKeyDown={handleKeyDown}
@@ -110,17 +116,8 @@ export const DocumentCard = memo(({ document, isActive, onSelect, onDelete }: Do
onMouseEnter={() => setShowDelete(true)}
onMouseLeave={() => setShowDelete(false)}
aria-label={`${isActive ? "Selected: " : ""}${document.title}`}
className="w-full"
className={cn("relative w-full cursor-pointer transition-all duration-300 group", isActive && "scale-[1.02]")}
>
<Card
blur="none"
transparency="light"
glowColor={isActive ? (typeColors.glow as any) : "none"}
glowType="inner"
glowSize="md"
size="sm"
className={cn("relative w-full cursor-pointer transition-all duration-300 group", isActive && "scale-[1.02]")}
>
<div>
{/* Document Type Badge */}
<div
@@ -181,8 +178,7 @@ export const DocumentCard = memo(({ document, isActive, onSelect, onDelete }: Do
</Button>
)}
</div>
</Card>
</div>
</Card>
);
});

View File

@@ -72,13 +72,9 @@ export const DocumentViewer = ({ document, onSave }: DocumentViewerProps) => {
// Extract content for display
const renderContent = () => {
if (!document.content) {
console.log("DocumentViewer - No content field found");
return <p className="text-gray-500 dark:text-gray-400 italic">No content available</p>;
}
console.log("DocumentViewer - Content type:", typeof document.content);
console.log("DocumentViewer - Content keys:", Object.keys(document.content));
// Handle string content
if (typeof document.content === "string") {
return (

View File

@@ -1,3 +1,4 @@
import { Activity, CheckCircle2, Eye, ListTodo } from "lucide-react";
import { useRef } from "react";
import { useDrop } from "react-dnd";
import { cn } from "../../../ui/primitives/styles";
@@ -43,12 +44,60 @@ export const KanbanColumn = ({
drop(ref);
// Get icon and label based on status
const getStatusInfo = () => {
switch (status) {
case "todo":
return {
icon: <ListTodo className="w-3 h-3" />,
label: "Todo",
color: "bg-pink-500/10 text-pink-600 dark:text-pink-400 border-pink-500/30",
};
case "doing":
return {
icon: <Activity className="w-3 h-3" />,
label: "Doing",
color: "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/30",
};
case "review":
return {
icon: <Eye className="w-3 h-3" />,
label: "Review",
color: "bg-purple-500/10 text-purple-600 dark:text-purple-400 border-purple-500/30",
};
case "done":
return {
icon: <CheckCircle2 className="w-3 h-3" />,
label: "Done",
color: "bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/30",
};
default:
return {
icon: <ListTodo className="w-3 h-3" />,
label: "Todo",
color: "bg-gray-500/10 text-gray-600 dark:text-gray-400 border-gray-500/30",
};
}
};
const statusInfo = getStatusInfo();
return (
<div ref={ref} className="flex flex-col h-full">
{/* Column Header - transparent with colored underline */}
{/* Column Header - pill badge only */}
<div className="text-center py-3 relative">
<h3 className={cn("font-mono text-sm font-medium", getColumnColor(status))}>{title}</h3>
<div className="mt-1 text-xs text-gray-500 dark:text-gray-400">{tasks.length}</div>
<div className="flex items-center justify-center">
<div
className={cn(
"inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium border backdrop-blur-md",
statusInfo.color
)}
>
{statusInfo.icon}
<span className="font-medium">{statusInfo.label}</span>
<span className="font-bold">{tasks.length}</span>
</div>
</div>
{/* Colored underline */}
<div
className={cn(
@@ -69,7 +118,7 @@ export const KanbanColumn = ({
projectId={projectId}
onTaskReorder={onTaskReorder}
onEdit={onTaskEdit}
onTaskDelete={onTaskDelete}
onDelete={onTaskDelete}
hoveredTaskId={hoveredTaskId}
onTaskHover={onTaskHover}
/>

View File

@@ -3,8 +3,9 @@ import type React from "react";
import { useCallback } from "react";
import { useDrag, useDrop } from "react-dnd";
import { isOptimistic } from "@/features/shared/utils/optimistic";
import { Card } from "../../../ui/primitives";
import { OptimisticIndicator } from "../../../ui/primitives/OptimisticIndicator";
import { cn, glassmorphism } from "../../../ui/primitives/styles";
import { cn } from "../../../ui/primitives/styles";
import { useTaskActions } from "../hooks";
import type { Assignee, Task, TaskPriority } from "../types";
import { getOrderColor, getOrderGlow, ItemTypes } from "../utils/task-styles";
@@ -125,8 +126,7 @@ export const TaskCard: React.FC<TaskCardProps> = ({
// biome-ignore lint/a11y/useSemanticElements: Drag-and-drop card with react-dnd - requires div for drag handle
<div
ref={(node) => drag(drop(node))}
role="button"
tabIndex={0}
role="group"
className={cn(
"w-full min-h-[140px] cursor-move relative group",
"transition-all duration-200 ease-in-out",
@@ -135,24 +135,16 @@ export const TaskCard: React.FC<TaskCardProps> = ({
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleTaskClick}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
if (onEdit) {
onEdit(task);
}
}
}}
>
<div
<Card
blur="md"
transparency="light"
size="none"
className={cn(
glassmorphism.background.card,
glassmorphism.border.default,
"rounded-lg backdrop-blur-md",
"transition-all duration-200 ease-in-out",
"w-full min-h-[140px] h-full",
isHighlighted && "border-cyan-400/50 shadow-[0_0_8px_rgba(34,211,238,0.2)]",
isSelected && "border-blue-500 shadow-[0_0_12px_rgba(59,130,246,0.4)] bg-blue-50/30 dark:bg-blue-900/20",
isSelected && "border-blue-500 shadow-[0_0_12px_rgba(59,130,246,0.4)]",
"group-hover:border-cyan-400/70 dark:group-hover:border-cyan-500/50 group-hover:shadow-[0_0_15px_rgba(34,211,238,0.4)] dark:group-hover:shadow-[0_0_15px_rgba(34,211,238,0.6)]",
optimistic && "opacity-80 ring-1 ring-cyan-400/30",
)}
@@ -234,7 +226,7 @@ export const TaskCard: React.FC<TaskCardProps> = ({
/>
</div>
</div>
</div>
</Card>
</div>
);
};