diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3a798be --- /dev/null +++ b/.env.example @@ -0,0 +1,48 @@ +# OpenAI Configuration +OPENAI_API_KEY=your_openai_api_key_here +OPENAI_ORGANIZATION=your_openai_organization_here + +# Anthropic Configuration (optional) +ANTHROPIC_API_KEY=your_anthropic_api_key_here + +# Google AI Configuration (optional) +GOOGLE_AI_API_KEY=your_google_ai_api_key_here + +# Authentication +NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_SECRET=your_nextauth_secret_here + +# Database +DATABASE_URL=postgresql://username:password@localhost:5432/aiagent_platform + +# Redis (for caching and real-time features) +REDIS_URL=redis://localhost:6379 + +# Vector Database (Pinecone) +PINECONE_API_KEY=your_pinecone_api_key_here +PINECONE_ENVIRONMENT=your_pinecone_environment_here + +# LangChain Configuration +LANGCHAIN_TRACING_V2=true +LANGCHAIN_ENDPOINT=https://api.smith.langchain.com +LANGCHAIN_API_KEY=your_langchain_api_key_here +LANGCHAIN_PROJECT=your_langchain_project_here + +# Email Configuration (for notifications) +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_USER=your_email@gmail.com +SMTP_PASSWORD=your_app_password_here + +# AWS Configuration (for file storage) +AWS_ACCESS_KEY_ID=your_aws_access_key_here +AWS_SECRET_ACCESS_KEY=your_aws_secret_key_here +AWS_REGION=us-east-1 +AWS_S3_BUCKET=your_s3_bucket_here + +# Analytics +VERCEL_ANALYTICS_ID=your_vercel_analytics_id_here + +# Development +NODE_ENV=development +NEXT_PUBLIC_APP_URL=http://localhost:3000 \ No newline at end of file diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..0788a95 --- /dev/null +++ b/next.config.js @@ -0,0 +1,28 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + serverActions: true, + serverComponentsExternalPackages: ['@langchain/core', '@langchain/openai'], + }, + webpack: (config) => { + config.resolve.alias = { + ...config.resolve.alias, + '@': './src', + }; + return config; + }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: '**', + }, + ], + }, + env: { + NEXTAUTH_URL: process.env.NEXTAUTH_URL, + NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET, + }, +}; + +module.exports = nextConfig; \ No newline at end of file diff --git a/package.json b/package.json index f856f0a..7d13a40 100644 --- a/package.json +++ b/package.json @@ -1,133 +1,143 @@ { - "name": "twotone", - "version": "0.0.2", - "description": "", - "author": { - "name": "Brian Chirls" - }, - "contributors": [ - { - "name": "Cristian Vogel", - "url": "https://github.com/cristianvogel" - }, - { - "name": "Brian Chirls", - "url": "https://github.com/brianchirls" - } - ], - "main": "index.js", - "engines": { - "node": "^14.0.0" - }, - "scripts": { - "lint": "eslint ./; true", - "lint-fix": "eslint --fix ./; true", - "start": "NODE_ENV=development webpack-dev-server", - "dev": "NODE_ENV=development webpack", - "build": "NODE_ENV=production webpack", - "deploy": "gh-pages -d ./build", - "github-labels": "node -r dotenv/config ./node_modules/github-label-sync/bin/github-label-sync.js -l ./devops/labels.json datavized/twotone", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "license": "MPL-2.0", - "devDependencies": { - "@babel/core": "^7.16.7", - "@babel/plugin-proposal-class-properties": "^7.16.7", - "@babel/plugin-proposal-object-rest-spread": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/plugin-transform-react-jsx": "^7.16.7", - "@babel/plugin-transform-react-jsx-self": "^7.16.7", - "@babel/plugin-transform-react-jsx-source": "^7.16.7", - "@babel/plugin-transform-runtime": "^7.16.7", - "@babel/polyfill": "^7.12.1", - "@babel/preset-env": "^7.16.7", - "@babel/preset-react": "^7.16.7", - "autoprefixer": "^9.6.1", - "babel-loader": "^8.2.3", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24", - "bluebird": "^3.5.5", - "case-sensitive-paths-webpack-plugin": "^2.2.0", - "clean-webpack-plugin": "^3.0.0", - "copy-webpack-plugin": "^6.3.2", - "datavized-code-style": "github:datavized/code-style", - "dotenv": "^8.1.0", - "eslint": "^6.3.0", - "eslint-config-crockford": "^2.0.0", - "eslint-loader": "^3.0.0", - "eslint-plugin-babel": "^5.3.1", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", - "exports-loader": "^0.7.0", - "fast-async": "^7.0.6", - "favicons-webpack-plugin": "^4.2.0", - "file-loader": "^4.2.0", - "gh-pages": "^3.1.0", - "github-label-sync": "^1.4.1", - "html-loader": "^0.5.5", - "html-webpack-plugin": "^4.5.1", - "imagemin-mozjpeg": "^8.0.0", - "imagemin-webpack-plugin": "^2.4.2", - "postcss-flexbugs-fixes": "^4.1.0", - "postcss-loader": "^3.0.0", - "react-dev-utils": "^12.0.0", - "react-hot-loader": "^4.12.12", - "style-loader": "^1.0.0", - "unused-files-webpack-plugin": "^3.4.0", - "url-loader": "^2.1.0", - "webpack": "^4.39.3", - "webpack-build-notifier": "^1.1.1", - "webpack-bundle-analyzer": "^3.4.1", - "webpack-cli": "^3.3.7", - "webpack-dev-server": "^3.8.0", - "webpack-merge": "^4.2.2", - "webpack-sources": "^1.4.3", - "workbox-webpack-plugin": "^4.3.1", - "xlsx": ">=0.17.0" - }, - "dependencies": { - "@hot-loader/react-dom": "^17.0.2", - "@material-ui/core": "^3.9.3", - "@material-ui/icons": "^3.0.2", - "@material-ui/lab": "^3.0.0-alpha.30", - "audio-metadata": "^0.3.0", - "audio-recorder-polyfill": "^0.1.6", - "browser-id3-writer": "^4.2.0", - "bulma": "^0.9.3", - "classnames": "^2.2.6", - "debounce": "^1.2.0", - "error-stack-parser": "^2.0.3", - "event-emitter": "^0.3.5", - "fast-deep-equal": "^2.0.1", - "file-saver": "^2.0.2", - "idb-keyval": "^3.2.0", - "ismobilejs": "^1.0.2", - "jsmediatags": "^3.9.2", - "lamejs": "^1.2.0", - "mui-virtualized-table": "^2.2.3", - "node-sass": "^7.0.1", - "parsecurrency": "^1.0.0", - "postcss": "^8.4.5", - "postcss-scss": "^4.0.3", - "pouchdb": "^7.1.1", - "prop-types": "^15.7.2", - "rc-slider": "^9.0.0", - "react": "^16.9.0", - "react-confirm": "^0.1.18", - "react-dom": "^16.9.0", - "react-dropzone": "^10.1.8", - "react-joyride": "^2.1.1", - "react-mic-record": "github:datavized/react-mic-record#hack", - "react-sortable-hoc": "^1.10.1", - "react-virtualized": "^9.21.1", - "serialize-error": "^4.1.0", - "standardized-audio-context": "^21.2.1", - "to-id": "^2.0.0", - "unistore": "^3.4.1", - "wav-encoder": "^1.3.0", - "webmidi": ">=3.0.1", - "worker-loader": "^2.0.0", - "xlsx": ">=0.17.0" - } + "name": "aiagent-platform", + "version": "1.0.0", + "description": "Professional AI Agent Platform - Build, Deploy, and Manage AI Agents", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "lint:fix": "next lint --fix", + "type-check": "tsc --noEmit", + "test": "jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage", + "analyze": "cross-env ANALYZE=true next build", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "db:generate": "prisma generate", + "db:push": "prisma db push", + "db:studio": "prisma studio" + }, + "dependencies": { + "@ai-sdk/openai": "^0.0.66", + "@auth/prisma-adapter": "^1.4.0", + "@hookform/resolvers": "^3.3.4", + "@langchain/core": "^0.1.48", + "@langchain/openai": "^0.0.15", + "@next-auth/prisma-adapter": "^1.0.7", + "@prisma/client": "^5.10.2", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-alert-dialog": "^1.0.5", + "@radix-ui/react-avatar": "^1.0.4", + "@radix-ui/react-badge": "^1.0.4", + "@radix-ui/react-button": "^1.0.4", + "@radix-ui/react-card": "^1.0.4", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.6", + "@radix-ui/react-form": "^0.0.3", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-navigation-menu": "^1.1.4", + "@radix-ui/react-progress": "^1.0.3", + "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-sheet": "^1.0.4", + "@radix-ui/react-skeleton": "^1.0.4", + "@radix-ui/react-slider": "^1.1.2", + "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.0.3", + "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-textarea": "^1.0.4", + "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", + "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-query": "^5.25.0", + "@tanstack/react-table": "^8.13.2", + "@vercel/analytics": "^1.2.2", + "@vercel/speed-insights": "^1.0.10", + "ai": "^3.0.9", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.0", + "cmdk": "^0.2.1", + "date-fns": "^3.3.1", + "framer-motion": "^11.0.6", + "langchain": "^0.1.25", + "lucide-react": "^0.336.0", + "next": "14.1.0", + "next-auth": "^4.24.6", + "next-themes": "^0.2.1", + "openai": "^4.28.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-hook-form": "^7.50.1", + "react-hot-toast": "^2.4.1", + "react-markdown": "^9.0.1", + "react-syntax-highlighter": "^15.5.0", + "recharts": "^2.12.1", + "remark-gfm": "^4.0.0", + "socket.io-client": "^4.7.4", + "tailwind-merge": "^2.2.1", + "tailwindcss-animate": "^1.0.7", + "vaul": "^0.9.0", + "zod": "^3.22.4", + "zustand": "^4.5.1" + }, + "devDependencies": { + "@next/bundle-analyzer": "^14.1.0", + "@storybook/addon-essentials": "^7.6.17", + "@storybook/addon-interactions": "^7.6.17", + "@storybook/addon-links": "^7.6.17", + "@storybook/addon-onboarding": "^1.0.11", + "@storybook/blocks": "^7.6.17", + "@storybook/nextjs": "^7.6.17", + "@storybook/react": "^7.6.17", + "@storybook/test": "^7.6.17", + "@testing-library/jest-dom": "^6.4.2", + "@testing-library/react": "^14.2.1", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", + "@types/node": "^20.11.20", + "@types/react": "^18.2.57", + "@types/react-dom": "^18.2.19", + "@types/react-syntax-highlighter": "^15.5.11", + "@typescript-eslint/eslint-plugin": "^7.0.2", + "@typescript-eslint/parser": "^7.0.2", + "autoprefixer": "^10.4.17", + "cross-env": "^7.0.3", + "eslint": "^8.56.0", + "eslint-config-next": "14.1.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-storybook": "^0.8.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "postcss": "^8.4.35", + "prettier": "^3.2.5", + "prisma": "^5.10.2", + "storybook": "^7.6.17", + "tailwindcss": "^3.4.1", + "typescript": "^5.3.3" + }, + "keywords": [ + "ai", + "agents", + "platform", + "langchain", + "openai", + "nextjs", + "typescript", + "ai-platform", + "multi-agent", + "conversational-ai" + ], + "author": { + "name": "AI Agent Platform Team" + }, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..96bb01e --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..ac62507 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,210 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 240 5.9% 10%; + --primary-foreground: 0 0% 98%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 240 5.9% 10%; + --radius: 0.5rem; + } + + .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +@layer components { + .gradient-text { + @apply bg-gradient-to-r from-primary to-blue-600 bg-clip-text text-transparent; + } + + .ai-chat-bubble { + @apply relative bg-card border rounded-lg p-4 shadow-sm; + } + + .ai-chat-bubble::before { + content: ''; + @apply absolute -left-2 top-3 w-0 h-0 border-t-8 border-b-8 border-r-8 border-t-transparent border-b-transparent border-r-card; + } + + .user-chat-bubble { + @apply relative bg-primary text-primary-foreground rounded-lg p-4 shadow-sm; + } + + .user-chat-bubble::before { + content: ''; + @apply absolute -right-2 top-3 w-0 h-0 border-t-8 border-b-8 border-l-8 border-t-transparent border-b-transparent border-l-primary; + } + + .loading-dots { + @apply flex space-x-1; + } + + .loading-dots > div { + @apply w-2 h-2 bg-primary rounded-full animate-pulse; + } + + .loading-dots > div:nth-child(2) { + animation-delay: 0.2s; + } + + .loading-dots > div:nth-child(3) { + animation-delay: 0.4s; + } + + .glass-effect { + @apply bg-white/10 backdrop-blur-lg border border-white/20; + } + + .dark .glass-effect { + @apply bg-black/10 backdrop-blur-lg border border-white/10; + } + + .scrollbar-hide { + -ms-overflow-style: none; + scrollbar-width: none; + } + + .scrollbar-hide::-webkit-scrollbar { + display: none; + } + + .agent-card { + @apply bg-card border rounded-lg p-6 shadow-sm hover:shadow-md transition-shadow cursor-pointer; + } + + .agent-card:hover { + @apply border-primary/50; + } + + .code-block { + @apply bg-muted rounded-lg p-4 overflow-x-auto font-mono text-sm; + } + + .typing-indicator { + @apply inline-block w-4 h-4 bg-primary rounded-full animate-pulse; + } +} + +@layer utilities { + .animation-delay-200 { + animation-delay: 200ms; + } + + .animation-delay-400 { + animation-delay: 400ms; + } + + .animation-delay-600 { + animation-delay: 600ms; + } +} + +/* Custom scrollbar styles */ +.custom-scrollbar::-webkit-scrollbar { + width: 8px; +} + +.custom-scrollbar::-webkit-scrollbar-track { + @apply bg-muted rounded-lg; +} + +.custom-scrollbar::-webkit-scrollbar-thumb { + @apply bg-border rounded-lg; +} + +.custom-scrollbar::-webkit-scrollbar-thumb:hover { + @apply bg-primary/50; +} + +/* Smooth transitions for theme switching */ +* { + transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease; +} + +/* Loading animation for agent responses */ +@keyframes typing { + from { width: 0 } + to { width: 100% } +} + +@keyframes blink-caret { + from, to { border-color: transparent } + 50% { border-color: orange; } +} + +/* Gradient backgrounds for hero sections */ +.hero-gradient { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +} + +.dark .hero-gradient { + background: linear-gradient(135deg, #2D3748 0%, #1A202C 100%); +} + +/* Custom focus styles for accessibility */ +.focus-visible:focus-visible { + @apply outline-none ring-2 ring-primary ring-offset-2; +} + +/* Agent status indicators */ +.agent-status-online { + @apply bg-green-500 animate-pulse; +} + +.agent-status-offline { + @apply bg-gray-400; +} + +.agent-status-busy { + @apply bg-yellow-500 animate-pulse; +} + +.agent-status-error { + @apply bg-red-500 animate-pulse; +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..652c4a6 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,105 @@ +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import './globals.css' +import { ThemeProvider } from '@/components/theme-provider' +import { Toaster } from '@/components/ui/toaster' +import { QueryProvider } from '@/components/providers/query-provider' +import { AuthProvider } from '@/components/providers/auth-provider' +import { Analytics } from '@vercel/analytics/react' +import { SpeedInsights } from '@vercel/speed-insights/next' + +const inter = Inter({ subsets: ['latin'] }) + +export const metadata: Metadata = { + title: 'AI Agent Platform - Build, Deploy, and Manage AI Agents', + description: 'The most advanced AI agent platform for building, deploying, and managing intelligent AI agents. Create custom agents, integrate with APIs, and scale your AI operations.', + keywords: ['ai', 'agents', 'platform', 'automation', 'langchain', 'openai', 'artificial intelligence', 'chatbots', 'ai tools'], + authors: [{ name: 'AI Agent Platform Team' }], + creator: 'AI Agent Platform', + publisher: 'AI Agent Platform', + formatDetection: { + email: false, + address: false, + telephone: false, + }, + metadataBase: new URL(process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'), + alternates: { + canonical: '/', + }, + openGraph: { + title: 'AI Agent Platform - Build, Deploy, and Manage AI Agents', + description: 'The most advanced AI agent platform for building, deploying, and managing intelligent AI agents.', + url: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000', + siteName: 'AI Agent Platform', + locale: 'en_US', + type: 'website', + images: [ + { + url: '/og-image.png', + width: 1200, + height: 630, + alt: 'AI Agent Platform', + }, + ], + }, + twitter: { + card: 'summary_large_image', + title: 'AI Agent Platform - Build, Deploy, and Manage AI Agents', + description: 'The most advanced AI agent platform for building, deploying, and managing intelligent AI agents.', + images: ['/og-image.png'], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-video-preview': -1, + 'max-image-preview': 'large', + 'max-snippet': -1, + }, + }, + manifest: '/manifest.json', + icons: { + icon: '/favicon.ico', + shortcut: '/favicon-16x16.png', + apple: '/apple-touch-icon.png', + }, +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + + + + + + + + +
+
+ {children} +
+
+ +
+
+
+ + + + + ) +} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..05634e2 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,32 @@ +import { Button } from '@/components/ui/button' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { Badge } from '@/components/ui/badge' +import { ArrowRight, Bot, Zap, Shield, Users, BarChart3, Sparkles } from 'lucide-react' +import Link from 'next/link' +import { Header } from '@/components/layout/header' +import { HeroSection } from '@/components/sections/hero-section' +import { FeaturesSection } from '@/components/sections/features-section' +import { AgentShowcase } from '@/components/sections/agent-showcase' +import { StatsSection } from '@/components/sections/stats-section' +import { TestimonialsSection } from '@/components/sections/testimonials-section' +import { PricingSection } from '@/components/sections/pricing-section' +import { Footer } from '@/components/layout/footer' + +export default function HomePage() { + return ( +
+
+ +
+ + + + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..cf0c3b0 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,114 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + darkMode: ["class"], + content: [ + './pages/**/*.{ts,tsx}', + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './src/**/*.{ts,tsx}', + ], + theme: { + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: 0 }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: 0 }, + }, + "slide-in": { + "0%": { transform: "translateX(-100%)" }, + "100%": { transform: "translateX(0)" }, + }, + "slide-out": { + "0%": { transform: "translateX(0)" }, + "100%": { transform: "translateX(-100%)" }, + }, + "fade-in": { + "0%": { opacity: 0 }, + "100%": { opacity: 1 }, + }, + "fade-out": { + "0%": { opacity: 1 }, + "100%": { opacity: 0 }, + }, + "pulse-slow": { + "0%, 100%": { opacity: 1 }, + "50%": { opacity: 0.5 }, + }, + "typing": { + "from": { width: "0" }, + "to": { width: "100%" }, + }, + "blink": { + "50%": { borderColor: "transparent" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + "slide-in": "slide-in 0.3s ease-out", + "slide-out": "slide-out 0.3s ease-out", + "fade-in": "fade-in 0.3s ease-out", + "fade-out": "fade-out 0.3s ease-out", + "pulse-slow": "pulse-slow 2s ease-in-out infinite", + "typing": "typing 3.5s steps(30, end)", + "blink": "blink 1s step-end infinite", + }, + backgroundImage: { + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', + }, + }, + }, + plugins: [require("tailwindcss-animate")], +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..91924b0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,45 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "es6"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"], + "@/components/*": ["./src/components/*"], + "@/lib/*": ["./src/lib/*"], + "@/utils/*": ["./src/utils/*"], + "@/types/*": ["./src/types/*"], + "@/hooks/*": ["./src/hooks/*"], + "@/app/*": ["./src/app/*"], + "@/store/*": ["./src/store/*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules", + ".next", + "dist", + "build" + ] +} \ No newline at end of file