diff --git a/docs/database-schema-message.md b/docs/database-schema-message.md new file mode 100644 index 00000000..0fa12231 --- /dev/null +++ b/docs/database-schema-message.md @@ -0,0 +1,37 @@ +# Message Database Schema Relations + +This document outlines the database schema relations for the `messages` table within IntelliCircle, as defined in `packages/shared/src/schema.ts`. + +## The `messages` Table +The `messages` table stores the core chat content for the application. + +### Columns +- `id`: Serial Primary Key +- `roomId`: Integer (Foreign Key to `chatRooms.id`) +- `userId`: Integer (Foreign Key to `users.id`) +- `content`: Text (Not Null) +- `createdAt`: Timestamp (Defaults to now) + +### Relationships +1. **Belongs to a Room:** + Each message is tied to exactly one chat room via `roomId`. +2. **Belongs to a User:** + Each message is authored by exactly one user via `userId`. + +### Indexes +- `roomHistoryIdx`: A composite index on `(roomId, createdAt)` exists to optimize the fetching of room message history in chronological order. + +### Drizzle ORM Definition +```typescript +export const messages = pgTable("messages", { + id: serial("id").primaryKey(), + roomId: integer("room_id").notNull(), + userId: integer("user_id").notNull(), + content: text("content").notNull(), + createdAt: timestamp("created_at").notNull().defaultNow(), +}, (table) => { + return { + roomHistoryIdx: index("message_room_created_idx").on(table.roomId, table.createdAt), + }; +}); +``` diff --git a/packages/client/src/app/(app)/dashboard/loading.tsx b/packages/client/src/app/(app)/dashboard/loading.tsx new file mode 100644 index 00000000..b9ec963d --- /dev/null +++ b/packages/client/src/app/(app)/dashboard/loading.tsx @@ -0,0 +1,82 @@ +import { Activity, Compass, MessageSquare, Target } from "lucide-react"; + +export default function DashboardLoading() { + return ( +
+
+ {/* Header Section Skeleton */} +
+
+
+
+ + {/* Main Dashboard Grid Skeleton */} +
+ + {/* Left Column Skeleton */} +
+ {/* Action Cards Skeleton */} +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + {/* Recent Activity/Feed Section Skeleton */} +
+
+
+ +
+
+
+
+
+
+
+ + {/* Right Column Skeleton */} +
+ {/* Mini Profile Card Skeleton */} +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + {/* Suggestions Block Skeleton */} +
+
+ +
+
+
+
+
+
+
+
+
+
+
+ ); +} diff --git a/packages/client/src/app/(app)/dashboard/page.tsx b/packages/client/src/app/(app)/dashboard/page.tsx index 4145f36a..319e66ae 100644 --- a/packages/client/src/app/(app)/dashboard/page.tsx +++ b/packages/client/src/app/(app)/dashboard/page.tsx @@ -5,6 +5,7 @@ import { useRouter } from "next/navigation"; import { useEffect } from "react"; import Link from "next/link"; import { Compass, MessageSquare, Users, Activity, ChevronRight, Zap, Target } from "lucide-react"; +import DashboardLoading from "./loading"; export default function Dashboard() { const { isAuthenticated, user } = useAuthStore(); @@ -17,14 +18,7 @@ export default function Dashboard() { }, [isAuthenticated, router]); if (!isAuthenticated || !user) { - return ( -
-
-
-
-
-
- ); + return ; } return ( diff --git a/packages/client/src/components/auth-modal.tsx b/packages/client/src/components/auth-modal.tsx index e561b973..f093263d 100644 --- a/packages/client/src/components/auth-modal.tsx +++ b/packages/client/src/components/auth-modal.tsx @@ -99,7 +99,7 @@ export const AuthModal = () => { {mounted && createPortal( {isOpen && ( -
+
Array.isArray(val) ? val : (val ? [val] : [])) }); + +// --- WebSocket Schemas --- +export const userJoinedPayloadSchema = z.object({ + userId: z.number(), + roomId: z.number(), + timestamp: z.date().default(() => new Date()), +});