Added AgentIQ Project

This commit is contained in:
Mohammad Yaseen 2025-12-23 15:31:25 +05:30
commit 1076fb6543
49 changed files with 6265 additions and 0 deletions

2
.env.example Normal file
View File

@ -0,0 +1,2 @@
# API Configuration
# VITE_API_BASE_URL=http://localhost:3000

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

292
GUIDELINES.md Normal file
View File

@ -0,0 +1,292 @@
# AgenticIQ Coding Standards and Best Practices
## 1. Introduction and Purpose
This document establishes comprehensive coding standards and best practices for all developers working on the AgenticIQ enterprise application. Following these guidelines ensures code consistency, maintainability, and scalability across the entire development team.
### 1.1 Document Objectives
- Establish uniform coding standards across all development teams
- Reduce technical debt and improve code quality
- Facilitate easier onboarding of new team members
- Enable efficient code reviews and collaboration
- Ensure application performs optimally across all devices
### 1.2 Technology Stack
AgenticIQ is built using modern enterprise technologies. All code must align with the architectural patterns and technology constraints defined for this application.
## 2. General Coding Standards
### 2.1 Code Formatting Rules
1. Use 4 spaces for indentation (no tabs)
2. Maximum line length: 120 characters
3. Use UTF-8 encoding for all source files
4. End files with a single newline character
5. Remove trailing whitespace from all lines
6. Use consistent brace style (opening brace on same line for JS/TS, new line for C#)
### 2.2 Code Organization Principles
- Single Responsibility Principle (SRP): Each file/class/function should have one purpose
- DRY (Don't Repeat Yourself): Extract common logic into reusable functions/components
- KISS (Keep It Simple): Avoid over-engineering; prefer clarity over cleverness
- YAGNI (You Aren't Gonna Need It): Don't add functionality until it's required
### 2.3 File Size Guidelines
- Maximum file length: 400 lines (excluding comments)
- Maximum function/method length: 50 lines
- Maximum class length: 300 lines
- If limits are exceeded, refactor into smaller units
## 3. Naming Conventions
Consistent naming is critical for code readability and maintainability. All naming must be meaningful, descriptive, and follow the patterns defined below.
### 3.1 General Naming Rules
1. Use meaningful, descriptive names that reveal intent
2. Avoid single-letter names except for loop counters (i, j, k)
3. Avoid abbreviations unless universally understood (e.g., URL, HTTP, ID)
4. Use American English spelling consistently
5. Boolean variables should indicate true/false (isActive, hasPermission, canEdit)
### 3.2 Naming Convention Reference Table
| Element | Convention | Example | Notes |
| --------------- | -------------- | --------------------- | --------------------------- |
| Class/Interface | PascalCase | UserService, IRepository | Prefix I for interfaces (C#) |
| Function/Method | camelCase | getUserById, calculateTotal | Start with verb |
| Variable | camelCase | userName, orderItems | Descriptive nouns |
| Constant | SCREAMING_SNAKE| MAX_RETRY_COUNT | All uppercase |
| Private Field | _camelCase | _userRepository | Underscore prefix |
| Component | PascalCase | UserDashboard.tsx | Match filename |
| CSS Class | kebab-case | user-profile-card | BEM methodology |
| File (General) | kebab-case | user-service.ts | Lowercase |
| Database Table | PascalCase Singular | UserProfile, OrderItem | Match entity name |
| API Endpoint | kebab-case plural | /api/user-profiles | RESTful conventions |
### 3.3 Function Naming Patterns
Function names should clearly describe the action performed. Use consistent verb prefixes to indicate the operation type.
| Prefix | Purpose | Examples |
| ---------- | ------------------ | ---------------------------------------------- |
| get | Retrieve data | getUserById(), getOrderList(), getActiveUsers()|
| set | Assign value | setUserName(), setOrderStatus() |
| create | Create new entity | createUser(), createOrder(), createReport() |
| update | Modify existing | updateUserProfile(), updateOrderQuantity() |
| delete/remove | Remove data | deleteUser(), removeCartItem() |
| is/has/can | Boolean checks | isActive(), hasPermission(), canEdit() |
| validate | Check validity | validateEmail(), validateUserInput() |
| calculate | Compute values | calculateTotal(), calculateDiscount() |
| handle | Event handling | handleSubmit(), handleClick(), handleError() |
| fetch/load | Async data load | fetchUserData(), loadConfiguration() |
| render | UI rendering | renderHeader(), renderUserList() |
| format/parse | Data transformation | formatDate(), parseJson(), formatCurrency() |
## 4. Function Design Guidelines
### 4.1 Function Structure Best Practices
1. Single Purpose: Each function should do exactly one thing well
2. Parameter Limit: Maximum 4 parameters; use objects for more
3. Pure Functions: Prefer functions without side effects when possible
4. Early Returns: Use guard clauses to handle edge cases first
5. Avoid Deep Nesting: Maximum 3 levels of nesting; refactor if deeper
### 4.2 Function Signature Guidelines
- Return Type: Always specify explicit return types in TypeScript
- Parameter Types: Use strong typing; avoid `any`
- Default Values: Provide sensible defaults for optional parameters
- Async Functions: Return `Promise<T>` with proper typing
### 4.3 Function Documentation Template
Every public function must include JSDoc/XML documentation with:
- `@description` - Brief explanation of what the function does
- `@param {Type} name` - Description of each parameter
- `@returns {Type}` - Description of the return value
- `@throws {ErrorType}` - Exceptions that may be thrown
- `@example` - Usage example (for complex functions)
## 5. Responsive Design & Screen Optimization
### 5.1 Breakpoint Standards
| Device | Breakpoint | CSS Variable | Target Devices |
| -------------- | ---------------- | --------------- | ------------------- |
| Mobile S | < 375px | --screen-xs | Small phones |
| Mobile M | 375px - 424px | --screen-sm | Standard phones |
| Mobile L | 425px - 767px | --screen-md | Large phones |
| Tablet | 768px - 1023px | --screen-lg | iPad, Tablets |
| Laptop | 1024px - 1439px | --screen-xl | Laptops, small desktops |
| Desktop | 1440px - 1919px | --screen-xxl | Standard monitors |
| Large Display | ≥ 1920px | --screen-xxxl | Large/4K monitors |
### 5.2 Mobile-First Development
1. Start with mobile layout and progressively enhance for larger screens
2. Use min-width media queries to add complexity as screen size increases
3. Design touch-friendly interfaces with minimum 44px touch targets
4. Optimize images for mobile using srcset and responsive images
5. Test on actual devices, not just browser developer tools
### 5.3 Layout Guidelines
- Flexbox: Use for one-dimensional layouts (rows or columns)
- CSS Grid: Use for two-dimensional layouts and complex designs
- Container Queries: Use for component-level responsiveness
- Relative Units: Use rem/em for typography, % for widths, vh/vw for viewports
- Avoid fixed pixel widths for containers; prefer max-width constraints
### 5.4 Typography Scaling
| Element | Mobile | Tablet | Desktop |
| ------- | ------------- | ------------- | ------------- |
| H1 | 1.75rem (28px)| 2rem (32px) | 2.5rem (40px) |
| H2 | 1.5rem (24px) | 1.75rem (28px)| 2rem (32px) |
| H3 | 1.25rem (20px)| 1.375rem (22px)| 1.5rem (24px)|
| Body | 0.875rem (14px)| 0.9375rem (15px)| 1rem (16px) |
| Caption | 0.75rem (12px)| 0.8125rem (13px)| 0.875rem (14px)|
## 6. Code Architecture Principles
### 6.1 Folder Structure Standards
Maintain consistent folder organization across all modules:
- `/src/components`: Reusable UI components
- `/src/pages`: Route-level page components
- `/src/hooks`: Custom React hooks
- `/src/services`: API calls and external integrations
- `/src/utils`: Utility functions and helpers
- `/src/types`: TypeScript type definitions
- `/src/constants`: Application constants and enums
- `/src/styles`: Global styles and theme configuration
### 6.2 Component Design Patterns
1. Container/Presentational Pattern: Separate logic from presentation
2. Compound Components: Create flexible, composable component APIs
3. Render Props/HOCs: Share behavior between components
4. Custom Hooks: Extract reusable stateful logic
5. Context Pattern: Share state across component tree
### 6.3 State Management Guidelines
- Local State: Use `useState` for component-specific state
- Server State: Use React Query/TanStack Query for API data
- Global State: Use Zustand/Redux for app-wide state
- Form State: Use React Hook Form for complex forms
## 7. Error Handling Best Practices
### 7.1 Error Handling Principles
1. Fail Fast: Detect and report errors as early as possible
2. Be Specific: Use specific error types, not generic exceptions
3. Log Appropriately: Include context but exclude sensitive data
4. User-Friendly Messages: Show helpful messages, not stack traces
5. Recover Gracefully: Implement fallback behavior where possible
### 7.2 Error Categories
| Error Type | Handling Strategy | Example |
| -------------- | ------------------------------ | ------------------------ |
| Validation | Show inline field errors | Invalid email format |
| Network | Retry with exponential backoff | API timeout |
| Authentication | Redirect to login | Token expired |
| Authorization | Show access denied message | 403 Forbidden |
| Not Found | Show 404 page or fallback | Resource not found |
| Server Error | Show error page with support contact | 500 Internal Error |
### 7.3 Try-Catch Guidelines
- Catch specific errors, not generic Exception/Error
- Never swallow exceptions silently without logging
- Use finally blocks for cleanup operations
- Avoid try-catch for flow control
- Re-throw with additional context when appropriate
## 8. Performance Optimization
### 8.1 Frontend Performance
1. Code Splitting: Use dynamic imports for route-level splitting
2. Lazy Loading: Defer loading of below-the-fold content
3. Image Optimization: Use WebP format, responsive images, lazy loading
4. Bundle Analysis: Regularly analyze and optimize bundle size
5. Caching: Implement proper caching headers and service workers
6. Memoization: Use `useMemo`, `useCallback`, `React.memo` appropriately
### 8.2 React Performance Tips
- Use virtualization for long lists (react-window, react-virtualized)
- Avoid inline function definitions in render
- Use stable keys for list items
- Avoid unnecessary re-renders with proper state structure
- Profile with React DevTools before optimizing
### 8.3 Performance Metrics Targets
| Metric | Target | Measurement |
| ------------------------ | --------------- | -------------------- |
| First Contentful Paint (FCP) | < 1.8 seconds | Lighthouse |
| Largest Contentful Paint (LCP) | < 2.5 seconds | Lighthouse |
| Cumulative Layout Shift (CLS) | < 0.1 | Lighthouse |
| Time to Interactive (TTI) | < 3.8 seconds | Lighthouse |
| Bundle Size (main) | < 250KB gzipped | Webpack analyzer |
## 9. Security Guidelines
### 9.1 Input Validation & Sanitization
1. Validate all inputs on both client and server side
2. Sanitize user inputs to prevent XSS attacks
3. Use parameterized queries to prevent SQL injection
4. Implement rate limiting on API endpoints
5. Validate file uploads (type, size, content)
### 9.2 Authentication & Authorization
- Never store sensitive data in localStorage/sessionStorage
- Use HTTP-only, Secure cookies for session tokens
- Implement proper CORS configuration
- Use CSRF tokens for state-changing operations
- Always verify authorization on the server
### 9.3 Data Protection
- Never log sensitive information (passwords, tokens, PII)
- Use environment variables for secrets
- Encrypt sensitive data at rest and in transit
- Implement proper error messages (no stack traces in production)
- Follow principle of least privilege
## 10. Documentation Standards
### 10.1 Code Comments Guidelines
- WHY, not WHAT: Explain the reasoning, not what the code does
- Self-Documenting Code: Use clear names; add comments only when necessary
- Update Comments: Keep comments in sync with code changes
- TODO Comments: Include ticket number, e.g., `// TODO(JIRA-123): Fix edge case`
- Avoid obvious comments
### 10.2 README Requirements
Every project/module must have a README.md with:
- Project overview and purpose
- Prerequisites and dependencies
- Installation and setup instructions
- Environment configuration
- Available scripts and commands
- Contributing guidelines
### 10.3 API Documentation
All APIs must be documented using OpenAPI/Swagger specification with endpoint descriptions, request/response schemas, authentication requirements, error codes and responses, and usage examples.
## 11. Version Control Guidelines
### 11.1 Git Commit Message Format
Follow the Conventional Commits specification: `<type>(<scope>): <subject>`
| Type | Description |
| ------ | --------------------------------------------- |
| feat | New feature for the user |
| fix | Bug fix for the user |
| docs | Documentation only changes |
| style | Formatting, missing semicolons (no code change) |
| refactor | Code change that neither fixes a bug nor adds a feature |
| test | Adding or updating tests |
| chore | Build process or auxiliary tool changes |
### 11.2 Branching Strategy
- `main`: Production-ready code only
- `develop`: Integration branch for features
- `feature/JIRA-XXX-description`: Feature branches
- `bugfix/JIRA-XXX-description`: Bug fix branches
- `hotfix/JIRA-XXX-description`: Production hotfixes
- `release/vX.X.X`: Release preparation branches
## 12. Testing Standards
### 12.1 Testing Pyramid
- Unit Tests (70%): Test individual functions/components in isolation
- Integration Tests (20%): Test component interactions and API integrations
- E2E Tests (10%): Test critical user journeys end-to-end
### 12.2 Test Naming Convention
Use the pattern: describe what is being tested + under what conditions + expected outcome.
- Example: `getUserById returns user object when valid ID is provided`
- Example: `calculateTotal throws error when items array is empty`
### 12.3 Code Coverage Requirements
- Minimum line coverage: 80%
- Minimum branch coverage: 75%
- Critical paths: 100% coverage required
- New code must maintain or improve coverage

141
README.md Normal file
View File

@ -0,0 +1,141 @@
# AgenticIQ
A modern React application built with TypeScript, Tailwind CSS, and shadcn/ui, following **AgenticIQ Enterprise Coding Guidelines & Best Practices Version 1.0** from Tech4Biz Solutions Pvt Ltd.
## 🚀 Features
- ⚡ **Vite** - Lightning-fast build tool
- ⚛️ **React 18** with TypeScript
- 🎨 **Tailwind CSS** - Utility-first CSS framework
- 🧩 **shadcn/ui** - Beautiful, accessible component library
- 📱 **Responsive Design** - Mobile-first with 7 breakpoints
- 🔒 **Type Safety** - Strict TypeScript configuration
- 📦 **Path Aliases** - Clean imports with `@/` prefix
- 🎯 **Best Practices** - Following enterprise coding standards
## 📋 Prerequisites
- Node.js 18+
- npm or yarn
## 🛠️ Installation
1. Clone the repository:
```bash
git clone <repository-url>
cd AgenticIQ
```
2. Install dependencies:
```bash
npm install
```
3. Create environment file:
```bash
cp .env.example .env
```
4. Start development server:
```bash
npm run dev
```
## 📁 Project Structure
Following AgenticIQ guidelines, the project is organized as:
```
src/
├── components/ # Reusable UI components
│ └── ui/ # shadcn/ui components
├── pages/ # Route-level components
├── hooks/ # Custom React hooks
├── services/ # API calls and external services
├── utils/ # Helper functions
├── types/ # TypeScript type definitions
├── constants/ # Application constants
└── lib/ # Third-party library configurations
```
## 🎨 Responsive Breakpoints
Following AgenticIQ responsive design guidelines:
- **Mobile S** (`< 375px`): Extra small mobile devices
- **Mobile M** (`375px - 424px`): Standard mobile devices
- **Mobile L** (`425px - 767px`): Large mobile devices
- **Tablet** (`768px - 1023px`): Tablet devices
- **Laptop** (`1024px - 1439px`): Laptop screens
- **Desktop** (`1440px - 1919px`): Desktop screens
- **Large Display** (`≥ 1920px`): Large displays
## 📝 Naming Conventions
Following AgenticIQ standards:
- **Components/Interfaces**: `PascalCase`
- **Functions/Variables**: `camelCase`
- **Constants**: `SCREAMING_SNAKE_CASE`
- **CSS Classes/Files**: `kebab-case`
- **Private Fields**: `_camelCase`
## 🧪 Available Scripts
- `npm run dev` - Start development server
- `npm run build` - Build for production
- `npm run preview` - Preview production build
- `npm run lint` - Run ESLint
## 📚 Adding shadcn/ui Components
To add new shadcn/ui components:
```bash
npx shadcn@latest add button
npx shadcn@latest add card
npx shadcn@latest add input
```
## 🎯 Code Quality Standards
This project follows:
- **File Size**: < 250 lines per file
- **Function Parameters**: Max 4 parameters
- **Nesting Levels**: Max 3 levels
- **Test Coverage**: Min 80% line coverage
- **Documentation**: JSDoc for all public functions
## 🔒 Security
- Input validation on client and server
- XSS prevention
- CSRF protection
- Secure authentication practices
## 📖 Documentation
All functions include JSDoc comments with:
- `@description` - What the function does
- `@param` - Parameter descriptions
- `@returns` - Return value description
- `@throws` - Possible errors
- `@example` - Usage examples
## 🤝 Contributing
Follow the AgenticIQ Enterprise Coding Guidelines when contributing:
1. Use conventional commits (`feat:`, `fix:`, `docs:`, etc.)
2. Follow branching strategy (`feature/`, `bugfix/`, `hotfix/`)
3. Maintain code quality standards
4. Add tests for new features
## 📄 License
[Your License Here]
## 🙏 Acknowledgments
Built following **AgenticIQ Enterprise Coding Guidelines & Best Practices Version 1.0** by Tech4Biz Solutions Pvt Ltd.

23
eslint.config.js Normal file
View File

@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])

19
index.html Normal file
View File

@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<title>AgenticIQ</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

4405
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

44
package.json Normal file
View File

@ -0,0 +1,44 @@
{
"name": "agenticiq",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@reduxjs/toolkit": "^2.11.2",
"@tailwindcss/vite": "^4.1.18",
"@tanstack/react-query": "^5.90.12",
"@tanstack/react-router": "^1.143.2",
"@tanstack/router-devtools": "^1.143.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.562.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.2.0",
"tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.18",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/node": "^24.10.4",
"@types/react": "^18.3.27",
"@types/react-dom": "^18.3.7",
"@vitejs/plugin-react-swc": "^4.2.2",
"autoprefixer": "^10.4.23",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"postcss": "^8.5.6",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4"
}
}

8
public/Agent.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

13
public/FT.svg Normal file
View File

@ -0,0 +1,13 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.0215 30.2559L33.0002 30.2559" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M15 30.2559H17.0426" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<circle cx="2.55319" cy="2.55319" r="1.80319" transform="matrix(1 0 0 -1 17.043 32.6816)" stroke="white" stroke-width="1.5"/>
<path d="M22.0215 18L33.0002 18" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M15 18H17.0426" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<circle cx="2.55319" cy="2.55319" r="1.80319" transform="matrix(1 0 0 -1 17.043 20.4258)" stroke="white" stroke-width="1.5"/>
<path d="M15.2354 24H23.2354" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M22.2354 22L24.2354 24" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M22.2354 26L24.2354 24" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M31.2129 24.5742L33.0001 24.5742" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<circle cx="2.55319" cy="2.55319" r="1.80319" transform="matrix(1 0 0 -1 26.2344 27)" stroke="white" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

3
public/KB.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M29.25 15.1522C29.25 14.5814 29.0327 14.034 28.6459 13.6304C28.2591 13.2267 27.7345 13 27.1875 13H14.8125C14.2655 13 13.7409 13.2267 13.3541 13.6304C12.9673 14.034 12.75 14.5814 12.75 15.1522V17.3043C12.7518 17.8355 12.9429 18.347 13.2862 18.7391C12.9429 19.1313 12.7518 19.6428 12.75 20.1739V22.3261C12.7518 22.8572 12.9429 23.3687 13.2862 23.7609C12.9429 24.153 12.7518 24.6645 12.75 25.1957V29.5H29.25V25.1957C29.2482 24.6645 29.0571 24.153 28.7137 23.7609C29.0571 23.3687 29.2482 22.8572 29.25 22.3261V20.1739C29.2482 19.6428 29.0571 19.1313 28.7137 18.7391C29.0571 18.347 29.2482 17.8355 29.25 17.3043V15.1522ZM14.125 15.1522C14.125 14.9619 14.1974 14.7794 14.3264 14.6449C14.4553 14.5104 14.6302 14.4348 14.8125 14.4348H16.1875V15.8696H17.5625V14.4348H18.9375V15.8696H20.3125V14.4348H27.1875C27.3698 14.4348 27.5447 14.5104 27.6736 14.6449C27.8026 14.7794 27.875 14.9619 27.875 15.1522V17.3043C27.875 17.4946 27.8026 17.6771 27.6736 17.8116C27.5447 17.9462 27.3698 18.0217 27.1875 18.0217H14.8125C14.6302 18.0217 14.4553 17.9462 14.3264 17.8116C14.1974 17.6771 14.125 17.4946 14.125 17.3043V15.1522ZM27.875 20.1739V22.3261C27.875 22.5164 27.8026 22.6988 27.6736 22.8334C27.5447 22.9679 27.3698 23.0435 27.1875 23.0435H14.8125C14.6302 23.0435 14.4553 22.9679 14.3264 22.8334C14.1974 22.6988 14.125 22.5164 14.125 22.3261V20.1739C14.125 19.9836 14.1974 19.8012 14.3264 19.6666C14.4553 19.5321 14.6302 19.4565 14.8125 19.4565H16.1875V20.8913H17.5625V19.4565H18.9375V20.8913H20.3125V19.4565H27.1875C27.3698 19.4565 27.5447 19.5321 27.6736 19.6666C27.8026 19.8012 27.875 19.9836 27.875 20.1739ZM27.875 28.0652H14.125V25.1957C14.125 25.0054 14.1974 24.8229 14.3264 24.6884C14.4553 24.5538 14.6302 24.4783 14.8125 24.4783H16.1875V25.913H17.5625V24.4783H18.9375V25.913H20.3125V24.4783H27.1875C27.3698 24.4783 27.5447 24.5538 27.6736 24.6884C27.8026 24.8229 27.875 25.0054 27.875 25.1957V28.0652Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

8
public/LLM.svg Normal file
View File

@ -0,0 +1,8 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="2.80046" cy="2.80046" r="2.05046" transform="matrix(-1 0 0 1 29.9121 15)" stroke="white" stroke-width="1.5"/>
<circle cx="2.80046" cy="2.80046" r="2.05046" transform="matrix(-1 0 0 1 20.5771 21.8457)" stroke="white" stroke-width="1.5"/>
<circle cx="2.80046" cy="2.80046" r="2.05046" transform="matrix(-1 0 0 1 31.7793 26.2012)" stroke="white" stroke-width="1.5"/>
<path d="M22.9409 15.2267L18.8509 18.764L18.3351 22.0065" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M32.6778 26.6518L31.91 21.2991L29.4598 19.1136" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
<path d="M17.9117 29.1131L22.9623 31.045L26.0635 29.9667" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 829 B

BIN
public/Logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

8
public/Models.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 38 KiB

3
public/Nav item.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.9424 23.75C16.3452 23.75 14.9876 23.191 13.8696 22.073C12.7515 20.9548 12.1924 19.5972 12.1924 18C12.1924 17.7222 12.2126 17.4444 12.2531 17.1667C12.2935 16.8889 12.361 16.6224 12.4559 16.3672C12.52 16.2134 12.6066 16.0997 12.7156 16.026C12.8245 15.9523 12.9475 15.8988 13.0846 15.8655C13.222 15.8322 13.3601 15.8347 13.4991 15.873C13.6383 15.9115 13.7649 15.9878 13.8789 16.102L16.5424 18.7462L18.6886 16.6L16.0539 13.9557C15.9399 13.8416 15.8636 13.7128 15.8251 13.5693C15.7866 13.4258 15.784 13.286 15.8174 13.15C15.8507 13.0142 15.9059 12.8917 15.9829 12.7827C16.0597 12.6737 16.1719 12.5872 16.3194 12.523C16.5745 12.4218 16.84 12.351 17.1156 12.3105C17.3911 12.2702 17.6667 12.25 17.9424 12.25C19.5397 12.25 20.8974 12.809 22.0154 13.927C23.1334 15.0452 23.6924 16.4028 23.6924 18C23.6924 18.4218 23.6526 18.8148 23.5731 19.1788C23.4936 19.5429 23.3744 19.8949 23.2154 20.2348L28.6501 25.6385C29.0693 26.056 29.2789 26.5671 29.2789 27.1718C29.2789 27.7764 29.07 28.2884 28.6521 28.7078C28.2343 29.1269 27.7228 29.3365 27.1176 29.3365C26.5125 29.3365 26.0002 29.1217 25.5809 28.6923L20.1771 23.273C19.8245 23.4257 19.466 23.5433 19.1019 23.626C18.7375 23.7087 18.351 23.75 17.9424 23.75ZM17.9424 22.25C18.38 22.25 18.8177 22.1849 19.2554 22.0548C19.6929 21.9248 20.0931 21.7212 20.4559 21.4443L26.6656 27.654C26.7873 27.7757 26.9398 27.834 27.1231 27.829C27.3065 27.8238 27.459 27.7603 27.5809 27.6385C27.7027 27.5167 27.7636 27.3641 27.7636 27.1807C27.7636 26.9974 27.7027 26.8448 27.5809 26.723L21.3714 20.5288C21.6521 20.1826 21.859 19.7887 21.9924 19.347C22.1257 18.9053 22.1924 18.4563 22.1924 18C22.1924 16.891 21.7962 15.9096 21.0039 15.0557C20.2115 14.2019 19.209 13.7833 17.9961 13.8L20.1636 15.9673C20.3443 16.1481 20.4346 16.359 20.4346 16.6C20.4346 16.841 20.3443 17.0519 20.1636 17.2327L17.1751 20.2213C16.9943 20.4019 16.7834 20.4923 16.5424 20.4923C16.3014 20.4923 16.0905 20.4019 15.9096 20.2213L13.7424 18.0538C13.7449 19.3371 14.1763 20.3573 15.0366 21.1145C15.897 21.8715 16.8655 22.25 17.9424 22.25Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

4
public/Optimization.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.739 33.5C22.398 33.5 22.1291 33.3868 21.9322 33.1605C21.7354 32.9343 21.6101 32.6558 21.5562 32.325L21.312 30.4538C21.0441 30.3641 20.7695 30.2385 20.488 30.077C20.2066 29.9153 19.9551 29.7422 19.7332 29.5577L18.0005 30.2943C17.6863 30.4328 17.3706 30.4462 17.0535 30.3345C16.7361 30.223 16.4896 30.0205 16.314 29.727L15.187 27.773C15.0113 27.4795 14.9607 27.1689 15.0352 26.8413C15.1096 26.5138 15.2801 26.2436 15.5467 26.0308L17.0447 24.9058C17.0217 24.7571 17.0054 24.6077 16.9957 24.4578C16.9861 24.3078 16.9812 24.1583 16.9812 24.0095C16.9812 23.8673 16.9861 23.7228 16.9957 23.576C17.0054 23.4292 17.0217 23.2686 17.0447 23.0943L15.5467 21.9693C15.2801 21.7564 15.1111 21.4846 15.04 21.1538C14.9688 20.8231 15.0211 20.5109 15.1967 20.2173L16.314 18.2923C16.4896 18.0051 16.7361 17.8042 17.0535 17.6895C17.3706 17.5747 17.6863 17.5865 18.0005 17.725L19.7235 18.452C19.9646 18.261 20.2221 18.0863 20.4957 17.928C20.7694 17.7697 21.0383 17.6424 21.3025 17.5462L21.5562 15.675C21.6101 15.3442 21.7611 15.0657 22.0092 14.8395C22.2572 14.6132 22.5517 14.5 22.8927 14.5H25.1082C25.4492 14.5 25.7437 14.6132 25.9917 14.8395C26.2399 15.0657 26.3909 15.3442 26.4447 15.675L26.689 17.5557C26.989 17.6647 27.2604 17.792 27.5032 17.9375C27.7462 18.083 27.9915 18.2545 28.239 18.452L30.0102 17.725C30.3242 17.5865 30.6399 17.5747 30.9572 17.6895C31.2746 17.8042 31.521 18.0051 31.6965 18.2923L32.814 20.227C32.9896 20.5205 33.0402 20.8311 32.9657 21.1587C32.8914 21.4862 32.7209 21.7564 32.4542 21.9693L31.5465 22.65C31.3812 22.7885 31.2004 22.8465 31.0042 22.824C30.8081 22.8015 30.6376 22.7076 30.4927 22.5423C30.3479 22.3769 30.2857 22.193 30.3062 21.9905C30.3267 21.7878 30.4196 21.6173 30.585 21.4788L31.435 20.85L30.4505 19.15L27.937 20.2095C27.6023 19.8518 27.2014 19.5358 26.7342 19.2615C26.2669 18.9872 25.7941 18.7929 25.316 18.6788L25.0005 16H23.016L22.685 18.6693C22.1748 18.7898 21.7037 18.9743 21.2717 19.223C20.8396 19.4718 20.4273 19.7923 20.035 20.1845L17.5505 19.15L16.566 20.85L18.7255 22.4595C18.6421 22.6968 18.5838 22.9437 18.5505 23.2C18.5171 23.4563 18.5005 23.7262 18.5005 24.0095C18.5005 24.2698 18.5171 24.525 18.5505 24.775C18.5838 25.025 18.639 25.2718 18.716 25.5155L16.566 27.15L17.5505 28.85L20.0255 27.8C20.328 28.1025 20.6481 28.3663 20.986 28.5913C21.3238 28.8163 21.6908 29.0006 22.087 29.1443C22.1101 29.8134 22.2246 30.4499 22.4302 31.0538C22.6361 31.6576 22.9114 32.2121 23.2562 32.7173C23.3639 32.8788 23.362 33.0496 23.2505 33.2297C23.139 33.4099 22.9685 33.5 22.739 33.5ZM24.012 21C23.18 21 22.472 21.2894 21.888 21.8682C21.304 22.4471 21.012 23.1577 21.012 24C21.012 24.3308 21.0636 24.6501 21.167 24.9578C21.2701 25.2654 21.4249 25.5533 21.6312 25.8212C21.7761 26.0071 21.9559 26.1205 22.1707 26.1615C22.3854 26.2025 22.5806 26.1506 22.7562 26.0058C22.9319 25.8711 23.031 25.7015 23.0535 25.497C23.0758 25.2927 23.0146 25.1161 22.8697 24.9672C22.7506 24.8339 22.6611 24.6868 22.6015 24.526C22.5418 24.365 22.512 24.1897 22.512 24C22.512 23.5833 22.6578 23.2292 22.9495 22.9375C23.2411 22.6458 23.5953 22.5 24.012 22.5C24.1915 22.5 24.3668 22.534 24.538 22.602C24.7091 22.6698 24.8614 22.7634 24.9947 22.8828C25.1434 23.0071 25.3123 23.0564 25.5015 23.0307C25.6905 23.0051 25.8523 22.9044 25.987 22.7288C26.1216 22.5533 26.171 22.3607 26.135 22.151C26.0991 21.9413 25.9934 21.7641 25.8177 21.6193C25.5972 21.4193 25.3299 21.2661 25.0157 21.1598C24.7017 21.0533 24.3671 21 24.012 21Z" fill="white"/>
<path d="M27.924 30.937C27.906 30.937 27.882 30.931 27.852 30.919C27.828 30.907 27.801 30.895 27.771 30.883L24.531 28.678C24.447 28.618 24.381 28.561 24.333 28.507C24.291 28.447 24.27 28.372 24.27 28.282V28.003C24.27 27.913 24.291 27.841 24.333 27.787C24.381 27.733 24.447 27.676 24.531 27.616L27.771 25.411C27.801 25.393 27.828 25.378 27.852 25.366C27.882 25.354 27.906 25.348 27.924 25.348C27.978 25.348 28.023 25.366 28.059 25.402C28.095 25.438 28.113 25.483 28.113 25.537V26.5C28.113 26.596 28.086 26.671 28.032 26.725C27.978 26.773 27.921 26.818 27.861 26.86L25.899 28.147L27.861 29.443C27.921 29.479 27.978 29.521 28.032 29.569C28.086 29.617 28.113 29.689 28.113 29.785V30.757C28.113 30.811 28.095 30.856 28.059 30.892C28.023 30.922 27.978 30.937 27.924 30.937ZM30.0894 30.937C30.0414 30.937 29.9994 30.922 29.9634 30.892C29.9274 30.856 29.9094 30.811 29.9094 30.757V29.785C29.9094 29.689 29.9364 29.617 29.9904 29.569C30.0444 29.521 30.1014 29.479 30.1614 29.443L32.1144 28.147L30.1614 26.86C30.1014 26.824 30.0444 26.779 29.9904 26.725C29.9364 26.671 29.9094 26.599 29.9094 26.509V25.537C29.9094 25.483 29.9274 25.441 29.9634 25.411C29.9994 25.375 30.0414 25.357 30.0894 25.357C30.1134 25.357 30.1374 25.363 30.1614 25.375C30.1914 25.387 30.2184 25.399 30.2424 25.411L33.4914 27.616C33.5814 27.676 33.6474 27.733 33.6894 27.787C33.7314 27.841 33.7524 27.916 33.7524 28.012V28.282C33.7524 28.372 33.7314 28.447 33.6894 28.507C33.6474 28.561 33.5814 28.618 33.4914 28.678L30.2424 30.883C30.2184 30.895 30.1914 30.907 30.1614 30.919C30.1374 30.931 30.1134 30.937 30.0894 30.937Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

3
public/Task watacher.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.5463 22.75H19.5C19.6385 22.75 19.7686 22.7846 19.8902 22.8538C20.0121 22.9231 20.1051 23.027 20.1693 23.1655L21.5 25.8077L24.8307 19.1655C24.9692 18.8783 25.1939 18.7348 25.5048 18.7348C25.8158 18.7348 26.0404 18.8783 26.1788 19.1655L27.9712 22.75H30.4538C30.2679 20.9858 29.5138 19.5032 28.1913 18.302C26.8689 17.1007 25.3052 16.5 23.5 16.5C21.6948 16.5 20.1311 17.1007 18.8088 18.302C17.4862 19.5032 16.7321 20.9858 16.5463 22.75ZM23.5 30.5C25.3052 30.5 26.8689 29.8993 28.1913 28.698C29.5138 27.4968 30.2679 26.0142 30.4538 24.25H27.5C27.3615 24.25 27.2314 24.2154 27.1098 24.1463C26.9879 24.0769 26.8949 23.973 26.8307 23.8345L25.5 21.1923L22.1693 27.8443C22.0307 28.1314 21.8061 28.2734 21.4953 28.2703C21.1843 28.2669 20.9596 28.1217 20.8213 27.8345L19.0287 24.25H16.5463C16.7321 26.0142 17.4862 27.4968 18.8088 28.698C20.1311 29.8993 21.6948 30.5 23.5 30.5ZM23.5 32C22.3308 32 21.2308 31.7769 20.2 31.3307C19.1692 30.8846 18.2679 30.2756 17.4963 29.5038C16.7244 28.7321 16.1154 27.8308 15.6693 26.8C15.2231 25.7692 15 24.6692 15 23.5H16.5C16.5 25.4333 17.1833 27.0833 18.55 28.45C19.9167 29.8167 21.5667 30.5 23.5 30.5C25.4333 30.5 27.0833 29.8167 28.45 28.45C29.8167 27.0833 30.5 25.4333 30.5 23.5H32C32 24.6692 31.7769 25.7692 31.3307 26.8C30.8846 27.8308 30.2756 28.7321 29.5038 29.5038C28.7321 30.2756 27.8308 30.8846 26.8 31.3307C25.7692 31.7769 24.6692 32 23.5 32ZM15 23.5C15 22.3308 15.2231 21.2308 15.6693 20.2C16.1154 19.1692 16.7244 18.2679 17.4963 17.4962C18.2679 16.7244 19.1692 16.1154 20.2 15.6693C21.2308 15.2231 22.3308 15 23.5 15C24.5013 15 25.4657 15.1699 26.3932 15.5098C27.3207 15.8494 28.182 16.3359 28.977 16.9693L29.6962 16.25C29.8346 16.1115 30.0086 16.0407 30.2182 16.0375C30.4279 16.0343 30.6052 16.1052 30.75 16.25C30.8948 16.3948 30.9672 16.5705 30.9672 16.777C30.9672 16.9833 30.8948 17.1589 30.75 17.3038L30.0307 18.023C30.6641 18.818 31.1506 19.6793 31.4902 20.6068C31.8301 21.5343 32 22.4987 32 23.5H30.5C30.5 21.5667 29.8167 19.9167 28.45 18.55C27.0833 17.1833 25.4333 16.5 23.5 16.5C21.5667 16.5 19.9167 17.1833 18.55 18.55C17.1833 19.9167 16.5 21.5667 16.5 23.5H15ZM23.5 30.5C21.5667 30.5 19.9167 29.8167 18.55 28.45C17.1833 27.0833 16.5 25.4333 16.5 23.5C16.5 21.5667 17.1833 19.9167 18.55 18.55C19.9167 17.1833 21.5667 16.5 23.5 16.5C25.4333 16.5 27.0833 17.1833 28.45 18.55C29.8167 19.9167 30.5 21.5667 30.5 23.5C30.5 25.4333 29.8167 27.0833 28.45 28.45C27.0833 29.8167 25.4333 30.5 23.5 30.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

4
public/Workflow.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.477 21V22.0983C24.477 22.7049 23.9834 23.1966 23.3746 23.1966H19.6537C18.7404 23.1966 18 23.9342 18 24.8441C18 24.8441 18 25.3924 18 26M24.523 21V22.0983C24.523 22.7049 25.0166 23.1966 25.6254 23.1966H29.3463C30.2596 23.1966 31 23.9342 31 24.8441C31 24.8441 31 25.3924 31 26" stroke="white" stroke-width="1.5"/>
<path d="M18.3398 27.0215C18.9395 27.0215 19.3439 27.0221 19.6553 27.0479C19.9577 27.0729 20.1056 27.1185 20.2051 27.1699C20.4522 27.2978 20.6544 27.5012 20.7822 27.752C20.8341 27.8539 20.8793 28.0045 20.9043 28.3096C20.93 28.624 20.9307 29.0321 20.9307 29.6357C20.9307 30.2395 20.93 30.6475 20.9043 30.9619C20.8793 31.2676 20.8342 31.4185 20.7822 31.5205C20.6543 31.7712 20.4522 31.9747 20.2051 32.1025C20.1056 32.154 19.9577 32.1986 19.6553 32.2236C19.3439 32.2494 18.9395 32.25 18.3398 32.25C17.7406 32.25 17.3367 32.2494 17.0254 32.2236C16.7233 32.1986 16.5751 32.1539 16.4756 32.1025C16.2285 31.9747 16.0263 31.7712 15.8984 31.5205C15.8464 31.4185 15.8013 31.2676 15.7764 30.9619C15.7507 30.6475 15.75 30.2395 15.75 29.6357C15.75 29.0321 15.7507 28.624 15.7764 28.3096C15.8013 28.0044 15.8465 27.8539 15.8984 27.752C16.0263 27.5012 16.2284 27.2978 16.4756 27.1699C16.5751 27.1185 16.723 27.0729 17.0254 27.0479C17.3367 27.0221 17.7406 27.0215 18.3398 27.0215ZM30.6602 27.0215C31.2594 27.0215 31.6633 27.0221 31.9746 27.0479C32.277 27.0729 32.4249 27.1185 32.5244 27.1699C32.7716 27.2978 32.9737 27.5012 33.1016 27.752C33.1535 27.8539 33.1987 28.0044 33.2236 28.3096C33.2493 28.624 33.25 29.0321 33.25 29.6357C33.25 30.2395 33.2493 30.6475 33.2236 30.9619C33.1987 31.2676 33.1536 31.4185 33.1016 31.5205C32.9737 31.7712 32.7715 31.9747 32.5244 32.1025C32.4249 32.1539 32.2768 32.1986 31.9746 32.2236C31.6633 32.2494 31.2594 32.25 30.6602 32.25C30.0605 32.25 29.6561 32.2494 29.3447 32.2236C29.0423 32.1986 28.8944 32.154 28.7949 32.1025C28.5478 31.9747 28.3457 31.7712 28.2178 31.5205C28.1658 31.4185 28.1207 31.2676 28.0957 30.9619C28.07 30.6475 28.0693 30.2395 28.0693 29.6357C28.0693 29.0321 28.07 28.624 28.0957 28.3096C28.1207 28.0045 28.1659 27.8539 28.2178 27.752C28.3456 27.5012 28.5478 27.2978 28.7949 27.1699C28.8944 27.1185 29.0423 27.0729 29.3447 27.0479C29.6561 27.0221 30.0605 27.0215 30.6602 27.0215ZM24.2393 15.75C24.8388 15.75 25.2433 15.7506 25.5547 15.7764C25.857 15.8014 26.005 15.846 26.1045 15.8975C26.3516 16.0253 26.5537 16.2288 26.6816 16.4795C26.7337 16.5815 26.7787 16.7324 26.8037 17.0381C26.8294 17.3525 26.8301 17.7605 26.8301 18.3643C26.8301 18.9679 26.8294 19.376 26.8037 19.6904C26.7788 19.9956 26.7336 20.1461 26.6816 20.248C26.5538 20.4988 26.3516 20.7022 26.1045 20.8301C26.005 20.8815 25.8571 20.9271 25.5547 20.9521C25.2433 20.9779 24.8388 20.9785 24.2393 20.9785C23.64 20.9785 23.2361 20.9779 22.9248 20.9521C22.6224 20.9271 22.4745 20.8815 22.375 20.8301C22.1279 20.7022 21.9257 20.4988 21.7979 20.248C21.7459 20.1461 21.7007 19.9956 21.6758 19.6904C21.6501 19.376 21.6494 18.9679 21.6494 18.3643C21.6494 17.7605 21.6501 17.3525 21.6758 17.0381C21.7008 16.7324 21.7458 16.5815 21.7979 16.4795C21.9258 16.2288 22.1279 16.0253 22.375 15.8975C22.4745 15.846 22.6226 15.8014 22.9248 15.7764C23.2361 15.7506 23.64 15.75 24.2393 15.75Z" stroke="white" stroke-width="1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

5
public/fi-rr-home.svg Normal file
View File

@ -0,0 +1,5 @@
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="fi-rr-home">
<path id="Vector" d="M32 21.5L30.35 14H15.65L14.018 21.3373L14 22.25C14.0027 22.974 14.2694 23.6721 14.75 24.2135V29.75C14.75 30.3467 14.9871 30.919 15.409 31.341C15.831 31.7629 16.4033 32 17 32H29C29.5967 32 30.169 31.7629 30.591 31.341C31.0129 30.919 31.25 30.3467 31.25 29.75V24.2135C31.7306 23.6721 31.9973 22.974 32 22.25V21.5ZM15.5 21.5817L16.85 15.5H19.25V18.5H20.75V15.5H25.25V18.5H26.75V15.5H29.15L30.5 21.5817V22.25C30.5 22.6478 30.342 23.0294 30.0607 23.3107C29.7794 23.592 29.3978 23.75 29 23.75H28.25C27.8522 23.75 27.4706 23.592 27.1893 23.3107C26.908 23.0294 26.75 22.6478 26.75 22.25H25.25C25.25 22.6478 25.092 23.0294 24.8107 23.3107C24.5294 23.592 24.1478 23.75 23.75 23.75H22.25C21.8522 23.75 21.4706 23.592 21.1893 23.3107C20.908 23.0294 20.75 22.6478 20.75 22.25H19.25C19.25 22.6478 19.092 23.0294 18.8107 23.3107C18.5294 23.592 18.1478 23.75 17.75 23.75H17C16.6022 23.75 16.2206 23.592 15.9393 23.3107C15.658 23.0294 15.5 22.6478 15.5 22.25V21.5817ZM29 30.5H17C16.8011 30.5 16.6103 30.421 16.4697 30.2803C16.329 30.1397 16.25 29.9489 16.25 29.75V25.1435C16.4944 25.211 16.7465 25.2468 17 25.25H17.75C18.1774 25.2486 18.5995 25.1554 18.9878 24.9765C19.376 24.7977 19.7212 24.5375 20 24.2135C20.2788 24.5375 20.624 24.7977 21.0122 24.9765C21.4005 25.1554 21.8226 25.2486 22.25 25.25H23.75C24.1759 25.2502 24.5969 25.1596 24.9849 24.984C25.3729 24.8085 25.719 24.5522 26 24.2323C26.281 24.5522 26.6271 24.8085 27.0151 24.984C27.4031 25.1596 27.8241 25.2502 28.25 25.25H29C29.2535 25.2468 29.5056 25.211 29.75 25.1435V29.75C29.75 29.9489 29.671 30.1397 29.5303 30.2803C29.3897 30.421 29.1989 30.5 29 30.5Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

10
public/profile.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 2.8 MiB

1
public/vite.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

18
src/App.tsx Normal file
View File

@ -0,0 +1,18 @@
/**
* Main App component
* @description Root application component wiring TanStack Router
*/
import { RouterProvider } from '@tanstack/react-router';
import { router } from './routes';
/**
* App component
* @description Application entry point
* @returns App element
*/
function App() {
return <RouterProvider router={router} />;
}
export default App;

1
src/assets/react.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,48 @@
/**
* Agent Card Component
* @description Displays agent information with tags and description
*/
/**
* AgentCard component props
*/
interface AgentCardProps {
title: string;
tags: string[];
description: string;
}
/**
* AgentCard component
* @description Card showing agent details with tags
* @param props - Component props
* @returns AgentCard element
*/
export function AgentCard({ title, tags, description }: AgentCardProps) {
// Define your colors in order
const tagColors = [
"bg-[#E5E8F4]", // 1st tag (index 0)
"bg-[#E9D7FF]", // 2nd tag (index 1)
"bg-[#E2F6B2]", // 3rd tag (index 2)
];
return (
<div className="bg-white rounded-xl p-6 shadow-sm border border-gray-100 card-hover">
<h3 className="text-lg font-semibold text-gray-900 mb-3">{title}</h3>
<div className="flex flex-wrap gap-2 mb-4">
{tags.map((tag, index) => (
<span
key={index}
/* Use the index to pick the color; fall back to the first color if index > 2 */
className={`${tagColors[index] || tagColors[0]} px-3 py-1 text-xs font-medium text-gray-700 border border-gray-200`}
>
{tag}
</span>
))}
</div>
<p className="text-sm text-gray-600 leading-relaxed">{description}</p>
</div>
);
}

View File

@ -0,0 +1,8 @@
/**
* Dashboard components barrel export
* @description Centralized exports for dashboard components
*/
export { Sidebar } from './sidebar';
export { MetricCard } from './metric-card';
export { AgentCard } from './agent-card';

View File

@ -0,0 +1,72 @@
/**
* Metric Card Component
* @description Displays metric information with gradient background
*/
/**
* MetricCard component props
*/
interface MetricCardProps {
title: string;
subtitle: string;
value: string;
gradient: 'blue-teal' | 'pink-purple' | 'orange-yellow' | 'blue-purple';
}
/**
* MetricCard component
* @description Card showing metric with gradient background and premium styling
* @param props - Component props
* @returns MetricCard element
*/
export function MetricCard({ title, subtitle, value, gradient }: MetricCardProps) {
const gradients = {
'blue-teal': ' bg-gradient-to-br from-[#001B2F] via-[#0626A8] to-[#039A98] text-white ',
'pink-purple': 'bg-gradient-to-br from-[#FF6B8B] via-[#944D8F] to-[#51459E]',
'orange-yellow': 'bg-gradient-to-br from-[#FF9D42] to-[#F17E31]',
'blue-purple': 'bg-gradient-to-br from-[#2D5BFF] to-[#8E34FF]',
};
// return (
// <div className={`${gradients[gradient]} rounded-[24px] p-6 text-white card-hover cursor-pointer relative overflow-hidden h-[120px] group transition-all duration-300`}>
// {/* Right side decorative vertical bar */}
// <div className="absolute right-0 top-0 bottom-0 w-[28%] bg-white/10 backdrop-blur-[2px]" />
// <div className="flex justify-between items-center h-full relative z-10 font-['Poppins']">
// <div className="flex flex-col justify-center">
// <p className="text-[11px] font-semibold tracking-wider opacity-90 uppercase mb-0.5">
// {title}
// </p>
// <h3 className="text-[22px] font-bold leading-tight">
// {subtitle}
// </h3>
// </div>
// <div className="flex items-center justify-center min-w-[60px]">
// <span className="text-[48px] font-bold tracking-tighter leading-none">
// {value}
// </span>
// </div>
// </div>
// </div>
// );
return (
<div className={`p-6 h-[110px] rounded-2xl ${gradients[gradient]} w-full `}>
<div className="flex items-center justify-between w-full ">
<div className="flex flex-col">
<span className="text-[12px] font-medium text-white uppercase tracking-wider">
{title}
</span>
<span className="text-[18px] font-bold mt-1 text-white">
{subtitle}
</span>
</div>
<div className="text-5xl font-bold text-white">
{value}
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,60 @@
/**
* Dashboard Sidebar Component
* @description Vertical navigation sidebar with icons
*/
import { Home, Settings } from 'lucide-react';
/**
* Sidebar component
* @description Left sidebar navigation with icon menu
* @returns Sidebar element
*/
export function Sidebar() {
return (
<aside className="fixed left-6 top-24 bottom-6 w-16 bg-gradient-to-b from-[#00A1A0] to-[#00166D] flex flex-col items-center py-6 gap-6 z-50 rounded-2xl shadow-xl">
{/* Navigation Icons */}
<nav className="flex flex-col items-center gap-5 flex-1 w-full">
{/* Home - Active State */}
<button className="w-[42px] h-[42px] bg-white/20 rounded-xl flex items-center justify-center text-white shadow-inner transition-all hover:bg-white/30" aria-label="Home">
<Home className="w-5 h-5 text-white" />
</button>
<button className="sidebar-icon-v3" aria-label="Agent">
<img src="/Agent.svg" alt="Agent" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="KB">
<img src="/KB.svg" alt="KB" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="Models">
<img src="/Models.svg" alt="Models" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="Workflow">
<img src="/Workflow.svg" alt="Workflow" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="Nav Item">
<img src="/Nav item.svg" alt="Nav Item" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="LLM">
<img src="/LLM.svg" alt="LLM" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="FT">
<img src="/FT.svg" alt="FT" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="Task Watcher">
<img src="/Task watacher.svg" alt="Task Watcher" className="w-[42px] h-[42px] " />
</button>
<button className="sidebar-icon-v3" aria-label="Optimization">
<img src="/Optimization.svg" alt="Optimization" className="w-[42px] h-[42px] " />
</button>
</nav>
{/* Bottom Icon */}
<div className="flex flex-col gap-4 mt-auto">
<button className="sidebar-icon-v3" aria-label="Settings">
<Settings className="w-5 h-5 text-white" />
</button>
</div>
</aside>
);
}

View File

@ -0,0 +1,76 @@
/**
* Header Component
* @description Global top header with logo, notifications, theme toggle, and profile
*/
import { useState } from 'react';
import { Bell, Moon, Sun, ChevronDown } from 'lucide-react';
/**
* Header component
* @description Top navigation header with logo and user actions
* @returns Header element
*/
export function Header() {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
return (
<header className="fixed top-0 mt-[24px] mb-[16px] left-0 right-0 h-16 z-[100] backdrop-blur-md flex items-center justify-between px-8">
{/* Logo */}
<div className="flex items-center">
<img
src="/Logo.png"
alt="AgenticIQ Logo"
width={168}
height={60}
className="object-contain"
/>
</div>
{/* Right Actions */}
<div className="bg-white rounded-[20px] p-2 flex items-center gap-2 shadow-sm border border-gray-100/50">
{/* Bell Notification */}
<button className="p-2.5 bg-[#F4F9FF] hover:bg-[#E9F3FF] rounded-xl transition-all duration-200">
<Bell className="w-5 h-5 text-[#1A1A1A]" strokeWidth={1.5} />
</button>
{/* Theme Toggles */}
<div className="flex items-center gap-1.5 px-1">
<button
onClick={() => setTheme('light')}
className={`p-2.5 rounded-full transition-all duration-300 ${
theme === 'light'
? 'bg-[#0033FF] text-white shadow-lg shadow-blue-500/40 scale-105'
: 'bg-[#F4F9FF] text-gray-500 hover:text-gray-700'
}`}
>
<Sun className="w-5 h-5" strokeWidth={theme === 'light' ? 2 : 1.5} />
</button>
<button
onClick={() => setTheme('dark')}
className={`p-2.5 rounded-full transition-all duration-300 ${
theme === 'dark'
? 'bg-[#0052FF] text-white shadow-lg shadow-blue-500/40 scale-105'
: 'bg-[#F4F9FF] text-gray-500 hover:text-gray-700'
}`}
>
<Moon className="w-5 h-5" strokeWidth={theme === 'dark' ? 2 : 1.5} />
</button>
</div>
{/* Profile Section */}
<div className="flex items-center gap-2 pl-1 pr-2">
<div className="w-10 h-10 rounded-full overflow-hidden border-2 border-white shadow-sm ring-1 ring-gray-100">
<img
src="/profile.svg"
alt="User Avatar"
className="w-full h-full"
/>
</div>
<ChevronDown className="w-4 h-4 text-gray-900" strokeWidth={2.5} />
</div>
</div>
</header>
);
}

View File

@ -0,0 +1,8 @@
/**
* Layout Components
* @description Exports for layout-related components
*/
export { RootLayout } from './root-layout';
export { Header } from './header';

View File

@ -0,0 +1,47 @@
/**
* Root Layout Component
* @description Main application layout with sidebar, header, and content area
*/
import type { ReactNode } from 'react';
import { Sidebar } from '@/components/dashboard/sidebar';
import { Header } from './header';
interface RootLayoutProps {
children: ReactNode;
}
/**
* RootLayout component
* @description Wraps all pages with consistent sidebar and header layout
* @param children - Page content to render
* @returns RootLayout element
*/
export function RootLayout({ children }: RootLayoutProps) {
return (
<div
className="min-h-screen"
style={{
backgroundColor: '#F5F8FF',
backgroundImage: `
radial-gradient(at 0% 0%, #C8FAFF 0px, transparent 50%),
radial-gradient(at 100% 0%, #C6D7FE 0px, transparent 50%),
radial-gradient(at 100% 100%, #00CEE022 0px, transparent 50%),
radial-gradient(at 0% 100%, #6172F311 0px, transparent 50%)
`,
}}
>
{/* Global Header */}
<Header />
{/* Sidebar */}
<Sidebar />
{/* Main Content Area */}
<main className="ml-24 pt-16 min-h-screen">
{children}
</main>
</div>
);
}

View File

@ -0,0 +1,3 @@
// Placeholder for components/ui directory
// shadcn/ui components will be added here
export { }

View File

@ -0,0 +1,70 @@
/**
* Button component
* @description Reusable button component with variants
*/
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
outline:
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
/**
* Button component with multiple variants
* @description Accessible button component with size and variant options
* @param variant - Visual style variant
* @param size - Button size
* @param className - Additional CSS classes
* @param children - Button content
* @returns Button element
* @example
* <Button variant="default" size="lg">Click me</Button>
*/
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, ...props }, ref) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }

35
src/constants/api.ts Normal file
View File

@ -0,0 +1,35 @@
/**
* API configuration constants
* @description Central location for API-related configuration
*/
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api'
export const API_TIMEOUT = 30000 // 30 seconds
export const API_ENDPOINTS = {
AUTH: {
LOGIN: '/auth/login',
LOGOUT: '/auth/logout',
REGISTER: '/auth/register',
REFRESH: '/auth/refresh',
},
USERS: {
LIST: '/users',
DETAIL: (id: string) => `/users/${id}`,
CREATE: '/users',
UPDATE: (id: string) => `/users/${id}`,
DELETE: (id: string) => `/users/${id}`,
},
} as const
export const HTTP_STATUS = {
OK: 200,
CREATED: 201,
NO_CONTENT: 204,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
INTERNAL_SERVER_ERROR: 500,
} as const

58
src/hooks/index.ts Normal file
View File

@ -0,0 +1,58 @@
/**
* Custom React hooks
* @description Reusable hooks following AgenticIQ best practices
*/
import { useState, useEffect } from 'react'
/**
* Hook for managing media queries
* @description Tracks whether a media query matches
* @param query - Media query string
* @returns Boolean indicating if query matches
* @example
* const isMobile = useMediaQuery('(max-width: 768px)')
*/
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(false)
useEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => setMatches(media.matches)
media.addEventListener('change', listener)
return () => media.removeEventListener('change', listener)
}, [matches, query])
return matches
}
/**
* Hook for debouncing values
* @description Delays updating a value until after a specified delay
* @param value - Value to debounce
* @param delay - Delay in milliseconds
* @returns Debounced value
* @example
* const debouncedSearch = useDebounce(searchTerm, 500)
*/
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debouncedValue
}

64
src/index.css Normal file
View File

@ -0,0 +1,64 @@
@import "tailwindcss";
@layer base {
body {
font-family: 'Poppins', sans-serif;
font-size: 12px;
}
:root {
/* Color System */
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}
@layer utilities {
.card-hover {
@apply transition-all duration-300 hover:shadow-lg hover:-translate-y-1;
}
.sidebar-icon-v3 {
@apply w-[42px] h-[42px] flex items-center justify-center text-white hover:bg-white/10 rounded-xl transition-all duration-300;
}
}

14
src/lib/utils.ts Normal file
View File

@ -0,0 +1,14 @@
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
/**
* Combines class names using clsx and merges Tailwind classes
* @description Utility function for conditional class names with Tailwind CSS
* @param inputs - Class values to combine
* @returns Merged class string
* @example
* cn("text-red-500", condition && "bg-blue-500")
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

28
src/main.tsx Normal file
View File

@ -0,0 +1,28 @@
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import './index.css';
import App from './App.tsx';
import { store } from './store';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
// Avoid aggressive refetching and favor cached data for performance.
staleTime: 5 * 60 * 1000,
refetchOnWindowFocus: false,
retry: 2,
},
},
});
createRoot(document.getElementById('root')!).render(
<StrictMode>
<Provider store={store}>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</Provider>
</StrictMode>,
);

150
src/pages/dashboard.tsx Normal file
View File

@ -0,0 +1,150 @@
/**
* Dashboard Page Component
* @description Main dashboard page with metrics and agent cards
*/
import { useState } from 'react';
import { MetricCard } from '@/components/dashboard/metric-card';
import { AgentCard } from '@/components/dashboard/agent-card';
import { Button } from '@/components/ui/button';
import { Search, Plus } from 'lucide-react';
/**
* Dashboard component
* @description Main dashboard page with all sections
* @returns Dashboard element
*/
export function Dashboard() {
const [activeTab, setActiveTab] = useState<'all' | 'my'>('all');
const agents = [
{
title: 'Customer Support Agent',
tags: ['GPT-4', 'Chat Interface'],
description: 'Automates customer service inquiries with intelligent escalation and context preservation.',
},
{
title: 'Document Analyst',
tags: ['Claude-3', 'PDF Processing', 'Knowledge Graph'],
description: 'Analyzes documents to extract insights and generate comprehensive reports automatically.',
},
{
title: 'Sales Qualifier',
tags: ['Lead Scoring', 'CRM Integration', 'Email Autom...'],
description: 'Qualifies prospects, schedules meetings, and manages follow-up communications with tracking.',
},
{
title: 'Customer Support Agent',
tags: ['GPT-4', 'Chat Interface'],
description: 'Automates customer service inquiries with intelligent escalation and context preservation.',
},
{
title: 'Document Analyst',
tags: ['Claude-3', 'PDF Processing', 'Knowledge Graph'],
description: 'Analyzes documents to extract insights and generate comprehensive reports automatically.',
},
{
title: 'Sales Qualifier',
tags: ['Lead Scoring', 'CRM Integration', 'Email Autom...'],
description: 'Qualifies prospects, schedules meetings, and manages follow-up communications with tracking.',
},
];
return (
<div className="px-8 pt-8">
{/* Content Header: Welcome + Search/Create */}
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
<div>
<h1 className="text-[22px] font-semibold text-gray-900 mb-2">
Welcome, Vijay! 👋
</h1>
<p className="text-gray-500 max-w-2xl text-[16px]">
Monitor and manage your intelligent agents, knowledge bases, and automated workflows from a centralized dashboard
</p>
</div>
<div className="flex items-center gap-3">
<div className="relative group">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 group-focus-within:text-blue-500 transition-colors" />
<input
type="text"
placeholder="Search"
className="pl-10 pr-4 py-2.5 bg-white border border-gray-200 rounded-xl text-sm focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 w-64 shadow-sm transition-all"
/>
</div>
<Button className="bg-[#0033FF] hover:bg-[#0042CC] text-white px-6 py-2.5 rounded-xl font-semibold flex items-center gap-2 shadow-lg shadow-blue-500/20 active:scale-95 transition-all h-auto">
<Plus className="w-5 h-5" />
Create Agent
</Button>
</div>
</div>
{/* Metrics Grid */}
<div className="bg-[#F3F8FF]/80 backdrop-blur-sm rounded-[32px] p-6 mb-8 border border-white/40 shadow-sm">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<MetricCard
title="ACTIVE AGENTS"
subtitle="Agents"
value="03"
gradient="blue-teal"
/>
<MetricCard
title="KNOWLEDGE BASES"
subtitle="Knowledge Bases"
value="02"
gradient="pink-purple"
/>
<MetricCard
title="ACTIVE WORKFLOWS"
subtitle="Workflows"
value="01"
gradient="orange-yellow"
/>
<MetricCard
title="CONNECTED TOOLS"
subtitle="Tools"
value="01"
gradient="blue-purple"
/>
</div>
</div>
{/* Agents Section */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 p-6">
{/* Tabs */}
<div className="flex gap-4 mb-6">
<button
onClick={() => setActiveTab('all')}
className={`px-6 py-2 rounded-lg text font-medium transition-colors ${activeTab === 'all'
? 'bg-black text-white'
: 'bg-white text-gray-600 border border-gray-300 hover:bg-gray-50'
}`}
>
All Agents
</button>
<button
onClick={() => setActiveTab('my')}
className={`px-6 py-2 rounded-lg font-medium transition-colors ${activeTab === 'my'
? 'bg-black text-white'
: 'bg-white text-gray-600 border border-gray-300 hover:bg-gray-50'
}`}
>
My Agents
</button>
</div>
{/* Agent Cards Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{agents.map((agent, index) => (
<AgentCard
key={index}
title={agent.title}
tags={agent.tags}
description={agent.description}
/>
))}
</div>
</div>
</div>
);
}

53
src/pages/sign-in.tsx Normal file
View File

@ -0,0 +1,53 @@
/**
* Sign In Page
* @description Basic sign-in form for existing users.
*/
import { Link } from '@tanstack/react-router';
export function SignInPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-[#C8FAFF] via-[#F5F8FF] to-[#C6D7FE] px-4 py-12">
<div className="w-full max-w-md rounded-2xl bg-white p-8 shadow-xl">
<div className="mb-6 text-center">
<img src="/Logo.png" alt="AgenticIQ Logo" className="mx-auto h-10 w-auto" />
<h1 className="mt-4 text-2xl font-semibold text-gray-900">Welcome back</h1>
<p className="mt-1 text-sm text-gray-500">Sign in to continue to your dashboard.</p>
</div>
<form className="space-y-4">
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">Email</label>
<input
type="email"
className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
placeholder="you@example.com"
/>
</div>
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">Password</label>
<input
type="password"
className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
placeholder="••••••••"
/>
</div>
<button
type="submit"
className="w-full rounded-lg bg-[#0033FF] px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-blue-500/20 transition hover:bg-[#0042CC]"
>
Sign In
</button>
</form>
<p className="mt-4 text-center text-sm text-gray-600">
New here?{' '}
<Link to="/signup" className="font-semibold text-[#0033FF] hover:underline">
Create an account
</Link>
</p>
</div>
</div>
);
}

61
src/pages/sign-up.tsx Normal file
View File

@ -0,0 +1,61 @@
/**
* Sign Up Page
* @description Basic sign-up form for new users.
*/
import { Link } from '@tanstack/react-router';
export function SignUpPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-[#C8FAFF] via-[#F5F8FF] to-[#C6D7FE] px-4 py-12">
<div className="w-full max-w-md rounded-2xl bg-white p-8 shadow-xl">
<div className="mb-6 text-center">
<img src="/Logo.png" alt="AgenticIQ Logo" className="mx-auto h-10 w-auto" />
<h1 className="mt-4 text-2xl font-semibold text-gray-900">Create your account</h1>
<p className="mt-1 text-sm text-gray-500">Join AgenticIQ to manage your agents and workflows.</p>
</div>
<form className="space-y-4">
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">Full name</label>
<input
type="text"
className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
placeholder="Jane Doe"
/>
</div>
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">Email</label>
<input
type="email"
className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
placeholder="you@example.com"
/>
</div>
<div>
<label className="mb-1 block text-sm font-medium text-gray-700">Password</label>
<input
type="password"
className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500/20"
placeholder="••••••••"
/>
</div>
<button
type="submit"
className="w-full rounded-lg bg-[#0033FF] px-4 py-2.5 text-sm font-semibold text-white shadow-lg shadow-blue-500/20 transition hover:bg-[#0042CC]"
>
Sign Up
</button>
</form>
<p className="mt-4 text-center text-sm text-gray-600">
Already have an account?{' '}
<Link to="/" className="font-semibold text-[#0033FF] hover:underline">
Sign in
</Link>
</p>
</div>
</div>
);
}

65
src/routes.tsx Normal file
View File

@ -0,0 +1,65 @@
/**
* Application Routes
* @description Defines public and authenticated routes using TanStack Router.
*/
import { createRootRoute, createRoute, createRouter, Outlet } from '@tanstack/react-router';
import { RootLayout } from '@/components/layout';
import { Dashboard } from '@/pages/dashboard';
import { SignInPage } from '@/pages/sign-in';
import { SignUpPage } from '@/pages/sign-up';
const rootRoute = createRootRoute({
component: () => <Outlet />,
});
const publicRoute = createRoute({
getParentRoute: () => rootRoute,
id: 'public',
component: () => <Outlet />,
});
const appRoute = createRoute({
getParentRoute: () => rootRoute,
id: 'app',
component: () => (
<RootLayout>
<Outlet />
</RootLayout>
),
});
const signInRoute = createRoute({
getParentRoute: () => publicRoute,
path: '/',
component: SignInPage,
});
const signUpRoute = createRoute({
getParentRoute: () => publicRoute,
path: '/signup',
component: SignUpPage,
});
const dashboardRoute = createRoute({
getParentRoute: () => appRoute,
path: '/dashboard',
component: Dashboard,
});
const routeTree = rootRoute.addChildren([
publicRoute.addChildren([signInRoute, signUpRoute]),
appRoute.addChildren([dashboardRoute]),
]);
export const router = createRouter({
routeTree,
defaultPreload: 'intent',
});
declare module '@tanstack/react-router' {
interface Register {
router: typeof router;
}
}

122
src/services/api.ts Normal file
View File

@ -0,0 +1,122 @@
/**
* API service layer
* @description Handles HTTP requests with error handling
*/
import { API_BASE_URL, API_TIMEOUT } from '@/constants/api'
import type { ApiResponse, ApiError } from '@/types'
/**
* Base fetch wrapper with error handling
* @description Makes HTTP requests with standardized error handling
* @param endpoint - API endpoint path
* @param options - Fetch options
* @returns Promise with API response
* @throws {ApiError} When request fails
* @example
* const data = await fetchApi('/users', { method: 'GET' })
*/
export async function fetchApi<T>(
endpoint: string,
options?: RequestInit
): Promise<ApiResponse<T>> {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT)
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
...options,
signal: controller.signal,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
})
clearTimeout(timeoutId)
if (!response.ok) {
const error: ApiError = {
message: `HTTP ${response.status}: ${response.statusText}`,
code: `HTTP_${response.status}`,
}
throw error
}
const data = await response.json()
return data
} catch (error) {
clearTimeout(timeoutId)
if (error instanceof Error) {
if (error.name === 'AbortError') {
throw {
message: 'Request timeout',
code: 'TIMEOUT',
} as ApiError
}
throw {
message: error.message,
code: 'NETWORK_ERROR',
} as ApiError
}
throw error
}
}
/**
* GET request helper
* @description Performs GET request
* @param endpoint - API endpoint
* @returns Promise with response data
*/
export async function getRequest<T>(endpoint: string): Promise<ApiResponse<T>> {
return fetchApi<T>(endpoint, { method: 'GET' })
}
/**
* POST request helper
* @description Performs POST request
* @param endpoint - API endpoint
* @param data - Request body data
* @returns Promise with response data
*/
export async function postRequest<T, D = unknown>(
endpoint: string,
data: D
): Promise<ApiResponse<T>> {
return fetchApi<T>(endpoint, {
method: 'POST',
body: JSON.stringify(data),
})
}
/**
* PUT request helper
* @description Performs PUT request
* @param endpoint - API endpoint
* @param data - Request body data
* @returns Promise with response data
*/
export async function putRequest<T, D = unknown>(
endpoint: string,
data: D
): Promise<ApiResponse<T>> {
return fetchApi<T>(endpoint, {
method: 'PUT',
body: JSON.stringify(data),
})
}
/**
* DELETE request helper
* @description Performs DELETE request
* @param endpoint - API endpoint
* @returns Promise with response data
*/
export async function deleteRequest<T>(
endpoint: string
): Promise<ApiResponse<T>> {
return fetchApi<T>(endpoint, { method: 'DELETE' })
}

36
src/store/auth-slice.ts Normal file
View File

@ -0,0 +1,36 @@
/**
* Auth slice
* @description Minimal authentication slice to hold auth state.
*/
import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit';
export interface AuthState {
isAuthenticated: boolean;
userEmail?: string;
}
const initialState: AuthState = {
isAuthenticated: false,
userEmail: undefined,
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
signIn(state, action: PayloadAction<{ email: string }>) {
state.isAuthenticated = true;
state.userEmail = action.payload.email;
},
signOut(state) {
state.isAuthenticated = false;
state.userEmail = undefined;
},
},
});
export const { signIn, signOut } = authSlice.actions;
export const authReducer = authSlice.reducer;

17
src/store/index.ts Normal file
View File

@ -0,0 +1,17 @@
/**
* Redux store
* @description Centralized store configuration following guidelines.
*/
import { configureStore } from '@reduxjs/toolkit';
import { authReducer } from './auth-slice';
export const store = configureStore({
reducer: {
auth: authReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

27
src/types/index.ts Normal file
View File

@ -0,0 +1,27 @@
/**
* Application-wide type definitions
* @description TypeScript interfaces and types for the application
*/
export interface User {
id: string
email: string
firstName: string
lastName: string
createdAt: string
updatedAt: string
}
export interface ApiResponse<T> {
data: T
message?: string
success: boolean
}
export interface ApiError {
message: string
code: string
details?: Record<string, unknown>
}
export type LoadingState = 'idle' | 'loading' | 'success' | 'error'

41
tsconfig.app.json Normal file
View File

@ -0,0 +1,41 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": [
"ES2022",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"types": [
"vite/client"
],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
/* Path Aliases */
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": [
"src"
]
}

19
tsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"files": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.node.json"
}
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"./src/*"
]
}
}
}

26
tsconfig.node.json Normal file
View File

@ -0,0 +1,26 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": ["ES2023"],
"module": "ESNext",
"types": ["node"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}

18
vite.config.ts Normal file
View File

@ -0,0 +1,18 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import path from 'path'
import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss(),
],
server: {
port: 3000,
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
})