Implemented comprehensive Projects UI with full CRUD functionality following modern React best practices and using shadcn/ui components. Changes: - Created ProjectForm component with react-hook-form + zod validation - Auto-uppercase project key input - Comprehensive field validation (name, key, description) - Support for both create and edit modes - Toast notifications for success/error states - Enhanced Projects List Page (app/(dashboard)/projects/page.tsx) - Beautiful card-based grid layout with hover effects - Skeleton loading states for better UX - Empty state with call-to-action - Project metadata display (key badge, created date) - Integrated ProjectForm in Dialog for creation - Enhanced Project Detail Page (app/(dashboard)/projects/[id]/page.tsx) - Comprehensive project information display - Edit functionality with dialog form - Delete functionality with confirmation AlertDialog - Epics preview section with stats - Quick actions sidebar (Kanban, Epics) - Statistics card (Total/Active/Completed epics) - Skeleton loading states - Error handling with retry capability - Added toast notifications (Sonner) - Installed and configured sonner package - Added Toaster component to root layout - Success/error notifications for all CRUD operations - Installed required dependencies - date-fns for date formatting - sonner for toast notifications - shadcn/ui alert-dialog component Technical highlights: - TypeScript with strict type checking - React Query for data fetching and caching - Optimistic updates with automatic rollback - Responsive design (mobile-friendly) - Accessibility-focused components - Clean error handling throughout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { Geist, Geist_Mono } from "next/font/google";
|
|
import "./globals.css";
|
|
import { QueryProvider } from "@/lib/providers/query-provider";
|
|
import { SignalRProvider } from "@/components/providers/SignalRProvider";
|
|
import { Toaster } from "@/components/ui/sonner";
|
|
|
|
const geistSans = Geist({
|
|
variable: "--font-geist-sans",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
const geistMono = Geist_Mono({
|
|
variable: "--font-geist-mono",
|
|
subsets: ["latin"],
|
|
});
|
|
|
|
export const metadata: Metadata = {
|
|
title: "ColaFlow - AI-Powered Project Management",
|
|
description: "Modern project management system with AI and MCP protocol",
|
|
};
|
|
|
|
export default function RootLayout({
|
|
children,
|
|
}: Readonly<{
|
|
children: React.ReactNode;
|
|
}>) {
|
|
return (
|
|
<html lang="en" suppressHydrationWarning>
|
|
<body
|
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
>
|
|
<QueryProvider>
|
|
<SignalRProvider>
|
|
{children}
|
|
<Toaster position="top-right" />
|
|
</SignalRProvider>
|
|
</QueryProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|