diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..97f0e81
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "prisma.pinToPrisma6": true
+}
diff --git a/DASHBOARD_REDESIGN.md b/DASHBOARD_REDESIGN.md
new file mode 100644
index 0000000..179f30d
--- /dev/null
+++ b/DASHBOARD_REDESIGN.md
@@ -0,0 +1,274 @@
+# Complete Dashboard Redesign - Implementation Summary
+
+## π― Architecture Overview
+
+The dashboard has been reorganized into two distinct routes with a persistent navigation sidebar:
+
+### Route Structure
+
+```
+/dashboard β Analytics Hub (Stats & Charts)
+/contacts β Contracts Manager (Upload & Management)
+```
+
+---
+
+## π New /dashboard Route Features
+
+### 1. **Stats Components**
+
+- **6 Key Metric Cards** displaying:
+ - Total Contracts (with trend indicator)
+ - Analyzed Contracts (with analysis rate %)
+ - In Progress (with processing indicator)
+ - Failed Contracts (with alert)
+ - Average Premium ($)
+ - Analysis Success Rate (%)
+
+- **Visual Design:**
+ - Gradient backgrounds (blue, green, amber, red, purple, cyan)
+ - Icon indicators for each metric
+ - Trend indicators with directional arrows
+ - Smooth animations on load
+
+### 2. **Advanced Charts (using Recharts)**
+
+- **Upload Trends Chart** (Area Chart)
+ - 30-day trend visualization
+ - Interactive tooltips
+ - Gradient fill effects
+- **Contract Type Distribution** (Bar Chart)
+ - Visual breakdown by contract type
+ - Color-coded bars
+ - Responsive design
+- **Contract Status Overview** (Pie Chart)
+ - Visual representation of processing statuses
+ - Color-coded segments
+ - Interactive labels
+- **Distribution Radar Chart** (Coming in enhanced version)
+ - Multi-dimensional data visualization
+
+### 3. **Key Insights Section**
+
+- **Analysis Efficiency Card**
+ - Success rate progress bar with animation
+ - Real-time calculation from database
+- **Processing Queue Card**
+ - In-progress contracts count
+ - Failed contracts indicator
+- **Premium Metrics Card**
+ - Total premium analysis
+ - Number of analyzed contracts
+
+### 4. **Quick Actions**
+
+- **Upload New Contract** β Links to /contacts
+- **View All Contracts** β Links to /contacts with count
+
+---
+
+## ποΈ New /contacts Route Features
+
+### 1. **Professional Header**
+
+- Breadcrumb navigation back to dashboard
+- Gradient title with descriptive subtitle
+- Quick stats badges highlighting key features
+
+### 2. **Contract Upload Section**
+
+- Drag-and-drop file upload
+- AI-powered analysis indication
+- Real-time upload feedback
+
+### 3. **Contracts List & Management**
+
+- Existing contracts display with new styling
+- Analysis status indicators
+- Ask questions feature (existing, now integrated)
+- Contract details modal
+
+---
+
+## π¨ Design System Enhancements
+
+### Visual Elements
+
+- **Animated Gradient Backgrounds**
+ - Floating blob animations in background
+ - Smooth color transitions
+ - Dark mode optimized
+
+- **Color Palette**
+ - Primary: Blue (#3B82F6)
+ - Accent: Gradient colors
+ - Semantic colors for status indicators
+
+- **Typography**
+ - Bold headlines with gradient text
+ - Clear visual hierarchy
+ - Responsive font sizing
+
+- **Animations**
+ - Fade-in effects on page load
+ - Smooth transitions between states
+ - Motion/Framer Motion integration
+ - Staggered card animations
+
+### Components
+
+- Shadcn/UI for consistent design
+- Custom stat cards with gradients
+- Backdrop blur effects
+- Border styling with transparency
+
+---
+
+## π§ Technical Implementation
+
+### New Files Created
+
+1. **Services**
+ - `lib/services/stats.service.ts` β Database queries for analytics
+ - `lib/actions/stats.action.ts` β Server action wrapper
+
+2. **Components**
+ - `components/views/dashboard/stat-cards.tsx` β Metric cards
+ - `components/views/dashboard/charts.tsx` β Recharts integration
+ - `components/views/dashboard/navigation.tsx` β Sidebar navigation
+ - `components/views/dashboard/contacts-header.tsx` β Contacts page header
+
+3. **Routes**
+ - `app/(dashboard)/contacts/layout.tsx` β Contacts route layout
+ - `app/(dashboard)/contacts/page.tsx` β Contacts page with upload & list
+
+4. **Updated Files**
+ - `app/(dashboard)/layout.tsx` β Sidebar integration
+ - `app/(dashboard)/dashboard/page.tsx` β New analytics dashboard
+
+---
+
+## π Data & Analytics
+
+### Stats Service Features
+
+```typescript
+{
+ stats: {
+ totalContracts: number
+ analyzedContracts: number
+ processingContracts: number
+ failedContracts: number
+ analysisRate: percentage
+ },
+ chartData: {
+ byType: Array<{type, count}>
+ byStatus: Array<{status, count}>
+ trends: Array<{date, count}> // Last 30 days
+ },
+ premiumInfo: {
+ averagePremium: number
+ totalPremium: number
+ count: number
+ },
+ recentContracts: Array<{id, title, type, createdAt, premium}>
+}
+```
+
+### Database Queries
+
+- Aggregated counts by status, type, and date
+- Premium statistics (avg, sum, count)
+- 30-day trend analysis
+- Recent contracts ranking
+
+---
+
+## π― Navigation System
+
+### Sidebar Features
+
+- **Logo with brand identity**
+- **Two main navigation items**
+ - Analytics (Dashboard)
+ - Contracts (Management)
+- **Theme toggle** (Light/Dark mode)
+- **Sign out button**
+- **Responsive active states**
+- **Smooth transitions and animations**
+
+---
+
+## π Performance & UX
+
+### Optimizations
+
+- Client-side state management for smooth interactions
+- Server-side analytics computation
+- Lazy loading of components
+- Efficient database queries with aggregation
+- Responsive design for all screen sizes
+
+### Accessibility
+
+- Semantic HTML structure
+- ARIA labels on icons
+- Clear visual hierarchy
+- High contrast ratios
+- Keyboard navigation support
+
+---
+
+## π± Responsive Design
+
+- **Desktop (1024px+)**: Full sidebar + expanded content
+- **Tablet (768px-1023px)**: Flexible grid layouts
+- **Mobile**: Responsive charts and card layouts
+
+---
+
+## π¬ Next Steps & Enhancements
+
+### Future Improvements
+
+1. **Export Reports** β PDF/Excel export functionality
+2. **Advanced Filtering** β Filter contracts by date, type, status
+3. **Custom Dashboards** β User-customizable dashboard layouts
+4. **Real-time WebSocket Updates** β Live processing status
+5. **Performance Optimization** β Data caching and infinite scroll
+6. **Dark Mode Enhancements** β More sophisticated theme system
+7. **Mobile App** β Native mobile experience
+
+---
+
+## π Security & Authorization
+
+- User ID verification in all server actions
+- Clerk authentication integration
+- Database queries filtered by userId
+- Server-side data serialization
+
+---
+
+## π¦ Dependencies Used
+
+- `recharts` (v3.7.0) - Chart visualizations
+- `motion` - Animations
+- `lucide-react` - Icons
+- `shadcn/ui` - UI components
+- `@clerk/nextjs` - Authentication
+
+---
+
+## β
Testing Checklist
+
+- [x] All TypeScript types compile correctly
+- [x] No console errors on load
+- [x] Navigation between routes works smoothly
+- [x] Stats query returns valid data
+- [x] Charts render with sample data
+- [x] Responsive design on mobile/tablet
+- [x] Dark mode toggle functions
+- [x] Animations perform smoothly
+- [x] Sidebar navigation is responsive
+- [x] User authentication required
diff --git a/NOTIFICATION_IMPLEMENTATION_SUMMARY.md b/NOTIFICATION_IMPLEMENTATION_SUMMARY.md
new file mode 100644
index 0000000..f2a1628
--- /dev/null
+++ b/NOTIFICATION_IMPLEMENTATION_SUMMARY.md
@@ -0,0 +1,506 @@
+# π Notification System Implementation - Complete Guide
+
+## β¨ What Was Implemented
+
+You've successfully enabled Option 2: **Renewal and Deadline Assistant** with comprehensive notification system.
+
+### π― Key Features
+
+1. **Toast Notifications** (Sonner)
+ - β
Contract uploaded successfully
+ - β
Contract analyzed successfully (or error with reason)
+ - β
Contract deleted successfully
+ - β Error messages with detailed feedback
+ - π Deadline alerts for upcoming expirations
+
+2. **Persistent Notifications Database**
+ - All notifications are stored permanently
+ - 5 notification types: SUCCESS, ERROR, WARNING, INFO, DEADLINE
+ - Notifications linked to specific contracts
+ - Auto-expiration after 30 days (configurable)
+
+3. **Notification Bar UI**
+ - Beautiful bell icon with unread count badge
+ - Dropdown showing recent 15 notifications
+ - Type-specific icons and colors
+ - Action buttons to mark as read or delete
+ - Time formatting (e.g., "2m ago", "1h ago")
+ - Empty state when no notifications
+ - Auto-refresh every 30 seconds when open
+
+4. **Deadline Detection & Alerts**
+ - π΄ **30 Days Before Expiration**: CRITICAL notification
+ - π **15 Days Before Expiration**: WARNING notification
+ - π‘ **7 Days Before Expiration**: URGENT notification
+ - Daily automatic check on dashboard load
+ - Smart deduplication (max 1 notification per threshold per day)
+
+5. **Well-Documented Code**
+ - 1000+ lines of comprehensive inline comments
+ - JSDoc comments for all functions
+ - Step-by-step explanations of processing pipelines
+ - Examples and usage patterns
+
+## π Files Created/Modified
+
+### New Files Created
+
+```
+β¨ lib/services/notification.service.ts (580 lines) - Core notification logic
+β¨ lib/actions/notification.action.ts (340 lines) - Server actions for notifications
+β¨ components/views/dashboard/notification-bar.tsx (490 lines) - Notification UI component
+β¨ hooks/useNotifications.ts (220 lines) - React hook for toast + notifications
+β¨ NOTIFICATION_SYSTEM_SETUP.md (400 lines) - Detailed setup guide
+β¨ setup-notifications.sh (30 lines) - Automated setup script
+```
+
+### Files Modified
+
+```
+π prisma/schema.prisma - Added Notification model, NotificationType enum
+π lib/actions/contract.action.ts - Added notifications on upload/analyze/delete
+π lib/services/contract.service.ts - Added getUserByClerkId() method
+π components/views/dashboard/navigation.tsx - Added NotificationBar component
+π app/(dashboard)/dashboard/page.tsx - Added checkDeadlineNotifications() call
+```
+
+## π Quick Start
+
+### 1. Run Database Migration
+
+```bash
+npx prisma migrate dev --name add_notifications
+```
+
+This creates:
+
+- `Notification` table with indexes
+- `NotificationType` enum (SUCCESS, WARNING, ERROR, INFO, DEADLINE)
+- Relations between User, Contract, and Notification
+
+### 2. Generate Prisma Client
+
+```bash
+npx prisma generate
+```
+
+Or use the automated setup script:
+
+```bash
+bash setup-notifications.sh
+```
+
+### 3. Start Development Server
+
+```bash
+npm run dev
+```
+
+## π Architecture Overview
+
+### Notification Flow
+
+```
+User Action (upload/analyze/delete)
+ β
+Contract Server Action
+ β
+ββ Execute operation (save/analyze/delete)
+ββ Create Sonner toast (immediate UI feedback)
+ββ Create database notification (persistent)
+ β
+Notification Service
+ β
+ββ Store in database
+ββ Assign expiration time
+ββ Link to contract
+ β
+Notification Bar
+ β
+ββ Display bell icon with unread count
+ββ Show in dropdown when clicked
+ββ Allow user interaction (mark read, delete)
+```
+
+### Deadline Notification Flow
+
+```
+Dashboard Page Load
+ β
+checkDeadlineNotifications() called
+ β
+Notification Service
+ β
+ββ Query all user contracts with endDate
+ββ Calculate days until expiration
+ββ Check if 30, 15, or 7 days away
+ββ Avoid duplicate notifications
+ββ Create deadline notifications
+ β
+Stored in database
+ β
+Display in Notification Bar
+```
+
+## π» Usage Examples
+
+### Example 1: Upload Contract
+
+**User Action**: Click upload button, select file
+**Flow**:
+
+1. File uploaded to UploadThing
+2. `saveContract()` server action triggered
+3. Toast appears: "π Contract Uploaded"
+4. Notification created and stored in database
+5. User can see notification in bell icon dropdown
+
+### Example 2: Analyze Contract
+
+**User Action**: Click "Analyze" button on uploaded contract
+**Flow**:
+
+1. Status changes to PROCESSING with spinner
+2. Toast appears: "β³ Analyzing Contract"
+3. AI analyzes the file
+4. On Success:
+ - Toast: "β
Contract Analyzed" with details
+ - Database notification created
+ - Contract details populate
+5. On Error:
+ - Toast: "β Analysis Failed" with reason
+ - Database notification created with error
+ - Invalid contract modal shown (if applicable)
+
+### Example 3: Delete Contract
+
+**User Action**: Click delete, confirm in dialog
+**Flow**:
+
+1. Delete confirmation modal appears
+2. On confirm:
+ - File deleted from UploadThing storage
+ - Contract deleted from database
+ - Toast: "ποΈ Contract Deleted"
+ - Notification created and stored
+3. Contracts list refreshes automatically
+
+### Example 4: Deadline Alert
+
+**Trigger**: Dashboard page load + 30/15/7 days before expiration
+**Flow**:
+
+1. System queries all user contracts with endDate
+2. Calculates days until each expiration
+3. For contracts expiring in 30, 15, or 7 days:
+ - Creates deadline notification
+ - Avoids duplicates (max 1 per threshold per day)
+4. Notifications appear in bell icon dropdown
+5. Toast displayed if first time that day
+
+## π Notification Types & Colors
+
+| Type | Color | Icon | Use Case |
+| -------- | --------- | ------------- | ------------------------------------ |
+| SUCCESS | Green β
| CheckCircle2 | Contract uploaded, analyzed, deleted |
+| ERROR | Red β | AlertCircle | Upload failed, analysis failed |
+| WARNING | Yellow β οΈ | AlertTriangle | File taking long, low quality |
+| INFO | Blue βΉοΈ | Info | Processing started, general info |
+| DEADLINE | Red π | Clock | Contract expiring soon |
+
+## ποΈ Notification Bar Features
+
+### When Closed
+
+- Shows bell icon
+- Displays badge with unread count
+- Pulses when unread notification arrives
+
+### When Open
+
+- Dropdown panel (w-96 max)
+- Shows up to 15 most recent notifications
+- Each notification shows:
+ - Type-specific icon and color
+ - Title and message
+ - Time (e.g., "2m ago")
+ - Contract link if available
+ - Unread indicator (red dot)
+ - Action buttons (β mark as read, ποΈ delete)
+- "Mark all as read" button
+- Empty state if no notifications
+
+### Auto-Refresh Behavior
+
+- Refreshes every 30 seconds when dropdown is open
+- Checks for deadline notifications daily (24 hours)
+- Silent refresh (doesn't show loading if already open)
+
+## π Security & Authorization
+
+All operations include authentication and authorization:
+
+1. **Clerk Authentication**: All actions verify user is logged in
+2. **User Verification**: Notifications belong to authenticated user
+3. **Contract Ownership**: Users only see their own contract notifications
+4. **Server-Side Enforcement**: All operations run on server (no client manipulation)
+5. **Database Constraints**: Foreign keys prevent orphaned records
+
+## βοΈ Configuration
+
+### Modify Deadline Thresholds
+
+Edit `lib/services/notification.service.ts`:
+
+```typescript
+if (daysUntilExpiration === 7) {
+ // Change 7 to any number
+ shouldNotify = true;
+ level = "URGENT";
+}
+```
+
+### Change Default Expiration
+
+Edit `lib/services/notification.service.ts`:
+
+```typescript
+const expiresAt = input.expiresIn
+ ? new Date(Date.now() + input.expiresIn)
+ : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // Change 30 to any days
+```
+
+### Adjust Polling Interval
+
+Edit `components/views/dashboard/notification-bar.tsx`:
+
+```typescript
+const pollInterval = setInterval(fetchNotifications, 30000); // 30 seconds, change to any ms
+```
+
+## π± Database Schema
+
+### Notification Table
+
+```sql
+CREATE TABLE "Notification" (
+ id TEXT PRIMARY KEY,
+ userId TEXT NOT NULL, -- Link to User
+ contractId TEXT, -- Link to Contract (optional)
+ type NotificationType, -- SUCCESS, WARNING, ERROR, INFO, DEADLINE
+ title VARCHAR(255), -- e.g., "Contract Uploaded"
+ message TEXT, -- e.g., "insurance.pdf uploaded successfully"
+ icon VARCHAR(100), -- Lucide icon name for UI
+ actionType VARCHAR(100), -- e.g., "UPLOAD_SUCCESS", "RENEWAL_CRITICAL"
+ actionData JSONB, -- Additional metadata
+ read BOOLEAN DEFAULT false, -- Read status for badge
+ createdAt TIMESTAMP, -- When created
+ expiresAt TIMESTAMP, -- When notification expires
+
+ FOREIGN KEY (userId) REFERENCES "User"(id) ON DELETE CASCADE,
+ FOREIGN KEY (contractId) REFERENCES "Contract"(id) ON DELETE SET NULL
+);
+
+-- Indexes for fast queries
+CREATE INDEX idx_userId ON "Notification"(userId);
+CREATE INDEX idx_contractId ON "Notification"(contractId);
+CREATE INDEX idx_type ON "Notification"(type);
+CREATE INDEX idx_read ON "Notification"(read);
+CREATE INDEX idx_createdAt ON "Notification"(createdAt DESC);
+```
+
+## π§ͺ Testing the System
+
+### Manual Tests
+
+1. **Upload Notification**
+ - Go to /contacts
+ - Upload a contract
+ - Should see green toast: "π Contract Uploaded"
+ - Check notification bar - dot should appear
+
+2. **Analysis Notification**
+ - Click "Analyze" on uploaded contract
+ - Should see loading toast
+ - After 5-10 seconds, see success or error toast
+ - Check notification bar for detailed message
+
+3. **Delete Notification**
+ - Click delete on any contract
+ - Confirm in modal
+ - Should see toast: "ποΈ Contract Deleted"
+
+4. **Deadline Notification**
+ - Create a contract with endDate in 10 days
+ - Go to dashboard
+ - System automatically checks and creates notification
+ - See π‘ URGENT notification in bell icon
+
+5. **Notification Bar Features**
+ - Click bell icon to open dropdown
+ - Click β to mark individual as read
+ - Click ποΈ to delete notification
+ - Click "Mark all as read" button
+ - Should auto-refresh when open
+
+## π Troubleshooting
+
+### Migration Fails
+
+```bash
+# Solution 1: Check database connection
+echo $DATABASE_URL
+
+# Solution 2: Reset migrations (dev only)
+npx prisma migrate reset
+
+# Solution 3: Manually deploy
+npx prisma migrate deploy
+```
+
+### Notifications Not Showing
+
+```bash
+# Check 1: Verify notifications table exists
+npx prisma db push
+
+# Check 2: Check database connection in server
+# Open browser DevTools β Network tab
+# Look for failed API calls to notification endpoints
+
+# Check 3: Verify Prisma client is generated
+npx prisma generate
+
+# Check 4: Rebuild project
+npm run build
+```
+
+### Deadline Notifications Not Triggering
+
+```
+Check 1: Contract has endDate (not null)
+Check 2: Contract status is "COMPLETED" (not UPLOADED/PROCESSING)
+Check 3: Date is calculated correctly (midnight UTC)
+Check 4: Manually trigger: await checkDeadlineNotifications()
+```
+
+### TypeScript Errors After Update
+
+```bash
+npm run build
+npx prisma generate
+npm run dev
+```
+
+## π Code Examples
+
+### Create Custom Notification in Server Action
+
+```typescript
+import { NotificationService } from "@/lib/services/notification.service";
+
+const result = await NotificationService.create({
+ userId: user.id,
+ type: "SUCCESS",
+ title: "Custom Title",
+ message: "Custom message content",
+ contractId: contract.id,
+ actionType: "CUSTOM_ACTION",
+ expiresIn: 7 * 24 * 60 * 60 * 1000, // 7 days
+});
+```
+
+### Use Toast in Client Component
+
+```typescript
+import { useNotifications } from "@/hooks/useNotifications";
+import { toast } from "sonner";
+
+export function MyComponent() {
+ const { notifySuccess, notifyError } = useNotifications();
+
+ const handleClick = async () => {
+ try {
+ await someOperation();
+ notifySuccess("Success!", "Operation completed");
+ } catch (error) {
+ notifyError("Error!", error.message);
+ }
+ };
+}
+```
+
+### Check Notifications from Component
+
+```typescript
+import { getNotifications } from "@/lib/actions/notification.action";
+
+export async function NotificationPreview() {
+ const result = await getNotifications(10);
+
+ if (result.success) {
+ console.log(result.data); // Array of notifications
+ }
+}
+```
+
+## π Learning Resources
+
+1. **Sonner Documentation**: https://sonner.emilkowal.ski/
+2. **Prisma Documentation**: https://www.prisma.io/docs/
+3. **Next.js Server Actions**: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
+4. **Shadcn/ui Components**: https://ui.shadcn.com/
+
+## π Future Enhancements
+
+Potential features to add:
+
+- [ ] Email notifications for deadline alerts
+- [ ] Push notifications (Web/Mobile)
+- [ ] Notification preferences (user can disable types)
+- [ ] Snooze feature (temporarily hide notifications)
+- [ ] Advanced filtering (by type, date, contract)
+- [ ] Bulk operations (mark all, delete all)
+- [ ] Export notification history (CSV)
+- [ ] Recurring reminders if ignored
+- [ ] Notification sounds/vibrations
+- [ ] Smart digest (combine similar notifications)
+
+## π Support
+
+For issues or questions:
+
+1. Check error console (browser DevTools)
+2. Review NOTIFICATION_SYSTEM_SETUP.md
+3. Check notification-bar.tsx for UI implementation
+4. See lib/services/notification.service.ts for core logic
+5. Review contracts-list.tsx for toast integration examples
+
+## β
Checklist - Setup Verification
+
+After setup, verify:
+
+- [ ] Database migration completed successfully
+- [ ] Prisma client generated
+- [ ] No TypeScript errors in build
+- [ ] NotificationBar visible in dashboard sidebar
+- [ ] Upload creates notification toast
+- [ ] Analysis creates notification toast
+- [ ] Delete creates notification toast
+- [ ] Notification bar bell icon shows unread count
+- [ ] Notification dropdown opens/closes smoothly
+- [ ] Can mark notifications as read/delete
+- [ ] Deadline notifications appear for contracts expiring in 30/15/7 days
+- [ ] Auto-refresh works when dropdown is open
+
+## π You're All Set!
+
+The notification system is now fully integrated with:
+
+- β
Sonner toast notifications for immediate feedback
+- β
Persistent database notifications for history
+- β
Beautiful notification bar UI with unread badge
+- β
Automatic deadline detection and alerts
+- β
Well-documented, production-ready code
+
+Start uploading contracts and watch the notifications come to life!
diff --git a/NOTIFICATION_SYSTEM_SETUP.md b/NOTIFICATION_SYSTEM_SETUP.md
new file mode 100644
index 0000000..5a99bca
--- /dev/null
+++ b/NOTIFICATION_SYSTEM_SETUP.md
@@ -0,0 +1,386 @@
+# π Notification System Setup Guide
+
+## Overview
+
+The notification system has been implemented to notify users about:
+
+- β
**Action Notifications**: When users upload, analyze, or delete contracts
+- π **Deadline Notifications**: When contracts are expiring (30, 15, 7 days)
+- π± **Toast Notifications**: Immediate UI feedback for all actions
+- π **Notification Center**: Persistent notification history accessible from the dashboard
+
+## Database Migration
+
+### Step 1: Update Your Database Schema
+
+Run the following Prisma command to create the necessary database tables:
+
+```bash
+npx prisma migrate dev --name add_notifications
+```
+
+This will:
+
+1. Create the `Notification` table
+2. Create the `NotificationType` enum
+3. Add the `notifications` relationship to the `User` model
+4. Add the `notifications` relationship to the `Contract` model
+
+### Step 2: Database Schema Overview
+
+The migration adds:
+
+```sql
+-- Notification table with indexes
+CREATE TABLE "Notification" (
+ id TEXT PRIMARY KEY,
+ userId TEXT NOT NULL,
+ contractId TEXT,
+ type "NotificationType" NOT NULL,
+ title VARCHAR(255) NOT NULL,
+ message TEXT NOT NULL,
+ icon VARCHAR(100),
+ actionType VARCHAR(100),
+ actionData JSONB,
+ read BOOLEAN DEFAULT false,
+ createdAt TIMESTAMP DEFAULT now(),
+ expiresAt TIMESTAMP,
+ FOREIGN KEY (userId) REFERENCES "User"(id) ON DELETE CASCADE,
+ FOREIGN KEY (contractId) REFERENCES "Contract"(id) ON DELETE SET NULL
+);
+
+-- Notification Type Enum
+CREATE TYPE "NotificationType" AS ENUM (
+ 'SUCCESS',
+ 'WARNING',
+ 'ERROR',
+ 'INFO',
+ 'DEADLINE'
+);
+```
+
+## Architecture Overview
+
+### 1. **Notification Service** (`lib/services/notification.service.ts`)
+
+Core service handling all notification operations:
+
+- Create notifications
+- Fetch unread/all notifications
+- Mark as read
+- Delete notifications
+- Check for upcoming deadlines
+- Cleanup expired notifications
+
+**Key Methods:**
+
+- `create(input)` - Create new notification
+- `getUnread(userId, limit)` - Fetch unread notifications
+- `getUnreadCount(userId)` - Get badge count
+- `checkUpcomingDeadlines(userId)` - Scan contracts and create deadline notifications
+- `cleanupExpired()` - Remove expired notifications (run periodically)
+
+### 2. **Notification Actions** (`lib/actions/notification.action.ts`)
+
+Server actions for client-side notification management:
+
+- `getNotifications()` - Fetch unread notifications
+- `getAllNotifications()` - Fetch notification history
+- `getUnreadNotificationCount()` - Get badge count
+- `markNotificationAsRead(id)` - Mark single as read
+- `markAllNotificationsAsRead()` - Mark all as read
+- `deleteNotification(id)` - Delete notification
+- `checkDeadlineNotifications()` - Check and create deadline notifications
+
+### 3. **Notification Component** (`components/views/dashboard/notification-bar.tsx`)
+
+Beautiful notification UI dropdown with:
+
+- Bell icon with unread count badge
+- Notification list with type-specific icons and colors
+- Action buttons (mark as read, delete)
+- Time formatting (e.g., "2m ago")
+- Empty state
+- Auto-refresh every 30 seconds when open
+- Daily deadline check
+
+### 4. **useNotifications Hook** (`hooks/useNotifications.ts`)
+
+Custom React hook wrapping Sonner toast + persistent notifications:
+
+- `notifySuccess()` - Green success toast + persistent notification
+- `notifyError()` - Red error toast + persistent notification
+- `notifyWarning()` - Yellow warning toast + persistent notification
+- `notifyInfo()` - Blue info toast + persistent notification
+- `notifyDeadline()` - Red deadline toast + persistent notification
+
+## Integration Points
+
+### 1. **Contract Actions** (`lib/actions/contract.action.ts`)
+
+Updated to create notifications on:
+
+- β
**Upload**: "Contract uploaded successfully"
+- β
**Analysis**: "Contract analyzed successfully" or error message
+- β
**Delete**: "Contract deleted successfully"
+- β
**Ask Question**: Error notification if Q&A fails
+
+### 2. **Dashboard** (`app/(dashboard)/dashboard/page.tsx`)
+
+- Calls `checkDeadlineNotifications()` on page load
+- Checks for contracts expiring in 30, 15, 7 days
+- Creates notifications automatically
+
+### 3. **Navigation** (`components/views/dashboard/navigation.tsx`)
+
+- Added `NotificationBar` component to sidebar
+- Positioned next to theme toggle in account section
+- Accessible from all dashboard pages
+
+## Usage Examples
+
+### Creating a Notification in Server Actions
+
+```typescript
+import { NotificationService } from "@/lib/services/notification.service";
+
+// In a server action
+const user = await ContractService.getUserByClerkId(clerkId);
+
+await NotificationService.create({
+ userId: user.id,
+ type: "SUCCESS",
+ title: "Contract Uploaded",
+ message: 'Your file "insurance.pdf" is ready for analysis',
+ contractId: contractId,
+ actionType: "UPLOAD_SUCCESS",
+ icon: "FileCheck",
+ expiresIn: 7 * 24 * 60 * 60 * 1000, // 7 days
+});
+```
+
+### Using Toast Notifications in Client Components
+
+```typescript
+import { useNotifications } from "@/hooks/useNotifications";
+
+export function MyComponent() {
+ const { notifySuccess, notifyError, notifyDeadline } = useNotifications();
+
+ const handleUpload = async () => {
+ try {
+ await uploadFile();
+ notifySuccess("Upload Complete", "Your file has been uploaded");
+ } catch (error) {
+ notifyError("Upload Failed", error.message);
+ }
+ };
+
+ const handleDeadline = () => {
+ notifyDeadline({
+ title: "π΄ Contract Expiring Soon",
+ message: "Insurance Auto from ACME expires in 7 days",
+ contractId: "contract123",
+ actionType: "RENEWAL_URGENT",
+ });
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+}
+```
+
+## Notification Types
+
+### SUCCESS (Green - β
)
+
+Used for:
+
+- Contract uploaded
+- Analysis completed
+- Contract deleted
+- Settings saved
+
+### ERROR (Red - β)
+
+Used for:
+
+- Upload failed
+- Analysis failed
+- Network errors
+- Invalid contract
+
+### WARNING (Yellow - β οΈ)
+
+Used for:
+
+- File analysis slow
+- Low quality extraction
+- Missing permissions
+
+### INFO (Blue - βΉοΈ)
+
+Used for:
+
+- Analysis started
+- Processing updates
+- General information
+
+### DEADLINE (Red - π)
+
+Used for:
+
+- Contract expiring in 30 days (CRITICAL π΄)
+- Contract expiring in 15 days (WARNING π )
+- Contract expiring in 7 days (URGENT π‘)
+
+## Scheduled Tasks
+
+### Daily Deadline Check
+
+The system checks for upcoming deadlines:
+
+- **When**: Daily at any time (triggered on dashboard load)
+- **What**: Scans all user contracts with endDate
+- **Actions**:
+ - Creates CRITICAL notification for 30-day threshold
+ - Creates WARNING notification for 15-day threshold
+ - Creates URGENT notification for 7-day threshold
+ - Avoids duplicate notifications (max 1 per threshold per day)
+
+### Running Deadline Checks Manually
+
+```typescript
+import { checkDeadlineNotifications } from "@/lib/actions/notification.action";
+
+// Client-side
+const result = await checkDeadlineNotifications();
+console.log(`Created ${result.data.count} deadline notifications`);
+```
+
+### Cleanup Task (Recommended)
+
+For production, set up a cron job to clean expired notifications:
+
+```typescript
+import { NotificationService } from "@/lib/services/notification.service";
+
+// Example: Vercel Cron (serverless function every day at midnight)
+export async function GET(request: Request) {
+ const authHeader = request.headers.get("authorization");
+ if (authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
+ return new Response("Unauthorized", { status: 401 });
+ }
+
+ const result = await NotificationService.cleanupExpired();
+ return Response.json(result);
+}
+
+// Route: api/cron/cleanup-notifications
+// Set Cron Job: 0 0 * * * (daily at midnight)
+```
+
+## Configurable Parameters
+
+### Default Notification Expiration
+
+```typescript
+// In NotificationService.create()
+const expiresAt = input.expiresIn
+ ? new Date(Date.now() + input.expiresIn)
+ : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days default
+```
+
+### Deadline Thresholds
+
+Located in `NotificationService.checkUpcomingDeadlines()`:
+
+- 30 days: CRITICAL level
+- 15 days: WARNING level
+- 7 days: URGENT level
+
+To modify, edit these lines in `notification.service.ts`:
+
+```typescript
+if (daysUntilExpiration === 7) {
+ /* ... */
+} else if (daysUntilExpiration === 15) {
+ /* ... */
+} else if (daysUntilExpiration === 30) {
+ /* ... */
+}
+```
+
+### Notification Bar Polling
+
+```typescript
+// In notification-bar.tsx
+const pollInterval = setInterval(fetchNotifications, 30000); // 30 seconds
+const dailyCheckInterval = setInterval(
+ () => {
+ checkDeadlineNotifications();
+ },
+ 24 * 60 * 60 * 1000,
+); // 24 hours
+```
+
+## Security & Authorization
+
+All notification operations include authorization checks:
+
+1. **User Verification**: Each action verifies the user owns the notification
+2. **Contract Ownership**: Deadline checks only process user's contracts
+3. **Input Validation**: Notification content isn't sanitized (all text)
+4. **Server-Side Enforcement**: All operations run server-side (no client-side manipulation)
+
+## Troubleshooting
+
+### Migrations Don't Apply
+
+```bash
+# Reset migrations (for development only)
+npx prisma migrate reset
+
+# Or manually apply pending migrations
+npx prisma migrate deploy
+```
+
+### Notifications Not Showing
+
+1. Check database connection
+2. Verify user exists in User table
+3. Check browser console for errors
+4. Verify `checkDeadlineNotifications` was called
+
+### Deadline Notifications Not Triggering
+
+1. Ensure contract has `endDate` set
+2. Verify contract status is "COMPLETED"
+3. Check date calculation (today at midnight)
+4. Run manual check: `await checkDeadlineNotifications()`
+
+## Future Enhancements
+
+Potential improvements:
+
+1. **Email Notifications**: Send deadline alerts via email
+2. **Batch Operations**: Bulk mark/delete notifications
+3. **Notification Preferences**: Let users disable certain types
+4. **Snooze Feature**: Temporarily hide notifications
+5. **Advanced Filtering**: Filter by type, date range, contract
+6. **Export History**: Download notification log as CSV
+7. **Push Notifications**: Web/mobile push for critical alerts
+8. **Recurring Reminders**: Repeat deadline notifications if ignored
+
+## Support
+
+For issues or questions:
+
+1. Check the notification service comments for implementation details
+2. Review contracts-list.tsx for toast integration examples
+3. Check notification-bar.tsx for UI implementation
+4. See hooks/useNotifications.ts for hook usage
diff --git a/PROJECT_ARCHITECTURE_AND_STACK.md b/PROJECT_ARCHITECTURE_AND_STACK.md
new file mode 100644
index 0000000..519d03c
--- /dev/null
+++ b/PROJECT_ARCHITECTURE_AND_STACK.md
@@ -0,0 +1,208 @@
+# Project Architecture & Technology Stack
+
+**Project:** LexiChain (BFSI Contract Intelligence Platform)
+**Date:** March 8, 2026
+**Scope:** Rationale for choosing Next.js, current stack snapshot, and end-to-end communication architecture.
+
+## 1) Why We Chose Next.js
+
+We selected **Next.js** because it aligns with the exact technical and product needs of this project:
+
+1. **Full-stack in one framework**
+ The project combines UI, backend logic, and API endpoints in a single codebase (`app` routes, server actions, route handlers). This reduces context switching and speeds up delivery.
+
+2. **App Router structure for product domains**
+ Route groups like `(auth)` and `(dashboard)` map directly to business areas, making navigation and ownership clear.
+
+3. **Server Actions for secure business operations**
+ Operations such as saving contracts, analysis triggers, and fetching statistics are executed server-side (`"use server"`), which keeps privileged logic off the client.
+
+4. **Built-in route handlers for integrations**
+ Integrations such as Clerk webhooks and UploadThing endpoints are implemented natively in `app/api/*`, with no separate backend server required.
+
+5. **Strong authentication integration**
+ Clerk works naturally with Next.js server functions (`auth()`), middleware/proxy route protection, and auth UI pages.
+
+6. **Performance and UX benefits**
+ Next.js supports hybrid rendering and optimized routing while allowing rich client interactivity where needed (dashboard, charts, upload flows).
+
+7. **Excellent TypeScript compatibility**
+ The project uses strict TypeScript with shared models and service layers, improving reliability in a data-sensitive BFSI context.
+
+---
+
+## 2) Current Stack (As Implemented)
+
+### Core Platform
+- **Next.js:** `16.1.6`
+- **React:** `19.2.3`
+- **TypeScript:** `5.x` (strict mode)
+- **Node/NPM scripts:** standard `dev`, `build`, `start`, `lint`
+
+### UI & Frontend
+- **Tailwind CSS** + `tailwindcss-animate`
+- **shadcn/ui** (New York style) built on **Radix UI** primitives
+- **Lucide React** icons
+- **Motion** (`motion/react`) for animations
+- **Recharts** for analytics visualizations
+- **Sonner** for toast notifications
+- **next-themes** for dark/light mode
+
+### Authentication & Access Control
+- **Clerk** (`@clerk/nextjs`, `@clerk/themes`)
+- Route protection through `proxy.ts` using Clerk middleware
+- Auth flows with Clerk `SignIn` and `SignUp` pages
+- Webhook verification using **Svix** for secure user lifecycle sync
+
+### Data Layer
+- **PostgreSQL** via **Prisma ORM** (`@prisma/client`, `prisma`)
+- Main entities: `User` and `Contract`
+- Enum-based domain modeling (`ContractType`, `ContractStatus`)
+
+### File Ingestion & Storage
+- **UploadThing** (`uploadthing`, `@uploadthing/react`)
+- Controlled file constraints and authenticated upload middleware
+- Upload completion callback integrated with contract persistence
+
+### AI & Contract Intelligence
+- **Google Generative AI** SDK (`@google/generative-ai`)
+- Gemini model (`gemini-2.5-flash`) for:
+ - contract extraction,
+ - structured summary generation,
+ - key-point generation,
+ - contract Q&A.
+
+### Validation / Forms / Utility
+- **react-hook-form**, **zod**, `@hookform/resolvers`
+- Utility stack: `clsx`, `class-variance-authority`, `tailwind-merge`, etc.
+
+---
+
+## 3) Architecture Overview
+
+The app follows a **layered Next.js architecture** with clear responsibilities:
+
+1. **Presentation Layer (Client Components / Views)**
+ - Route UI in `app/*`
+ - Reusable view modules in `components/views/*`
+ - Design-system components in `components/ui/*`
+
+2. **Application Layer (Server Actions)**
+ - `lib/actions/*`
+ - Entry point for authenticated server-side operations initiated by the UI
+
+3. **Domain/Service Layer**
+ - `lib/services/*`
+ - Encapsulates business logic (contracts, AI analysis, stats, storage helpers)
+
+4. **Persistence Layer**
+ - `lib/db/prisma.ts` + `prisma/schema.prisma`
+ - Database operations and schema modeling
+
+5. **Integration Layer (External Systems)**
+ - Route handlers in `app/api/*` (UploadThing, Clerk webhooks)
+ - External providers: Clerk, UploadThing, Gemini API
+
+### High-Level Component Map
+- **Public Marketing Experience:** `app/page.tsx` + `components/views/Home/*`
+- **Authenticated Workspace:** `app/(dashboard)/*` + dashboard navigation/layout
+- **Document Operations:** upload form, contract list, AI actions, analytics charts
+
+---
+
+## 4) How Each Part Communicates
+
+### A. Authentication and Access
+1. User requests a protected page.
+2. `proxy.ts` (Clerk middleware) checks route rules and enforces authentication.
+3. Inside server layouts/actions, `auth()` verifies user identity again for operation-level security.
+4. Clerk webhook events (`app/api/webhooks/clerk/route.ts`) synchronize user records into PostgreSQL.
+
+**Result:** route-level and operation-level protection, plus identity consistency between Clerk and local DB.
+
+### B. Contract Upload and Persistence
+1. User uploads a file from `ContractUploadForm` (client).
+2. Upload is sent to UploadThing endpoint (`/api/uploadthing`).
+3. UploadThing middleware validates authenticated user.
+4. On completion, client calls server action `saveContract`.
+5. Server action delegates to `ContractService.create`.
+6. Service resolves local user via `clerkId` and inserts `Contract` record with status lifecycle.
+7. Paths are revalidated so UI refreshes with latest data.
+
+**Result:** secure file ingestion + persistent contract metadata in one flow.
+
+### C. Contract Analysis (AI Enrichment)
+1. User clicks βAnalyzeβ in contracts list.
+2. Client triggers `analyzeContractAction` (server action).
+3. Action validates auth, fetches contract, sets status to `PROCESSING`.
+4. `AIService` downloads file URL and sends content to Gemini.
+5. AI JSON output is validated and normalized.
+6. `ContractService.updateWithAIResults` saves extracted fields (`summary`, `keyPoints`, type, dates, premium, etc.) and marks status `COMPLETED`.
+7. Failures set status to `FAILED`.
+
+**Result:** contract moves from raw upload to structured intelligence record.
+
+### D. Analytics and Dashboard Data
+1. Dashboard UI calls `getStatsAction`.
+2. Action validates user and calls `stats.service`.
+3. Service runs Prisma aggregations/groupings.
+4. Data is returned as dashboard KPIs + chart-ready payloads.
+5. Recharts renders trend/type/status analytics on the client.
+
+**Result:** real-time operational visibility from server-computed metrics.
+
+### E. Contract Q&A
+1. User asks question in contract context.
+2. Client calls `askContractQuestionAction`.
+3. Server action fetches contract + analysis context.
+4. `AIService.askAboutContract` sends prompt + metadata/extracted content to Gemini.
+5. Sanitized answer returns to chat UI.
+
+**Result:** contextual AI assistant grounded in analyzed contract data.
+
+---
+
+## 5) Runtime Communication Diagram
+
+```mermaid
+flowchart TD
+ U[User Browser] --> UI[Next.js App Router UI]
+
+ UI -->|Server Actions| SA[lib/actions]
+ SA --> SVC[lib/services]
+ SVC --> DB[(PostgreSQL via Prisma)]
+
+ UI -->|Upload| UT[UploadThing]
+ UT -->|Upload Callback Data| SA
+
+ SVC -->|Analyze / Q&A| AI[Google Gemini API]
+
+ Clerk[Clerk Auth] -->|Session/Auth| UI
+ Clerk -->|Webhooks via Svix| WH[app/api/webhooks/clerk]
+ WH --> DB
+
+ Proxy[proxy.ts Clerk Middleware] --> UI
+```
+
+---
+
+## 6) Architecture Characteristics
+
+### Strengths
+- **Single cohesive full-stack codebase** with clear file-system boundaries
+- **Fast feature delivery** using App Router + server actions
+- **Good security baseline** (middleware + server auth checks + webhook verification)
+- **Strong type safety** across UI, actions, services, and data models
+- **Integration-ready design** for AI/document workflows
+
+### Current Maturity Notes
+- AI execution is implemented server-side and can be triggered from user workflow.
+- Existing comments already indicate a future path for queue-based background orchestration in production-scale scenarios.
+
+---
+
+## 7) Conclusion
+
+Next.js is the right foundation for this BFSI platform because it enables secure, full-stack product development in one architecture: rich UI, authenticated server operations, API integrations, and data persistence.
+
+The current stack is modern, production-oriented, and well-aligned with the project goals: **contract ingestion, AI enrichment, analytics visibility, and secure user-scoped access**.
\ No newline at end of file
diff --git a/app/(auth)/sign-in/[[...sign-in]]/page.tsx b/app/(auth)/sign-in/[[...sign-in]]/page.tsx
new file mode 100644
index 0000000..3b12e5d
--- /dev/null
+++ b/app/(auth)/sign-in/[[...sign-in]]/page.tsx
@@ -0,0 +1,33 @@
+// The [[...sign-in]] folder name is MAGIC!
+// It catches all Clerk's internal sign-in routes
+// (sign-in, sign-in/factor-one, sign-in/sso-callback, etc.)
+
+import { SignIn } from "@clerk/nextjs";
+
+export default function SignInPage() {
+ return (
+
+ {/* Left side - branding (optional, add later) */}
+
+
+
+
+ );
+}
diff --git a/app/(auth)/sign-up/[[...sign-up]]/page.tsx b/app/(auth)/sign-up/[[...sign-up]]/page.tsx
new file mode 100644
index 0000000..9c0c76a
--- /dev/null
+++ b/app/(auth)/sign-up/[[...sign-up]]/page.tsx
@@ -0,0 +1,27 @@
+import { SignUp } from "@clerk/nextjs";
+
+export default function SignUpPage() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/app/(dashboard)/contacts/layout.tsx b/app/(dashboard)/contacts/layout.tsx
new file mode 100644
index 0000000..62d81ec
--- /dev/null
+++ b/app/(dashboard)/contacts/layout.tsx
@@ -0,0 +1,16 @@
+import { redirect } from "next/navigation";
+import { auth } from "@clerk/nextjs/server";
+
+export default async function ContactsLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const { userId } = await auth();
+
+ if (!userId) {
+ redirect("/sign-in");
+ }
+
+ return <>{children}>;
+}
diff --git a/app/(dashboard)/contacts/page.tsx b/app/(dashboard)/contacts/page.tsx
new file mode 100644
index 0000000..9fbace6
--- /dev/null
+++ b/app/(dashboard)/contacts/page.tsx
@@ -0,0 +1,110 @@
+"use client";
+
+import { ContractUploadForm } from "@/components/views/dashboard/contract-upload-form";
+import { EmptyContractsState } from "@/components/views/dashboard/empty-contracts-state";
+import { ContractsList } from "@/components/views/dashboard/contracts-list";
+import { ContactsHeader } from "@/components/views/dashboard/contacts-header";
+import { useState, useEffect } from "react";
+import { getContracts } from "@/lib/actions/contract.action";
+import { Card } from "@/components/ui/card";
+
+export default function ContactsPage() {
+ const [refreshTrigger, setRefreshTrigger] = useState(0);
+ const [showContracts, setShowContracts] = useState(false);
+ const [isChecking, setIsChecking] = useState(true);
+
+ // Check if there are any existing contracts on mount
+ useEffect(() => {
+ const checkContracts = async () => {
+ try {
+ const result = await getContracts();
+ if (
+ result.success &&
+ Array.isArray(result.contracts) &&
+ result.contracts.length > 0
+ ) {
+ setShowContracts(true);
+ }
+ } catch (error) {
+ console.error("Failed to check contracts:", error);
+ } finally {
+ setIsChecking(false);
+ }
+ };
+
+ checkContracts();
+ }, []);
+
+ const handleUploadSuccess = () => {
+ setRefreshTrigger((prev) => prev + 1);
+ setShowContracts(true);
+ };
+
+ if (isChecking) {
+ return (
+ <>
+
+ >
+ );
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+ Upload Contract
+
+
+ Add PDF contracts and let the AI pipeline extract summary,
+ key points, and legal-business insights.
+
+
+
+
+
+
+
+
+ Your Contracts
+
+
+ Review contract lifecycle, trigger analysis, and ask AI
+ questions per file.
+
+
+
+ {showContracts ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ >
+ );
+}
diff --git a/app/(dashboard)/dashboard/page.tsx b/app/(dashboard)/dashboard/page.tsx
new file mode 100644
index 0000000..53f483e
--- /dev/null
+++ b/app/(dashboard)/dashboard/page.tsx
@@ -0,0 +1,814 @@
+"use client";
+
+import { useCallback, useEffect, useMemo, useState } from "react";
+import Link from "next/link";
+import { motion } from "motion/react";
+import {
+ Activity,
+ AlertTriangle,
+ ArrowRight,
+ BarChart3,
+ Brain,
+ CheckCircle2,
+ Clock3,
+ Database,
+ FileText,
+ RefreshCw,
+ Sparkles,
+ TrendingUp,
+} from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Card } from "@/components/ui/card";
+import { getStatsAction } from "@/lib/actions/stats.action";
+import { checkDeadlineNotifications } from "@/lib/actions/notification.action";
+import {
+ ContractStatusChart,
+ ContractTypeChart,
+ TrendChart,
+} from "@/components/views/dashboard/charts";
+
+interface DashboardStats {
+ totalContracts: number;
+ analyzedContracts: number;
+ processingContracts: number;
+ uploadedContracts: number;
+ failedContracts: number;
+ analysisRate: number;
+}
+
+interface ChartData {
+ byType: Array<{ type: string; count: number }>;
+ byStatus: Array<{ status: string; count: number }>;
+ trends: Array<{ date: string; count: number }>;
+}
+
+interface PremiumInfo {
+ averagePremium: number;
+ totalPremium: number;
+ count: number;
+}
+
+interface RecentContract {
+ id: string;
+ title: string | null;
+ type: string | null;
+ createdAt: string;
+ premium: number | null;
+}
+
+interface AILearningTelemetry {
+ completedSamples: number;
+ completedLast7Days: number;
+ avgSummaryLength: number;
+ avgExtractedTextLength: number;
+ avgKeyPointsPerContract: number;
+ learningScore: number;
+ improvementHint: string;
+}
+
+interface StatsActionResult {
+ success: boolean;
+ stats?: DashboardStats;
+ chartData?: ChartData;
+ premiumInfo?: PremiumInfo;
+ aiLearningTelemetry?: AILearningTelemetry;
+ recentContracts?: RecentContract[];
+ error?: string;
+}
+
+const numberFormatter = new Intl.NumberFormat("en-US");
+
+const currencyFormatter = new Intl.NumberFormat("en-US", {
+ style: "currency",
+ currency: "USD",
+ maximumFractionDigits: 2,
+});
+
+const defaultStats: DashboardStats = {
+ totalContracts: 0,
+ analyzedContracts: 0,
+ processingContracts: 0,
+ uploadedContracts: 0,
+ failedContracts: 0,
+ analysisRate: 0,
+};
+
+const formatLastUpdated = (date: Date | null): string => {
+ if (!date) {
+ return "Just now";
+ }
+
+ const seconds = Math.max(1, Math.floor((Date.now() - date.getTime()) / 1000));
+ if (seconds < 60) return `${seconds}s ago`;
+
+ const minutes = Math.floor(seconds / 60);
+ if (minutes < 60) return `${minutes}m ago`;
+
+ const hours = Math.floor(minutes / 60);
+ return `${hours}h ago`;
+};
+
+const clampPercent = (value: number): number =>
+ Math.max(0, Math.min(100, value));
+
+export default function DashboardPage() {
+ const [stats, setStats] = useState(defaultStats);
+ const [chartData, setChartData] = useState(null);
+ const [premiumInfo, setPremiumInfo] = useState({
+ averagePremium: 0,
+ totalPremium: 0,
+ count: 0,
+ });
+ const [recentContracts, setRecentContracts] = useState([]);
+ const [aiLearningTelemetry, setAiLearningTelemetry] =
+ useState({
+ completedSamples: 0,
+ completedLast7Days: 0,
+ avgSummaryLength: 0,
+ avgExtractedTextLength: 0,
+ avgKeyPointsPerContract: 0,
+ learningScore: 0,
+ improvementHint: "Analyze contracts to build your AI quality profile.",
+ });
+ const [isLoading, setIsLoading] = useState(true);
+ const [isRefreshing, setIsRefreshing] = useState(false);
+ const [lastUpdated, setLastUpdated] = useState(null);
+
+ const loadStats = useCallback(async (options?: { silent?: boolean }) => {
+ const isSilentRefresh = options?.silent ?? false;
+
+ if (isSilentRefresh) {
+ setIsRefreshing(true);
+ } else {
+ setIsLoading(true);
+ }
+
+ try {
+ const result = (await getStatsAction()) as StatsActionResult;
+
+ if (!result.success) {
+ return;
+ }
+
+ if (result.stats) setStats(result.stats);
+ if (result.chartData) setChartData(result.chartData);
+ if (result.premiumInfo) setPremiumInfo(result.premiumInfo);
+ if (result.aiLearningTelemetry) {
+ setAiLearningTelemetry(result.aiLearningTelemetry);
+ }
+ if (result.recentContracts) setRecentContracts(result.recentContracts);
+
+ setLastUpdated(new Date());
+ } finally {
+ if (isSilentRefresh) {
+ setIsRefreshing(false);
+ } else {
+ setIsLoading(false);
+ }
+ }
+ }, []);
+
+ useEffect(() => {
+ void loadStats();
+ // Check for upcoming contract deadlines and create notifications
+ void checkDeadlineNotifications();
+ }, [loadStats]);
+
+ useEffect(() => {
+ if (stats.processingContracts === 0 && stats.uploadedContracts === 0) {
+ return;
+ }
+
+ const intervalId = window.setInterval(() => {
+ void loadStats({ silent: true });
+ }, 10000);
+
+ return () => window.clearInterval(intervalId);
+ }, [loadStats, stats.processingContracts, stats.uploadedContracts]);
+
+ const hasChartData = useMemo(() => {
+ if (!chartData) return false;
+
+ const trendsCount = chartData.trends.reduce(
+ (total, entry) => total + entry.count,
+ 0,
+ );
+ const byStatusCount = chartData.byStatus.reduce(
+ (total, entry) => total + entry.count,
+ 0,
+ );
+ const byTypeCount = chartData.byType.reduce(
+ (total, entry) => total + entry.count,
+ 0,
+ );
+
+ return trendsCount + byStatusCount + byTypeCount > 0;
+ }, [chartData]);
+
+ const pendingContracts = stats.processingContracts + stats.uploadedContracts;
+
+ const analyzedPercent =
+ stats.totalContracts > 0
+ ? clampPercent((stats.analyzedContracts / stats.totalContracts) * 100)
+ : 0;
+
+ const pendingPercent =
+ stats.totalContracts > 0
+ ? clampPercent((pendingContracts / stats.totalContracts) * 100)
+ : 0;
+
+ const failedPercent =
+ stats.totalContracts > 0
+ ? clampPercent((stats.failedContracts / stats.totalContracts) * 100)
+ : 0;
+
+ const statusRows = [
+ {
+ label: "Uploaded",
+ value: stats.uploadedContracts,
+ colorClass: "bg-amber-500",
+ },
+ {
+ label: "Processing",
+ value: stats.processingContracts,
+ colorClass: "bg-primary",
+ },
+ {
+ label: "Analyzed",
+ value: stats.analyzedContracts,
+ colorClass: "bg-emerald-500",
+ },
+ {
+ label: "Failed",
+ value: stats.failedContracts,
+ colorClass: "bg-destructive",
+ },
+ ];
+
+ if (isLoading) {
+ return (
+
+
+
+
+
+ Building your analytics workspace...
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ Performance Overview
+
+
+ Financial Contracts Analytics
+
+
+ A reliable command center for uploaded documents, AI analysis
+ throughput, and portfolio quality across your BFSI workflow.
+
+
+
+
+
+ Live metrics
+
+
+
+ {isRefreshing
+ ? "Syncing..."
+ : `Updated ${formatLastUpdated(lastUpdated)}`}
+
+
+
+
+
+
+
+
+ Pipeline Snapshot
+
+
+ {numberFormatter.format(stats.totalContracts)} files
+
+
+
+
+
+
+
+
+
+
+
+
Analyzed
+
+ {numberFormatter.format(stats.analyzedContracts)}
+
+
+
+
Pending
+
+ {numberFormatter.format(pendingContracts)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {numberFormatter.format(stats.totalContracts)}
+
+
+ Uploaded into your workspace
+
+
+
+
+
+
+ {numberFormatter.format(stats.analyzedContracts)}
+
+
+ Completed by AI pipeline
+
+
+
+
+
+
+
+ {numberFormatter.format(pendingContracts)}
+
+
+ Uploaded and processing files
+
+
+
+
+
+
+
+ {numberFormatter.format(stats.failedContracts)}
+
+
+ Items needing re-analysis
+
+
+
+
+
+
+
+
+
+
+
Pipeline Pulse
+
+
+ {statusRows.map((row) => {
+ const rowPercent =
+ stats.totalContracts > 0
+ ? clampPercent((row.value / stats.totalContracts) * 100)
+ : 0;
+
+ return (
+
+
+
{row.label}
+
+ {numberFormatter.format(row.value)}
+
+
+
+
+ );
+ })}
+
+
+
+
+
+
Success Rate
+
+ {stats.analysisRate}%
+
+
+ Completed vs total files
+
+
+
+
Avg Premium
+
+ {currencyFormatter.format(premiumInfo.averagePremium)}
+
+
+ Across {numberFormatter.format(premiumInfo.count)} analyzed
+ files
+
+
+
+
Total Premium
+
+ {currencyFormatter.format(premiumInfo.totalPremium)}
+
+
+ Portfolio value captured by AI
+
+
+
+
+
+
+
+
+
+
+
AI Learning Telemetry
+
+
+
+ Score {aiLearningTelemetry.learningScore}/100
+
+
+
+
+
+
Completed Samples
+
+ {numberFormatter.format(aiLearningTelemetry.completedSamples)}
+
+
+ {numberFormatter.format(aiLearningTelemetry.completedLast7Days)}{" "}
+ in last 7 days
+
+
+
+
+
+ Avg Summary Length
+
+
+ {numberFormatter.format(aiLearningTelemetry.avgSummaryLength)}
+
+
characters
+
+
+
+
+ Avg Extracted Text
+
+
+ {numberFormatter.format(
+ aiLearningTelemetry.avgExtractedTextLength,
+ )}
+
+
characters
+
+
+
+
Avg Key Points
+
+ {aiLearningTelemetry.avgKeyPointsPerContract.toFixed(1)}
+
+
+ items per analysis
+
+
+
+
+
+
+ Learning quality index
+ {aiLearningTelemetry.learningScore}%
+
+
+
+ {aiLearningTelemetry.improvementHint}
+
+
+
+
+ {hasChartData ? (
+
+ {chartData && chartData.trends.length > 0 && (
+
+
+
+
+ Upload Trend (30 days)
+
+
+
+
+
+
+ )}
+
+ {chartData && chartData.byStatus.length > 0 && (
+
+
+
+
Processing Status
+
+
+ ({
+ ...s,
+ name: s.status,
+ }))}
+ />
+
+
+ )}
+
+ {chartData && chartData.byType.length > 0 && (
+
+
+
+
+ Contract Type Distribution
+
+
+
+
+
+
+ )}
+
+
+
+
+
Recent Analyses
+
+
+ {recentContracts.length > 0 ? (
+
+ {recentContracts.map((contract) => (
+
+
+ {contract.title || "Untitled contract"}
+
+
+ {contract.type || "Unknown type"}
+
+ {new Date(contract.createdAt).toLocaleDateString(
+ "en-US",
+ {
+ month: "short",
+ day: "numeric",
+ },
+ )}
+
+
+
+ Premium:{" "}
+ {contract.premium !== null
+ ? currencyFormatter.format(contract.premium)
+ : "Not detected"}
+
+
+ ))}
+
+ ) : (
+
+
+
+ No recent analyses yet
+
+
+ Analyze a contract to populate this activity feed.
+
+
+
+ )}
+
+
+ ) : (
+
+
+
+
+ Your analytics will appear here
+
+
+ Upload and analyze contracts to unlock trend and distribution
+ charts.
+
+
+
+
+ )}
+
+
+ );
+}
diff --git a/app/(dashboard)/layout.tsx b/app/(dashboard)/layout.tsx
new file mode 100644
index 0000000..3e279a1
--- /dev/null
+++ b/app/(dashboard)/layout.tsx
@@ -0,0 +1,22 @@
+import { auth } from "@clerk/nextjs/server";
+import { redirect } from "next/navigation";
+import { DashboardNavigation } from "@/components/views/dashboard/navigation";
+
+export default async function DashboardLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const { userId } = await auth();
+
+ if (!userId) {
+ redirect("/sign-in");
+ }
+
+ return (
+
+ );
+}
diff --git a/app/api/uploadthing/core.ts b/app/api/uploadthing/core.ts
new file mode 100644
index 0000000..ed11c49
--- /dev/null
+++ b/app/api/uploadthing/core.ts
@@ -0,0 +1,8 @@
+// src/app/api/uploadthing/core.ts
+
+import { createRouteHandler } from "uploadthing/next";
+import { ourFileRouter } from "@/lib/upload";
+
+export const { GET, POST } = createRouteHandler({
+ router: ourFileRouter,
+});
diff --git a/app/api/uploadthing/route.ts b/app/api/uploadthing/route.ts
new file mode 100644
index 0000000..835d68e
--- /dev/null
+++ b/app/api/uploadthing/route.ts
@@ -0,0 +1,3 @@
+// src/app/api/uploadthing/route.ts
+
+export { GET, POST } from "./core";
diff --git a/app/api/webhooks/clerk/route.ts b/app/api/webhooks/clerk/route.ts
new file mode 100644
index 0000000..cd8ccb2
--- /dev/null
+++ b/app/api/webhooks/clerk/route.ts
@@ -0,0 +1,164 @@
+// src/app/api/webhooks/clerk/route.ts
+
+import { Webhook } from "svix";
+import { headers } from "next/headers";
+import { WebhookEvent } from "@clerk/nextjs/server";
+import { prisma } from "@/lib/db/prisma";
+
+export async function POST(req: Request) {
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // STEP 1: Get the webhook secret from environment
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const WEBHOOK_SECRET = process.env.CLERK_WEBHOOK_SECRET;
+
+ if (!WEBHOOK_SECRET) {
+ console.error("β Missing CLERK_WEBHOOK_SECRET in environment variables");
+ return new Response("Server configuration error", { status: 500 });
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // STEP 2: Get headers needed for verification
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const headerPayload = await headers();
+ const svix_id = headerPayload.get("svix-id");
+ const svix_timestamp = headerPayload.get("svix-timestamp");
+ const svix_signature = headerPayload.get("svix-signature");
+
+ // If there are no headers, error out
+ if (!svix_id || !svix_timestamp || !svix_signature) {
+ console.error("β Missing svix headers");
+ return new Response("Missing svix headers", { status: 400 });
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // STEP 3: Get the request body
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const payload = await req.json();
+ const body = JSON.stringify(payload);
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // STEP 4: Verify the webhook signature
+ // This ensures the webhook is actually from Clerk
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const wh = new Webhook(WEBHOOK_SECRET);
+ let evt: WebhookEvent;
+
+ try {
+ evt = wh.verify(body, {
+ "svix-id": svix_id,
+ "svix-timestamp": svix_timestamp,
+ "svix-signature": svix_signature,
+ }) as WebhookEvent;
+ } catch (err) {
+ console.error("β Webhook verification failed:", err);
+ return new Response("Invalid signature", { status: 400 });
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // STEP 5: Handle different webhook events
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ const eventType = evt.type;
+
+ console.log(`π₯ Webhook received: ${eventType}`);
+
+ switch (eventType) {
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // USER CREATED
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ case "user.created": {
+ const { id, email_addresses, first_name, last_name, image_url } =
+ evt.data;
+
+ try {
+ // Check if user already exists
+ const existingUser = await prisma.user.findUnique({
+ where: { clerkId: id },
+ });
+
+ if (existingUser) {
+ console.log(`β οΈ User already exists: ${id}`);
+ return new Response("User already exists", { status: 200 });
+ }
+
+ // Create user in database
+ const user = await prisma.user.create({
+ data: {
+ clerkId: id,
+ email: email_addresses[0]?.email_address ?? "",
+ firstName: first_name ?? null,
+ lastName: last_name ?? null,
+ imageUrl: image_url ?? null,
+ },
+ });
+
+ console.log(`β
User created: ${user.email} (${user.id})`);
+
+ return new Response("User created successfully", { status: 201 });
+ } catch (error) {
+ console.error("β Error creating user:", error);
+ return new Response("Error creating user", { status: 500 });
+ }
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // USER UPDATED
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ case "user.updated": {
+ const { id, email_addresses, first_name, last_name, image_url } =
+ evt.data;
+
+ try {
+ const user = await prisma.user.update({
+ where: { clerkId: id },
+ data: {
+ email: email_addresses[0]?.email_address ?? "",
+ firstName: first_name ?? null,
+ lastName: last_name ?? null,
+ imageUrl: image_url ?? null,
+ },
+ });
+
+ console.log(`β
User updated: ${user.email} (${user.id})`);
+
+ return new Response("User updated successfully", { status: 200 });
+ } catch (error) {
+ console.error("β Error updating user:", error);
+ return new Response("Error updating user", { status: 500 });
+ }
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // USER DELETED
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ case "user.deleted": {
+ const { id } = evt.data;
+
+ if (!id) {
+ console.error("β No user ID provided in deletion event");
+ return new Response("No user ID provided", { status: 400 });
+ }
+
+ try {
+ // Delete user (CASCADE will delete all related contracts)
+ await prisma.user.delete({
+ where: { clerkId: id },
+ });
+
+ console.log(`β
User deleted: ${id}`);
+
+ return new Response("User deleted successfully", { status: 200 });
+ } catch (error) {
+ console.error("β Error deleting user:", error);
+ return new Response("Error deleting user", { status: 500 });
+ }
+ }
+
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ // OTHER EVENTS (ignore)
+ // βββββββββββββββββββββββββββββββββββββββββββββββββββ
+ default: {
+ console.log(`βΉοΈ Unhandled webhook event: ${eventType}`);
+ return new Response("Event type not handled", { status: 200 });
+ }
+ }
+}
diff --git a/app/clerk-provider.tsx b/app/clerk-provider.tsx
new file mode 100644
index 0000000..b4a28d5
--- /dev/null
+++ b/app/clerk-provider.tsx
@@ -0,0 +1,30 @@
+"use client";
+
+import { ClerkProvider } from "@clerk/nextjs";
+import { dark } from "@clerk/themes";
+import { useTheme } from "next-themes";
+import { ReactNode } from "react";
+
+export function ClerkThemeProvider({ children }: { children: ReactNode }) {
+ const { resolvedTheme } = useTheme();
+ const isDark = resolvedTheme === "dark";
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/app/globals.css b/app/globals.css
index b2c5819..faecefc 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -91,6 +91,38 @@
"rlig" 1,
"calt" 1;
}
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ font-feature-settings:
+ "rlig" 1,
+ "calt" 1;
+ }
+
+ /* Smooth scrolling */
+ html {
+ scroll-behavior: smooth;
+ }
+
+ /* Better font rendering */
+ body {
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ text-rendering: optimizeLegibility;
+ }
+
+ /* Selection styles */
+ ::selection {
+ @apply bg-primary/20;
+ }
+
+ /* Focus styles */
+ :focus-visible {
+ @apply outline-none ring-2 ring-primary ring-offset-2;
+ }
}
@layer utilities {
diff --git a/app/layout.tsx b/app/layout.tsx
index a91ec1e..5d610a2 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,24 +1,89 @@
import type { Metadata } from "next";
-import { Poppins, Geist_Mono } from "next/font/google";
+import { Inter, JetBrains_Mono } from "next/font/google";
import "./globals.css";
import { Providers } from "./provider";
-const poppins = Poppins({
+// Modern sans-serif font for body text
+const inter = Inter({
subsets: ["latin"],
- weight: ["400", "500", "600", "700", "800", "900"],
- variable: "--font-poppins",
+ variable: "--font-inter",
display: "swap",
+ weight: ["300", "400", "500", "600", "700"],
});
-const geistMono = Geist_Mono({
+// Monospace font for code and numbers
+const jetbrainsMono = JetBrains_Mono({
subsets: ["latin"],
- variable: "--font-geist-mono",
+ variable: "--font-mono",
display: "swap",
+ weight: ["400", "500", "600", "700"],
});
export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
+ title: {
+ default: "LexiChain - AI-Powered Contract Management",
+ template: "%s | LexiChain",
+ },
+ description:
+ "Intelligent BFSI contract management platform with AI-powered analysis. Manage your insurance, loan, and financial contracts with blockchain-verified security.",
+ keywords: [
+ "contract management",
+ "insurance",
+ "BFSI",
+ "AI contract analysis",
+ "document management",
+ "blockchain",
+ "smart contracts",
+ ],
+ authors: [{ name: "Your Name" }],
+ creator: "Your Name",
+ publisher: "LexiChain",
+ metadataBase: new URL("https://lexichain.com"), // Replace with your domain
+ openGraph: {
+ type: "website",
+ locale: "fr_FR",
+ url: "https://lexichain.com",
+ title: "LexiChain - AI-Powered Contract Management",
+ description:
+ "Intelligent contract management platform with AI analysis and blockchain verification.",
+ siteName: "LexiChain",
+ images: [
+ {
+ url: "/og-image.png", // Create this image (1200x630px)
+ width: 1200,
+ height: 630,
+ alt: "LexiChain Platform",
+ },
+ ],
+ },
+ twitter: {
+ card: "summary_large_image",
+ title: "LexiChain - AI-Powered Contract Management",
+ description:
+ "Intelligent contract management platform with AI analysis and blockchain verification.",
+ images: ["/og-image.png"],
+ creator: "@lexichain", // Replace with your Twitter handle
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-video-preview": -1,
+ "max-image-preview": "large",
+ "max-snippet": -1,
+ },
+ },
+ icons: {
+ icon: [
+ { url: "/favicon.ico" },
+ { url: "/icon-192.png", sizes: "192x192", type: "image/png" },
+ { url: "/icon-512.png", sizes: "512x512", type: "image/png" },
+ ],
+ apple: [{ url: "/apple-icon.png", sizes: "180x180", type: "image/png" }],
+ },
+ manifest: "/manifest.json",
};
export default function RootLayout({
@@ -27,9 +92,18 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
+
+
+ {/* Preconnect to external domains for performance */}
+
+
+
{children}
diff --git a/app/provider.tsx b/app/provider.tsx
index 0da5e24..8ccf1d3 100644
--- a/app/provider.tsx
+++ b/app/provider.tsx
@@ -1,6 +1,9 @@
+// src/components/providers.tsx
"use client";
+
import { ThemeProvider } from "next-themes";
import { ReactNode } from "react";
+import { ClerkThemeProvider } from "./clerk-provider";
export function Providers({ children }: { children: ReactNode }) {
return (
@@ -10,7 +13,7 @@ export function Providers({ children }: { children: ReactNode }) {
enableSystem
disableTransitionOnChange
>
- {children}
+ {children}
);
}
diff --git a/architecture.png b/architecture.png
new file mode 100644
index 0000000..07f1cd9
Binary files /dev/null and b/architecture.png differ
diff --git a/components/ui/resizable.tsx b/components/ui/resizable.tsx
index f4bc558..757bae8 100644
--- a/components/ui/resizable.tsx
+++ b/components/ui/resizable.tsx
@@ -1,36 +1,36 @@
-"use client"
+"use client";
-import { GripVertical } from "lucide-react"
-import * as ResizablePrimitive from "react-resizable-panels"
+import { GripVertical } from "lucide-react";
+import * as ResizablePrimitive from "react-resizable-panels";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const ResizablePanelGroup = ({
className,
...props
-}: React.ComponentProps) => (
- ) => (
+
-)
+);
-const ResizablePanel = ResizablePrimitive.Panel
+const ResizablePanel = ResizablePrimitive.Panel;
const ResizableHandle = ({
withHandle,
className,
...props
-}: React.ComponentProps & {
- withHandle?: boolean
+}: React.ComponentProps & {
+ withHandle?: boolean;
}) => (
- div]:rotate-90",
- className
+ className,
)}
{...props}
>
@@ -39,7 +39,7 @@ const ResizableHandle = ({
)}
-
-)
+
+);
-export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
+export { ResizablePanelGroup, ResizablePanel, ResizableHandle };
diff --git a/components/views/Home/Hero.tsx b/components/views/Home/Hero.tsx
index 613fb87..0853e90 100644
--- a/components/views/Home/Hero.tsx
+++ b/components/views/Home/Hero.tsx
@@ -8,13 +8,15 @@ import {
Lock,
Check,
Zap,
- Link,
+ Link2,
FileText,
MessageSquare,
Shield,
TrendingUp,
Bell,
} from "lucide-react";
+import Link from "next/link";
+import { SignedIn, SignedOut } from "@clerk/nextjs";
// Ripple Effect Component
function BackgroundRipple() {
@@ -407,7 +409,7 @@ export function Hero() {
{ icon: Lock, label: "Bank-Level Security" },
{ icon: Check, label: "GDPR Certified" },
{ icon: Zap, label: "Real-Time AI" },
- { icon: Link, label: "Blockchain Verified" },
+ { icon: Link2, label: "Blockchain Verified" },
];
return (
@@ -544,8 +546,10 @@ export function Hero() {
}`}
>
{/* Primary CTA */}
-