-
-
-
-
-
-
-
CodeForge
-
- Low-Code Next.js App Builder with AI
-
-
-
-
-
-
-
-
Overview
-
- CodeForge is a comprehensive visual low-code platform for generating production-ready Next.js applications.
- It combines the power of visual designers with direct code editing, AI-powered generation, and a complete
- full-stack development toolkit.
-
-
-
-
-
-
-
- Key Features
-
-
-
- }
- title="Monaco Code Editor"
- description="Full-featured code editor with syntax highlighting, autocomplete, and AI-powered improvements"
- />
- }
- title="Prisma Schema Designer"
- description="Visual database model designer with automatic schema generation and AI assistance"
- />
- }
- title="Component Tree Builder"
- description="Hierarchical component structure builder with drag-and-drop and AI generation"
- />
- }
- title="Theme Designer"
- description="Material UI theme customizer with multiple variants, custom colors, and AI theme generation"
- />
- }
- title="Flask Backend Designer"
- description="Visual Python Flask API designer with blueprints, endpoints, and CORS configuration"
- />
- }
- title="Playwright Test Designer"
- description="E2E test builder with step configuration and AI test generation"
- />
- }
- title="Unit Test Designer"
- description="Comprehensive test suite builder for components, functions, hooks, and integration tests"
- />
- }
- title="Auto Error Repair"
- description="Automated error detection and AI-powered code repair system"
- />
- }
- title="Project Settings"
- description="Configure Next.js options, npm packages, scripts, and build settings"
- />
- }
- title="AI Integration"
- description="OpenAI-powered generation across all features for rapid development"
- />
-
-
-
-
-
Getting Started
-
-
-
-
- 1
- Create Your First Model
-
-
- Navigate to the Models tab and create your database schema using the visual designer
- or describe your data model to the AI.
-
-
-
-
- 2
- Design Your Components
-
-
- Use the Components tab to build your UI hierarchy visually or let the AI generate
- component structures based on your requirements.
-
-
-
-
- 3
- Customize Your Theme
-
-
- Head to the Styling tab to create custom color palettes, manage theme variants (light/dark),
- and configure typography.
-
-
-
-
- 4
- Build Your Backend
-
-
- Configure your Flask API in the Flask API tab by creating blueprints and endpoints
- with full CORS and authentication support.
-
-
-
-
- 5
- Export Your Project
-
-
- Click Export Project to generate all files including Next.js pages, Prisma schemas,
- Flask backend, tests, and configuration files ready for deployment.
-
-
-
-
-
-
-
-
AI-Powered Features
-
- CodeForge integrates OpenAI across every designer to accelerate development:
-
-
-
-
-
-
Technology Stack
-
-
-
- Frontend
-
-
-
-
-
- Next.js 14 with App Router
-
-
-
- React 18 with TypeScript
-
-
-
- Material UI 5
-
-
-
- Monaco Editor
-
-
-
- Tailwind CSS
-
-
-
-
-
-
- Backend & Tools
-
-
-
-
-
- Flask REST API
-
-
-
- Prisma ORM
-
-
-
- Playwright E2E Testing
-
-
-
- Vitest & React Testing Library
-
-
-
- Storybook for Components
-
-
-
-
-
-
-
-
-
-
-
- Pro Tips
-
-
-
- 💡 Use the AI Generate feature to quickly scaffold entire applications from descriptions
- 💡 The Error Repair tab automatically scans and fixes common issues - check it before exporting
- 💡 Create multiple theme variants (light, dark, custom) in the Styling tab for complete theme support
- 💡 Test your components with Storybook stories before writing full E2E tests
- 💡 Flask blueprints help organize your API endpoints by feature or resource
-
-
-
+
-
-
-
-
- Product Roadmap
-
-
- Features delivered and planned for CodeForge development
-
-
-
-
-
-
-
-
-
Completed Features
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Planned Features
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
- Agents Files
-
-
- AI agent configuration and service architecture
-
-
-
-
-
-
AI Service Architecture
-
- CodeForge uses a modular AI service architecture that integrates OpenAI's GPT models across all features.
- Each designer has specialized prompts and validation logic to ensure high-quality generated code.
-
-
-
-
- Core AI Services
- Primary modules handling AI operations
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AI Integration Points
- Features enhanced by AI capabilities
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Prompt Engineering
- How we optimize AI interactions
-
-
-
-
Context Preservation
-
- All AI prompts include relevant project context such as existing models, components,
- and theme configurations to ensure generated code integrates seamlessly.
-
-
-
-
Format Specification
-
- Prompts specify exact output formats (JSON, TypeScript, Python) with strict schemas
- to ensure parseable and valid responses.
-
-
-
-
Best Practices Enforcement
-
- Generated code follows Next.js, React, and Flask best practices through detailed
- prompt instructions and post-processing validation.
-
-
-
-
Error Handling
-
- Fallback mechanisms and retry logic ensure graceful degradation when AI services
- are unavailable or responses are malformed.
-
-
-
-
-
-
-
-
-
- Future AI Enhancements
-
-
-
-
-
-
- Multi-Model Support: Integration with Claude, Gemini, and other LLMs for specialized tasks
-
-
-
- Fine-Tuned Models: Custom models trained on specific frameworks and design patterns
-
-
-
- Code Review Agent: Automated code review with security and performance analysis
-
-
-
- Conversational Interface: Chat-based project building with natural language commands
-
-
-
- Learning System: AI that learns from user corrections and preferences over time
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
Progressive Web App
-
- Offline-first experience with native-like capabilities
-
-
-
-
-
-
-
-
Overview
-
- CodeForge is a fully-featured Progressive Web App that can be installed on any device and works offline.
- With intelligent caching, automatic updates, and native app-like features, you can build applications anywhere, anytime.
-
-
-
-
-
- PWA Features
- Native app capabilities in your browser
-
-
-
-
-
- Installable
-
-
- Install on desktop or mobile for quick access from your home screen or applications menu
-
-
-
-
-
- Offline Support
-
-
- Work without internet connection; changes sync automatically when you reconnect
-
-
-
-
-
- Automatic Updates
-
-
- Get notified when new versions are available with one-click updates
-
-
-
-
-
- Push Notifications
-
-
- Opt-in to receive updates about builds, errors, and new features
-
-
-
-
-
- App Shortcuts
-
-
- Quick access to Dashboard, Code Editor, and Models from your OS
-
-
-
-
-
- Share Target
-
-
- Share code files directly to CodeForge from other apps
-
-
-
-
-
-
-
Installation
-
-
-
-
- Desktop Installation
-
-
-
-
Chrome/Edge/Brave:
-
- Look for install icon (⊕) in address bar
- Click "Install" or use prompt in app
- App added to applications menu
-
-
-
-
Safari (macOS):
-
- Click File → Add to Dock
- App appears in Dock
-
-
-
-
-
-
-
- Mobile Installation
-
-
-
-
iOS (Safari):
-
- Tap Share button
- Select "Add to Home Screen"
- Tap "Add"
-
-
-
-
Android (Chrome):
-
- Tap menu (three dots)
- Select "Install app"
- Confirm installation
-
-
-
-
-
-
-
-
-
PWA Settings
-
- Navigate to the PWA tab to manage all Progressive Web App features:
-
-
-
-
- Available Controls
-
-
-
-
Installation Status
-
- Check if app is installed and trigger installation if available
-
-
-
-
-
Network Status
-
- Real-time online/offline indicator with connectivity information
-
-
-
-
-
Push Notifications
-
- Toggle notifications and manage permissions
-
-
-
-
-
Cache Management
-
- View cache size, service worker status, and clear cached data
-
-
-
-
-
Update Management
-
- Install pending updates when new versions are available
-
-
-
-
-
-
-
-
Offline Capabilities
-
-
-
-
-
-
- Works Offline
-
-
-
-
-
- •
- View and edit existing projects
-
-
- •
- Browse files and code
-
-
- •
- Use Monaco editor
-
-
- •
- Navigate all tabs
-
-
- •
- View documentation
-
-
- •
- Make changes locally
-
-
-
-
-
-
-
-
-
- Requires Internet
-
-
-
-
-
- •
- AI-powered generation
-
-
- •
- External font loading
-
-
- •
- Database sync
-
-
- •
- External resources
-
-
-
-
-
-
-
-
-
-
-
- Pro Tips
-
-
-
-
-
- •
- Install for best performance: Installed apps load faster and work more reliably offline
-
-
- •
- Save before going offline: Ensure projects are saved to local storage before losing connection
-
-
- •
- Clear cache if issues arise: Use PWA settings to clear cache and reload with fresh data
-
-
- •
- Enable notifications: Stay informed about updates and build completions
-
-
- •
- Update regularly: New versions bring performance improvements and features
-
-
-
-
-
+
-
-
-
-
-
-
Sass Styles Guide
-
- Custom Material UI components with Sass
-
-
-
-
-
-
-
-
Overview
-
- CodeForge includes a comprehensive Sass-based styling system for non-standard Material UI components.
- This system provides pre-built components, utilities, mixins, and animations that extend beyond the
- standard Material UI component library.
-
-
-
-
-
- File Structure
-
-
-
-
src/styles/_variables.scss
-
- Color palettes, spacing scales, typography, transitions, and other design tokens
-
-
-
-
src/styles/_utilities.scss
-
- Mixins and functions for responsive design, colors, typography, and layout helpers
-
-
-
-
src/styles/_animations.scss
-
- Keyframe animations and animation utility classes for transitions and effects
-
-
-
-
src/styles/material-ui-custom.scss
-
- Custom Material UI component styles with variants and states
-
-
-
-
src/styles/main.scss
-
- Main entry point that imports all Sass modules and provides layout components
-
-
-
-
-
-
-
- Available Components
- Custom Material UI components built with Sass
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Layout Components
- Sass-powered layout utilities
-
-
- }
- title="custom-mui-container"
- description="Max-width container with responsive padding"
- />
- }
- title="custom-mui-grid"
- description="CSS Grid layouts with responsive columns (--cols-1 to --cols-12, --responsive)"
- />
- }
- title="custom-mui-flex"
- description="Flexbox utilities (--row, --col, --wrap, --center, --between, --around)"
- />
- }
- title="custom-mui-stack"
- description="Vertical/horizontal stacks with configurable gaps"
- />
- }
- title="custom-mui-surface"
- description="Interactive surfaces with elevation and hover effects"
- />
-
-
-
-
-
- Sass Utilities & Mixins
- Reusable functions for custom styling
-
-
-
-
-
-
- Responsive Design
-
-
-
@include respond-to($breakpoint)
-
Generate media queries for xs, sm, md, lg, xl, 2xl breakpoints
-
-{`@include respond-to('lg') {
- padding: 2rem;
-}`}
-
-
-
-
-
-
-
-
-
- Elevation & Shadows
-
-
-
@include elevation($level)
-
Apply box shadows with levels 1-4
-
-{`@include elevation(2);`}
-
-
-
-
-
-
-
-
-
- Glassmorphism
-
-
-
@include glassmorphism($blur, $opacity)
-
Create frosted glass effects with backdrop blur
-
-{`@include glassmorphism(16px, 0.1);`}
-
-
-
-
-
-
-
-
-
- Color Functions
-
-
-
get-color($palette, $shade)
-
Access colors from predefined palettes (primary, secondary, accent, success, error, warning)
-
-{`color: get-color('primary', 500);`}
-
-
-
-
-
-
-
-
-
- Text Truncation
-
-
-
@include truncate($lines)
-
Truncate text with ellipsis after specified lines
-
-{`@include truncate(2);`}
-
-
-
-
-
-
-
-
-
- Custom Scrollbars
-
-
-
@include show-scrollbar($track, $thumb)
-
Style webkit scrollbars with custom colors
-
-{`@include show-scrollbar(rgba(0,0,0,0.1), rgba(0,0,0,0.3));`}
-
-
-
-
-
-
-
-
-
- Animation Classes
- Pre-built animation utilities
-
-
-
-
-
-
-
-
-
-
- Quick Start Example
-
-
-
-
-
Using Custom Components
-
-{`import './styles/main.scss'
-
-function MyComponent() {
- return (
-
-
-
-
Card Title
-
Card content
-
- Click Me
-
-
-
-
- )
-}`}
-
-
-
-
-
-
-
Creating Custom Styles with Mixins
-
-{`@use './styles/utilities' as *;
-@use './styles/variables' as *;
-
-.my-custom-component {
- @include elevation(2);
- @include responsive-padding(spacing('6'));
- background: get-color('primary', 500);
-
- @include respond-to('md') {
- @include elevation(3);
- }
-
- &:hover {
- @include glassmorphism(12px, 0.15);
- }
-}`}
-
-
-
-
-
-
-
-
-
- Best Practices
-
-
-
-
-
-
- Import main.scss in your index.css to access all Sass components and utilities
-
-
-
- Use @use instead of @import for better module encapsulation
-
-
-
- Leverage mixins for consistent spacing, elevation, and responsive design
-
-
-
- Extend existing component classes rather than creating from scratch
-
-
-
- Use animation classes sparingly and respect prefers-reduced-motion
-
-
-
- Customize variables in _variables.scss to match your design system
-
-
-
-
-
+
-
-
-
-
-
-
-
-
CI/CD Guide
-
- Complete deployment automation for multiple platforms
-
-
-
-
-
-
-
-
Overview
-
- CodeForge includes production-ready CI/CD configurations for GitHub Actions, GitLab CI, Jenkins,
- and CircleCI. Each pipeline includes linting, testing, security scanning, Docker image building,
- and automated deployment workflows.
-
-
-
-
-
- Available Configurations
-
-
-
-
-
-
-
-
-
-
-
Pipeline Stages
-
- All CI/CD configurations follow a similar multi-stage pipeline structure:
-
-
-
-
-
-
- Docker Configuration
- Containerization for production deployment
-
-
-
-
Files Included
-
-
-
Dockerfile
-
Multi-stage build with Node.js builder and Nginx runtime
-
-
-
nginx.conf
-
Production Nginx configuration with health checks and caching
-
-
-
docker-compose.yml
-
Local development and deployment orchestration
-
-
-
.dockerignore
-
Optimized build context by excluding unnecessary files
-
-
-
-
-
-
-
-
Docker Commands
-
-{`# Build image locally
-docker build -t codeforge:local .
-
-# Run container
-docker run -p 3000:80 codeforge:local
-
-# Use docker-compose
-docker-compose up -d
-
-# Pull from registry
-docker pull ghcr.io//:latest`}
-
-
-
-
-
-
-
Features
-
-
-
- Multi-stage build reduces final image size to ~50MB
-
-
-
- Nginx serves static files with gzip compression
-
-
-
- Health check endpoint at /health for orchestration
-
-
-
- Automatic cache headers for static assets
-
-
-
- SPA routing support with fallback to index.html
-
-
-
-
-
-
-
-
- Environment Variables
- Required configuration for CI/CD platforms
-
-
-
-
-
-
-
- Variable
- Description
- Required
-
-
-
-
- NODE_VERSION
- Node.js version (default: 20)
- No
-
-
- REGISTRY
- Docker registry URL (default: ghcr.io)
- No
-
-
- STAGING_WEBHOOK_URL
- Webhook for staging deployments
- Optional
-
-
- PRODUCTION_WEBHOOK_URL
- Webhook for production deployments
- Optional
-
-
- CODECOV_TOKEN
- Codecov integration token
- Optional
-
-
- SLACK_WEBHOOK
- Slack webhook for notifications
- Optional
-
-
-
-
-
-
-
-
-
-
Branch Strategy
-
-
-
-
-
-
-
main
-
- Production branch - deploys to production environment (manual approval required)
-
-
-
-
-
-
-
-
-
-
-
develop
-
- Development branch - automatically deploys to staging environment
-
-
-
-
-
-
-
-
-
-
-
feature/*
-
- Feature branches - runs tests only, no deployment
-
-
-
-
-
-
-
-
-
-
-
v* tags
-
- Version tags - triggers release workflow with artifacts and changelog
-
-
-
-
-
-
-
-
-
-
-
-
- Quick Start
-
-
-
-
-
-
- 1
- Choose Your Platform
-
-
- Select GitHub Actions, GitLab CI, Jenkins, or CircleCI based on your infrastructure
-
-
-
-
- 2
- Configure Secrets
-
-
- Add required environment variables and secrets in your platform's settings
-
-
-
-
- 3
- Push to Repository
-
-
- Push code to main or develop branch to trigger the CI/CD pipeline
-
-
-
-
- 4
- Monitor Pipeline
-
-
- View pipeline status, test results, and deployment logs in your platform's dashboard
-
-
-
-
-
-
-
-
-
-
- Best Practices
-
-
-
-
-
-
- Never commit secrets - use environment variables and platform secret management
-
-
-
- Enable branch protection on main and develop branches
-
-
-
- Require code reviews and passing tests before merging
-
-
-
- Use manual approval gates for production deployments
-
-
-
- Monitor security scan results and fix vulnerabilities promptly
-
-
-
- Keep dependencies updated with Dependabot or Renovate
-
-
-
- Use semantic versioning for releases (v1.0.0, v1.1.0, etc.)
-
-
-
- Configure Slack or email notifications for deployment status
-
-
-
-
-
-
-
-
-
- Additional Resources
-
-
-
-
-
-
- CI_CD_GUIDE.md - Detailed setup guide for all platforms
-
-
-
- .github/workflows/ - GitHub Actions workflows
-
-
-
- .gitlab-ci.yml - GitLab CI configuration
-
-
-
- Jenkinsfile - Jenkins pipeline definition
-
-
-
- .circleci/config.yml - CircleCI configuration
-
-
-
-
-
+
diff --git a/src/components/DocumentationView/AgentItems.tsx b/src/components/DocumentationView/AgentItems.tsx
new file mode 100644
index 0000000..68c59c8
--- /dev/null
+++ b/src/components/DocumentationView/AgentItems.tsx
@@ -0,0 +1,51 @@
+import { FileCode, CheckCircle, Sparkle } from '@phosphor-icons/react'
+
+export function AgentFileItem({ filename, path, description, features }: {
+ filename: string
+ path: string
+ description: string
+ features: string[]
+}) {
+ return (
+
+
+
+
+ {filename}
+
+
{path}
+
{description}
+
+
+
Key Features:
+
+ {features.map((feature) => (
+
+
+ {feature}
+
+ ))}
+
+
+
+ )
+}
+
+export function IntegrationPoint({ component, capabilities }: { component: string; capabilities: string[] }) {
+ return (
+
+
+
+ {component}
+
+
+ {capabilities.map((capability) => (
+
+ •
+ {capability}
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsCoreServices.tsx b/src/components/DocumentationView/AgentsCoreServices.tsx
new file mode 100644
index 0000000..363c148
--- /dev/null
+++ b/src/components/DocumentationView/AgentsCoreServices.tsx
@@ -0,0 +1,25 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import agentsData from '@/data/documentation/agents-data.json'
+import { AgentFileItem } from './AgentItems'
+
+export function AgentsCoreServices() {
+ return (
+
+
+ Core AI Services
+ Primary modules handling AI operations
+
+
+ {agentsData.coreServices.map((service) => (
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsFutureEnhancements.tsx b/src/components/DocumentationView/AgentsFutureEnhancements.tsx
new file mode 100644
index 0000000..f691cf4
--- /dev/null
+++ b/src/components/DocumentationView/AgentsFutureEnhancements.tsx
@@ -0,0 +1,28 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Target, Package } from '@phosphor-icons/react'
+import agentsData from '@/data/documentation/agents-data.json'
+
+export function AgentsFutureEnhancements() {
+ return (
+
+
+
+
+ Future AI Enhancements
+
+
+
+
+ {agentsData.futureEnhancements.map((item) => (
+
+
+
+ {item.title}: {item.description}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsIntegrationPoints.tsx b/src/components/DocumentationView/AgentsIntegrationPoints.tsx
new file mode 100644
index 0000000..58e8807
--- /dev/null
+++ b/src/components/DocumentationView/AgentsIntegrationPoints.tsx
@@ -0,0 +1,21 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import agentsData from '@/data/documentation/agents-data.json'
+import { IntegrationPoint } from './AgentItems'
+
+export function AgentsIntegrationPoints() {
+ return (
+
+
+ AI Integration Points
+ Features enhanced by AI capabilities
+
+
+
+ {agentsData.integrationPoints.map((point) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsOverviewSection.tsx b/src/components/DocumentationView/AgentsOverviewSection.tsx
new file mode 100644
index 0000000..464b5db
--- /dev/null
+++ b/src/components/DocumentationView/AgentsOverviewSection.tsx
@@ -0,0 +1,22 @@
+import { Separator } from '@/components/ui/separator'
+import { FileCode } from '@phosphor-icons/react'
+import agentsData from '@/data/documentation/agents-data.json'
+
+export function AgentsOverviewSection() {
+ return (
+
+
+
+ {agentsData.title}
+
+
{agentsData.subtitle}
+
+
+
+
+
AI Service Architecture
+
{agentsData.overview}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsPromptEngineering.tsx b/src/components/DocumentationView/AgentsPromptEngineering.tsx
new file mode 100644
index 0000000..72a44fc
--- /dev/null
+++ b/src/components/DocumentationView/AgentsPromptEngineering.tsx
@@ -0,0 +1,21 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import agentsData from '@/data/documentation/agents-data.json'
+
+export function AgentsPromptEngineering() {
+ return (
+
+
+ Prompt Engineering
+ How we optimize AI interactions
+
+
+ {agentsData.promptEngineering.map((item) => (
+
+
{item.title}
+
{item.description}
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/AgentsTab.tsx b/src/components/DocumentationView/AgentsTab.tsx
new file mode 100644
index 0000000..5483f2e
--- /dev/null
+++ b/src/components/DocumentationView/AgentsTab.tsx
@@ -0,0 +1,19 @@
+import { AgentsCoreServices } from './AgentsCoreServices'
+import { AgentsFutureEnhancements } from './AgentsFutureEnhancements'
+import { AgentsIntegrationPoints } from './AgentsIntegrationPoints'
+import { AgentsOverviewSection } from './AgentsOverviewSection'
+import { AgentsPromptEngineering } from './AgentsPromptEngineering'
+
+export function AgentsTab() {
+ return (
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdBestPracticesCard.tsx b/src/components/DocumentationView/CicdBestPracticesCard.tsx
new file mode 100644
index 0000000..6dfd065
--- /dev/null
+++ b/src/components/DocumentationView/CicdBestPracticesCard.tsx
@@ -0,0 +1,26 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { CheckCircle, Rocket } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdBestPracticesCard() {
+ return (
+
+
+
+
+ Best Practices
+
+
+
+
+ {cicdData.bestPractices.map((practice) => (
+
+
+ {practice}
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdBranchStrategySection.tsx b/src/components/DocumentationView/CicdBranchStrategySection.tsx
new file mode 100644
index 0000000..34d0a25
--- /dev/null
+++ b/src/components/DocumentationView/CicdBranchStrategySection.tsx
@@ -0,0 +1,48 @@
+import { Card, CardContent } from '@/components/ui/card'
+import { GitBranch } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+const toneStyles = {
+ green: {
+ card: 'bg-green-500/5 border-green-500/20',
+ icon: 'text-green-500'
+ },
+ blue: {
+ card: 'bg-blue-500/5 border-blue-500/20',
+ icon: 'text-blue-500'
+ },
+ purple: {
+ card: 'bg-purple-500/5 border-purple-500/20',
+ icon: 'text-purple-500'
+ },
+ orange: {
+ card: 'bg-orange-500/5 border-orange-500/20',
+ icon: 'text-orange-500'
+ }
+} as const
+
+export function CicdBranchStrategySection() {
+ return (
+
+
Branch Strategy
+
+ {cicdData.branches.map((branch) => {
+ const styles = toneStyles[branch.tone]
+ return (
+
+
+
+
+
+
{branch.name}
+
{branch.description}
+
+
+
+
+ )
+ })}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdDockerCard.tsx b/src/components/DocumentationView/CicdDockerCard.tsx
new file mode 100644
index 0000000..6f8e83b
--- /dev/null
+++ b/src/components/DocumentationView/CicdDockerCard.tsx
@@ -0,0 +1,49 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { Separator } from '@/components/ui/separator'
+import { CheckCircle } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdDockerCard() {
+ return (
+
+
+ Docker Configuration
+ Containerization for production deployment
+
+
+
+
Files Included
+
+ {cicdData.docker.files.map((file) => (
+
+
{file.name}
+
{file.description}
+
+ ))}
+
+
+
+
+
+
+
Docker Commands
+
{cicdData.docker.commands}
+
+
+
+
+
+
Features
+
+ {cicdData.docker.features.map((feature) => (
+
+
+ {feature}
+
+ ))}
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdEnvVarsCard.tsx b/src/components/DocumentationView/CicdEnvVarsCard.tsx
new file mode 100644
index 0000000..593a4b3
--- /dev/null
+++ b/src/components/DocumentationView/CicdEnvVarsCard.tsx
@@ -0,0 +1,39 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdEnvVarsCard() {
+ return (
+
+
+ Environment Variables
+ Required configuration for CI/CD platforms
+
+
+
+
+
+
+
+ Variable
+ Description
+ Required
+
+
+
+ {cicdData.environmentVariables.map((variable) => (
+
+
+ {variable.variable}
+
+ {variable.description}
+ {variable.required}
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdItems.tsx b/src/components/DocumentationView/CicdItems.tsx
new file mode 100644
index 0000000..c7f0601
--- /dev/null
+++ b/src/components/DocumentationView/CicdItems.tsx
@@ -0,0 +1,56 @@
+import { Badge } from '@/components/ui/badge'
+import { Card, CardContent } from '@/components/ui/card'
+import { CheckCircle, GitBranch } from '@phosphor-icons/react'
+
+export function CICDPlatformItem({ name, file, description, features }: {
+ name: string
+ file: string
+ description: string
+ features: string[]
+}) {
+ return (
+
+
+
+
+
{name}
+
+
{file}
+
{description}
+
+
+
Key Features:
+
+ {features.map((feature) => (
+
+
+ {feature}
+
+ ))}
+
+
+
+ )
+}
+
+export function PipelineStageCard({ stage, description, duration }: {
+ stage: string
+ description: string
+ duration: string
+}) {
+ return (
+
+
+
+
+
{stage}
+
{description}
+
+
+ {duration}
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdOverviewSection.tsx b/src/components/DocumentationView/CicdOverviewSection.tsx
new file mode 100644
index 0000000..47840b9
--- /dev/null
+++ b/src/components/DocumentationView/CicdOverviewSection.tsx
@@ -0,0 +1,26 @@
+import { Separator } from '@/components/ui/separator'
+import { GitBranch } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdOverviewSection() {
+ return (
+
+
+
+
+
+
+
{cicdData.title}
+
{cicdData.subtitle}
+
+
+
+
+
+
+
Overview
+
{cicdData.overview}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdPipelineSection.tsx b/src/components/DocumentationView/CicdPipelineSection.tsx
new file mode 100644
index 0000000..2d25d19
--- /dev/null
+++ b/src/components/DocumentationView/CicdPipelineSection.tsx
@@ -0,0 +1,21 @@
+import cicdData from '@/data/documentation/cicd-data.json'
+import { PipelineStageCard } from './CicdItems'
+
+export function CicdPipelineSection() {
+ return (
+
+
Pipeline Stages
+
{cicdData.pipeline.intro}
+
+ {cicdData.pipeline.stages.map((stage) => (
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdPlatformsCard.tsx b/src/components/DocumentationView/CicdPlatformsCard.tsx
new file mode 100644
index 0000000..cab3594
--- /dev/null
+++ b/src/components/DocumentationView/CicdPlatformsCard.tsx
@@ -0,0 +1,24 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import cicdData from '@/data/documentation/cicd-data.json'
+import { CICDPlatformItem } from './CicdItems'
+
+export function CicdPlatformsCard() {
+ return (
+
+
+ Available Configurations
+
+
+ {cicdData.platforms.map((platform) => (
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdQuickStartCard.tsx b/src/components/DocumentationView/CicdQuickStartCard.tsx
new file mode 100644
index 0000000..1658550
--- /dev/null
+++ b/src/components/DocumentationView/CicdQuickStartCard.tsx
@@ -0,0 +1,31 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Lightbulb } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdQuickStartCard() {
+ return (
+
+
+
+
+ Quick Start
+
+
+
+
+ {cicdData.quickStart.map((step) => (
+
+
+
+ {step.step}
+
+ {step.title}
+
+
{step.description}
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdResourcesCard.tsx b/src/components/DocumentationView/CicdResourcesCard.tsx
new file mode 100644
index 0000000..3df07b0
--- /dev/null
+++ b/src/components/DocumentationView/CicdResourcesCard.tsx
@@ -0,0 +1,28 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { FileCode, Package } from '@phosphor-icons/react'
+import cicdData from '@/data/documentation/cicd-data.json'
+
+export function CicdResourcesCard() {
+ return (
+
+
+
+
+ Additional Resources
+
+
+
+
+ {cicdData.resources.map((resource) => (
+
+
+
+ {resource.label} - {resource.description}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/CicdTab.tsx b/src/components/DocumentationView/CicdTab.tsx
new file mode 100644
index 0000000..56bc1be
--- /dev/null
+++ b/src/components/DocumentationView/CicdTab.tsx
@@ -0,0 +1,25 @@
+import { CicdBestPracticesCard } from './CicdBestPracticesCard'
+import { CicdBranchStrategySection } from './CicdBranchStrategySection'
+import { CicdDockerCard } from './CicdDockerCard'
+import { CicdEnvVarsCard } from './CicdEnvVarsCard'
+import { CicdOverviewSection } from './CicdOverviewSection'
+import { CicdPipelineSection } from './CicdPipelineSection'
+import { CicdPlatformsCard } from './CicdPlatformsCard'
+import { CicdQuickStartCard } from './CicdQuickStartCard'
+import { CicdResourcesCard } from './CicdResourcesCard'
+
+export function CicdTab() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/FeatureItems.tsx b/src/components/DocumentationView/FeatureItems.tsx
new file mode 100644
index 0000000..7558160
--- /dev/null
+++ b/src/components/DocumentationView/FeatureItems.tsx
@@ -0,0 +1,30 @@
+import { Card, CardContent } from '@/components/ui/card'
+import { Sparkle } from '@phosphor-icons/react'
+
+export function FeatureItem({ icon, title, description }: { icon: React.ReactNode; title: string; description: string }) {
+ return (
+
+
{icon}
+
+
{title}
+
{description}
+
+
+ )
+}
+
+export function AIFeatureCard({ title, description }: { title: string; description: string }) {
+ return (
+
+
+
+
+
+
{title}
+
{description}
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaFeaturesCard.tsx b/src/components/DocumentationView/PwaFeaturesCard.tsx
new file mode 100644
index 0000000..2f578f4
--- /dev/null
+++ b/src/components/DocumentationView/PwaFeaturesCard.tsx
@@ -0,0 +1,25 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { CheckCircle } from '@phosphor-icons/react'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+export function PwaFeaturesCard() {
+ return (
+
+
+ PWA Features
+ Native app capabilities in your browser
+
+
+ {pwaData.features.map((feature) => (
+
+
+
+ {feature.title}
+
+
{feature.description}
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaInstallationSection.tsx b/src/components/DocumentationView/PwaInstallationSection.tsx
new file mode 100644
index 0000000..d873755
--- /dev/null
+++ b/src/components/DocumentationView/PwaInstallationSection.tsx
@@ -0,0 +1,36 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+function InstallationCard({ title, items }: { title: string; items: { title: string; steps: string[] }[] }) {
+ return (
+
+
+ {title}
+
+
+ {items.map((item) => (
+
+
{item.title}
+
+ {item.steps.map((step) => (
+ {step}
+ ))}
+
+
+ ))}
+
+
+ )
+}
+
+export function PwaInstallationSection() {
+ return (
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaOfflineSection.tsx b/src/components/DocumentationView/PwaOfflineSection.tsx
new file mode 100644
index 0000000..5837ff7
--- /dev/null
+++ b/src/components/DocumentationView/PwaOfflineSection.tsx
@@ -0,0 +1,50 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { CheckCircle, Wrench } from '@phosphor-icons/react'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+function OfflineList({ items, accent }: { items: string[]; accent: boolean }) {
+ return (
+
+ {items.map((item) => (
+
+ •
+ {item}
+
+ ))}
+
+ )
+}
+
+export function PwaOfflineSection() {
+ return (
+
+
Offline Capabilities
+
+
+
+
+
+
+ Works Offline
+
+
+
+
+
+
+
+
+
+
+
+ Requires Internet
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaOverviewSection.tsx b/src/components/DocumentationView/PwaOverviewSection.tsx
new file mode 100644
index 0000000..1e8d4d3
--- /dev/null
+++ b/src/components/DocumentationView/PwaOverviewSection.tsx
@@ -0,0 +1,26 @@
+import { Separator } from '@/components/ui/separator'
+import { Rocket } from '@phosphor-icons/react'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+export function PwaOverviewSection() {
+ return (
+
+
+
+
+
+
+
{pwaData.title}
+
{pwaData.subtitle}
+
+
+
+
+
+
+
Overview
+
{pwaData.overview}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaProTipsCard.tsx b/src/components/DocumentationView/PwaProTipsCard.tsx
new file mode 100644
index 0000000..b8ba7e2
--- /dev/null
+++ b/src/components/DocumentationView/PwaProTipsCard.tsx
@@ -0,0 +1,28 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Lightbulb } from '@phosphor-icons/react'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+export function PwaProTipsCard() {
+ return (
+
+
+
+
+ Pro Tips
+
+
+
+
+ {pwaData.proTips.map((tip) => (
+
+ •
+
+ {tip.title}: {tip.description}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaSettingsCard.tsx b/src/components/DocumentationView/PwaSettingsCard.tsx
new file mode 100644
index 0000000..5b10c6b
--- /dev/null
+++ b/src/components/DocumentationView/PwaSettingsCard.tsx
@@ -0,0 +1,29 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Separator } from '@/components/ui/separator'
+import pwaData from '@/data/documentation/pwa-data.json'
+
+export function PwaSettingsCard() {
+ return (
+
+
PWA Settings
+
+ Navigate to the PWA tab to manage all Progressive Web App features:
+
+
+
+
+ Available Controls
+
+
+ {pwaData.settings.map((setting, index) => (
+
+
{setting.title}
+
{setting.description}
+ {index < pwaData.settings.length - 1 &&
}
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/PwaTab.tsx b/src/components/DocumentationView/PwaTab.tsx
new file mode 100644
index 0000000..0ce98c8
--- /dev/null
+++ b/src/components/DocumentationView/PwaTab.tsx
@@ -0,0 +1,19 @@
+import { PwaFeaturesCard } from './PwaFeaturesCard'
+import { PwaInstallationSection } from './PwaInstallationSection'
+import { PwaOfflineSection } from './PwaOfflineSection'
+import { PwaOverviewSection } from './PwaOverviewSection'
+import { PwaProTipsCard } from './PwaProTipsCard'
+import { PwaSettingsCard } from './PwaSettingsCard'
+
+export function PwaTab() {
+ return (
+
+ )
+}
diff --git a/src/components/DocumentationView/RoadmapTab.tsx b/src/components/DocumentationView/RoadmapTab.tsx
new file mode 100644
index 0000000..9e55773
--- /dev/null
+++ b/src/components/DocumentationView/RoadmapTab.tsx
@@ -0,0 +1,57 @@
+import { Separator } from '@/components/ui/separator'
+import { CheckCircle, Clock, MapPin } from '@phosphor-icons/react'
+import roadmapData from '@/data/documentation/roadmap-data.json'
+import { RoadmapItem } from './RoadmapItem'
+
+const sections = [
+ {
+ key: 'completed',
+ title: 'Completed Features',
+ icon:
,
+ items: roadmapData.completed
+ },
+ {
+ key: 'planned',
+ title: 'Planned Features',
+ icon:
,
+ items: roadmapData.planned
+ }
+]
+
+export function RoadmapTab() {
+ return (
+
+
+
+
+ {roadmapData.title}
+
+
{roadmapData.subtitle}
+
+
+
+
+ {sections.map((section) => (
+
+
+ {section.icon}
+
{section.title}
+
+
+ {section.items.map((item) => (
+
+ ))}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassAnimationsCard.tsx b/src/components/DocumentationView/SassAnimationsCard.tsx
new file mode 100644
index 0000000..a83da81
--- /dev/null
+++ b/src/components/DocumentationView/SassAnimationsCard.tsx
@@ -0,0 +1,21 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import sassData from '@/data/documentation/sass-data.json'
+import { AnimationItem } from './SassItems'
+
+export function SassAnimationsCard() {
+ return (
+
+
+ Animation Classes
+ Pre-built animation utilities
+
+
+
+ {sassData.animations.map((animation) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassBestPracticesCard.tsx b/src/components/DocumentationView/SassBestPracticesCard.tsx
new file mode 100644
index 0000000..23c27e2
--- /dev/null
+++ b/src/components/DocumentationView/SassBestPracticesCard.tsx
@@ -0,0 +1,26 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { CheckCircle, Target } from '@phosphor-icons/react'
+import sassData from '@/data/documentation/sass-data.json'
+
+export function SassBestPracticesCard() {
+ return (
+
+
+
+
+ Best Practices
+
+
+
+
+ {sassData.bestPractices.map((practice) => (
+
+
+ {practice}
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassComponentsCard.tsx b/src/components/DocumentationView/SassComponentsCard.tsx
new file mode 100644
index 0000000..57203f0
--- /dev/null
+++ b/src/components/DocumentationView/SassComponentsCard.tsx
@@ -0,0 +1,26 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import sassData from '@/data/documentation/sass-data.json'
+import { SassComponentItem } from './SassItems'
+
+export function SassComponentsCard() {
+ return (
+
+
+ Available Components
+ Custom Material UI components built with Sass
+
+
+
+ {sassData.components.map((component) => (
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassFileStructureCard.tsx b/src/components/DocumentationView/SassFileStructureCard.tsx
new file mode 100644
index 0000000..bd82bb7
--- /dev/null
+++ b/src/components/DocumentationView/SassFileStructureCard.tsx
@@ -0,0 +1,20 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import sassData from '@/data/documentation/sass-data.json'
+
+export function SassFileStructureCard() {
+ return (
+
+
+ File Structure
+
+
+ {sassData.fileStructure.map((item) => (
+
+
{item.file}
+
{item.description}
+
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassItems.tsx b/src/components/DocumentationView/SassItems.tsx
new file mode 100644
index 0000000..7da099a
--- /dev/null
+++ b/src/components/DocumentationView/SassItems.tsx
@@ -0,0 +1,22 @@
+export function SassComponentItem({ name, classes, description }: { name: string; classes: string[]; description: string }) {
+ return (
+
+
{name}
+
{description}
+
+ {classes.map((cls) => (
+ {cls}
+ ))}
+
+
+ )
+}
+
+export function AnimationItem({ name, description }: { name: string; description: string }) {
+ return (
+
+
{name}
+
{description}
+
+ )
+}
diff --git a/src/components/DocumentationView/SassLayoutCard.tsx b/src/components/DocumentationView/SassLayoutCard.tsx
new file mode 100644
index 0000000..8ab38aa
--- /dev/null
+++ b/src/components/DocumentationView/SassLayoutCard.tsx
@@ -0,0 +1,25 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { Code } from '@phosphor-icons/react'
+import sassData from '@/data/documentation/sass-data.json'
+import { FeatureItem } from './FeatureItems'
+
+export function SassLayoutCard() {
+ return (
+
+
+ Layout Components
+ Sass-powered layout utilities
+
+
+ {sassData.layoutComponents.map((item) => (
+ }
+ title={item.title}
+ description={item.description}
+ />
+ ))}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassOverviewSection.tsx b/src/components/DocumentationView/SassOverviewSection.tsx
new file mode 100644
index 0000000..b2627b8
--- /dev/null
+++ b/src/components/DocumentationView/SassOverviewSection.tsx
@@ -0,0 +1,26 @@
+import { Separator } from '@/components/ui/separator'
+import { PaintBrush } from '@phosphor-icons/react'
+import sassData from '@/data/documentation/sass-data.json'
+
+export function SassOverviewSection() {
+ return (
+
+
+
+
+
{sassData.title}
+
{sassData.subtitle}
+
+
+
+
+
+
+
Overview
+
{sassData.overview}
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassQuickStartCard.tsx b/src/components/DocumentationView/SassQuickStartCard.tsx
new file mode 100644
index 0000000..4cd8494
--- /dev/null
+++ b/src/components/DocumentationView/SassQuickStartCard.tsx
@@ -0,0 +1,30 @@
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Separator } from '@/components/ui/separator'
+import { Rocket } from '@phosphor-icons/react'
+import sassData from '@/data/documentation/sass-data.json'
+
+export function SassQuickStartCard() {
+ return (
+
+
+
+
+ Quick Start Example
+
+
+
+
+
{sassData.quickStart.components.title}
+
{sassData.quickStart.components.code}
+
+
+
+
+
+
{sassData.quickStart.mixins.title}
+
{sassData.quickStart.mixins.code}
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassTab.tsx b/src/components/DocumentationView/SassTab.tsx
new file mode 100644
index 0000000..5f0210b
--- /dev/null
+++ b/src/components/DocumentationView/SassTab.tsx
@@ -0,0 +1,23 @@
+import { SassAnimationsCard } from './SassAnimationsCard'
+import { SassBestPracticesCard } from './SassBestPracticesCard'
+import { SassComponentsCard } from './SassComponentsCard'
+import { SassFileStructureCard } from './SassFileStructureCard'
+import { SassLayoutCard } from './SassLayoutCard'
+import { SassOverviewSection } from './SassOverviewSection'
+import { SassQuickStartCard } from './SassQuickStartCard'
+import { SassUtilitiesCard } from './SassUtilitiesCard'
+
+export function SassTab() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/components/DocumentationView/SassUtilitiesCard.tsx b/src/components/DocumentationView/SassUtilitiesCard.tsx
new file mode 100644
index 0000000..ddf8199
--- /dev/null
+++ b/src/components/DocumentationView/SassUtilitiesCard.tsx
@@ -0,0 +1,33 @@
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
+import { Separator } from '@/components/ui/separator'
+import { Lightbulb } from '@phosphor-icons/react'
+import sassData from '@/data/documentation/sass-data.json'
+
+export function SassUtilitiesCard() {
+ return (
+
+
+ Sass Utilities & Mixins
+ Reusable functions for custom styling
+
+
+
+ {sassData.utilities.map((utility, index) => (
+
+
+
+ {utility.title}
+
+
+
{utility.mixin}
+
{utility.description}
+
{utility.snippet}
+
+ {index < sassData.utilities.length - 1 &&
}
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/components/FaviconDesigner/constants.ts b/src/components/FaviconDesigner/constants.ts
index 70c6c78..ac1fed6 100644
--- a/src/components/FaviconDesigner/constants.ts
+++ b/src/components/FaviconDesigner/constants.ts
@@ -8,41 +8,41 @@ import {
TextT,
Image as ImageIcon,
} from '@phosphor-icons/react'
-import { FaviconDesign } from './types'
+import presets from '../../data/favicon-designer-presets.json'
+import { FaviconDesign, FaviconElement } from './types'
-export const PRESET_SIZES = [16, 32, 48, 64, 128, 256, 512]
+type ElementTypePreset = {
+ value: FaviconElement['type']
+ label: string
+}
-export const ELEMENT_TYPES = [
- { value: 'circle', label: 'Circle', icon: CircleNotch },
- { value: 'square', label: 'Square', icon: Square },
- { value: 'triangle', label: 'Triangle', icon: Triangle },
- { value: 'star', label: 'Star', icon: Star },
- { value: 'heart', label: 'Heart', icon: Heart },
- { value: 'polygon', label: 'Polygon', icon: Polygon },
- { value: 'text', label: 'Text', icon: TextT },
- { value: 'emoji', label: 'Emoji', icon: ImageIcon },
-]
+type IconComponent = typeof CircleNotch
+
+type ElementTypeValue = ElementTypePreset['value']
+
+const ELEMENT_TYPE_ICONS: Record
= {
+ circle: CircleNotch,
+ square: Square,
+ triangle: Triangle,
+ star: Star,
+ heart: Heart,
+ polygon: Polygon,
+ text: TextT,
+ emoji: ImageIcon,
+}
+
+const elementTypePresets = presets.elementTypes as ElementTypePreset[]
+const defaultDesignPreset = presets.defaultDesign as FaviconDesign
+
+export const PRESET_SIZES = presets.presetSizes
+
+export const ELEMENT_TYPES = elementTypePresets.map((preset) => ({
+ ...preset,
+ icon: ELEMENT_TYPE_ICONS[preset.value],
+}))
export const DEFAULT_DESIGN: FaviconDesign = {
- id: 'default',
- name: 'My Favicon',
- size: 128,
- backgroundColor: '#7c3aed',
- elements: [
- {
- id: '1',
- type: 'text',
- x: 64,
- y: 64,
- width: 100,
- height: 100,
- color: '#ffffff',
- rotation: 0,
- text: 'CF',
- fontSize: 48,
- fontWeight: 'bold',
- },
- ],
+ ...defaultDesignPreset,
createdAt: Date.now(),
updatedAt: Date.now(),
}
diff --git a/src/components/FeatureIdeaCloud.tsx b/src/components/FeatureIdeaCloud.tsx
index dc07481..5094c67 100644
--- a/src/components/FeatureIdeaCloud.tsx
+++ b/src/components/FeatureIdeaCloud.tsx
@@ -24,8 +24,28 @@ import { ScrollArea } from '@/components/ui/scroll-area'
import { Plus, Trash, Sparkle, Package } from '@phosphor-icons/react'
import { toast } from 'sonner'
import { FeatureIdea, IdeaGroup, IdeaEdgeData } from './FeatureIdeaCloud/types'
-import { SEED_IDEAS, CATEGORIES, PRIORITIES, STATUSES, CONNECTION_STYLE, GROUP_COLORS } from './FeatureIdeaCloud/constants'
+import { CONNECTION_STYLE } from './FeatureIdeaCloud/constants'
+import seedIdeasData from './FeatureIdeaCloud/data/seed-ideas.json'
+import categoriesData from './FeatureIdeaCloud/data/categories.json'
+import prioritiesData from './FeatureIdeaCloud/data/priorities.json'
+import statusesData from './FeatureIdeaCloud/data/statuses.json'
+import groupColorsData from './FeatureIdeaCloud/data/group-colors.json'
import { nodeTypes } from './FeatureIdeaCloud/nodes'
+import { dispatchConnectionCountUpdate } from './FeatureIdeaCloud/dispatchConnectionCountUpdate'
+
+type SeedIdeaJson = Omit & { createdAtOffsetMs: number }
+
+const SEED_IDEAS: FeatureIdea[] = (seedIdeasData as SeedIdeaJson[]).map((idea) => {
+ const { createdAtOffsetMs, ...rest } = idea
+ return {
+ ...rest,
+ createdAt: Date.now() - createdAtOffsetMs,
+ }
+})
+const CATEGORIES = categoriesData as string[]
+const PRIORITIES = prioritiesData as FeatureIdea['priority'][]
+const STATUSES = statusesData as FeatureIdea['status'][]
+const GROUP_COLORS = groupColorsData as Array<{ name: string; value: string; bg: string; border: string }>
export function FeatureIdeaCloud() {
const [ideas, setIdeas] = useKV('feature-ideas', SEED_IDEAS)
@@ -114,10 +134,7 @@ export function FeatureIdeaCloud() {
bottom: connections.bottom.size,
}
- const event = new CustomEvent('updateConnectionCounts', {
- detail: { nodeId, counts }
- })
- window.dispatchEvent(event)
+ dispatchConnectionCountUpdate(nodeId, counts)
})
}, [])
diff --git a/src/components/FeatureIdeaCloud/GroupNode.tsx b/src/components/FeatureIdeaCloud/GroupNode.tsx
new file mode 100644
index 0000000..61a1968
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/GroupNode.tsx
@@ -0,0 +1,44 @@
+import { NodeProps } from 'reactflow'
+import { Button } from '@/components/ui/button'
+import { DotsThree } from '@phosphor-icons/react'
+import { IdeaGroup } from './types'
+import { GROUP_COLORS } from './constants'
+import { dispatchEditGroup } from './dispatchEditGroup'
+
+export function GroupNode({ data, selected }: NodeProps) {
+ const colorScheme = GROUP_COLORS.find(c => c.value === data.color) || GROUP_COLORS[0]
+
+ return (
+
+
+ {data.label}
+
+
{
+ e.stopPropagation()
+ dispatchEditGroup(data)
+ }}
+ >
+
+
+
+ )
+}
diff --git a/src/components/FeatureIdeaCloud/IdeaNode.tsx b/src/components/FeatureIdeaCloud/IdeaNode.tsx
new file mode 100644
index 0000000..1b1ed52
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/IdeaNode.tsx
@@ -0,0 +1,72 @@
+import { useState, useEffect } from 'react'
+import { NodeProps, Position } from 'reactflow'
+import { Button } from '@/components/ui/button'
+import { Card } from '@/components/ui/card'
+import { Badge } from '@/components/ui/badge'
+import { DotsThree } from '@phosphor-icons/react'
+import { FeatureIdea } from './types'
+import { PRIORITY_COLORS, STATUS_COLORS } from './constants'
+import { generateHandles } from './generateHandles'
+import { dispatchEditIdea } from './dispatchEditIdea'
+
+export function IdeaNode({ data, selected, id }: NodeProps & { id: string }) {
+ const [connectionCounts, setConnectionCounts] = useState>({
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ })
+
+ useEffect(() => {
+ const updateConnectionCounts = (event: CustomEvent) => {
+ const { nodeId, counts } = event.detail
+ if (nodeId === id) {
+ setConnectionCounts(counts)
+ }
+ }
+
+ window.addEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener)
+ return () => {
+ window.removeEventListener('updateConnectionCounts' as any, updateConnectionCounts as EventListener)
+ }
+ }, [id])
+
+ return (
+
+ {generateHandles({ position: Position.Left, type: 'target', side: 'left', count: connectionCounts.left })}
+ {generateHandles({ position: Position.Right, type: 'source', side: 'right', count: connectionCounts.right })}
+ {generateHandles({ position: Position.Top, type: 'target', side: 'top', count: connectionCounts.top })}
+ {generateHandles({ position: Position.Bottom, type: 'source', side: 'bottom', count: connectionCounts.bottom })}
+
+
+
+
+
{data.title}
+ {
+ e.stopPropagation()
+ dispatchEditIdea(data)
+ }}
+ >
+
+
+
+
+ {data.description}
+
+
+
+ {data.category}
+
+
+ {data.status}
+
+
+
+
+
+ )
+}
diff --git a/src/components/FeatureIdeaCloud/constants.ts b/src/components/FeatureIdeaCloud/constants.ts
index ac25c07..08cc2fd 100644
--- a/src/components/FeatureIdeaCloud/constants.ts
+++ b/src/components/FeatureIdeaCloud/constants.ts
@@ -1,124 +1,8 @@
-import { FeatureIdea } from './types'
-
-export const SEED_IDEAS: FeatureIdea[] = [
- {
- id: 'idea-1',
- title: 'AI Code Assistant',
- description: 'Integrate an AI assistant that can suggest code improvements and answer questions',
- category: 'AI/ML',
- priority: 'high',
- status: 'completed',
- createdAt: Date.now() - 10000000,
- },
- {
- id: 'idea-2',
- title: 'Real-time Collaboration',
- description: 'Allow multiple developers to work on the same project simultaneously',
- category: 'Collaboration',
- priority: 'high',
- status: 'idea',
- createdAt: Date.now() - 9000000,
- },
- {
- id: 'idea-3',
- title: 'Component Marketplace',
- description: 'A marketplace where users can share and download pre-built components',
- category: 'Community',
- priority: 'medium',
- status: 'idea',
- createdAt: Date.now() - 8000000,
- },
- {
- id: 'idea-4',
- title: 'Visual Git Integration',
- description: 'Git operations through a visual interface with branch visualization',
- category: 'DevOps',
- priority: 'high',
- status: 'planned',
- createdAt: Date.now() - 7000000,
- },
- {
- id: 'idea-5',
- title: 'API Mock Server',
- description: 'Built-in mock server for testing API integrations',
- category: 'Testing',
- priority: 'medium',
- status: 'idea',
- createdAt: Date.now() - 6000000,
- },
- {
- id: 'idea-6',
- title: 'Performance Profiler',
- description: 'Analyze and optimize application performance with visual metrics',
- category: 'Performance',
- priority: 'medium',
- status: 'idea',
- createdAt: Date.now() - 5000000,
- },
- {
- id: 'idea-7',
- title: 'Theme Presets',
- description: 'Pre-designed theme templates for quick project setup',
- category: 'Design',
- priority: 'low',
- status: 'completed',
- createdAt: Date.now() - 4000000,
- },
- {
- id: 'idea-8',
- title: 'Database Schema Migrations',
- description: 'Visual tool for creating and managing database migrations',
- category: 'Database',
- priority: 'high',
- status: 'in-progress',
- createdAt: Date.now() - 3000000,
- },
- {
- id: 'idea-9',
- title: 'Mobile App Preview',
- description: 'Live preview on actual mobile devices or simulators',
- category: 'Mobile',
- priority: 'medium',
- status: 'planned',
- createdAt: Date.now() - 2000000,
- },
- {
- id: 'idea-10',
- title: 'Accessibility Checker',
- description: 'Automated accessibility testing and suggestions',
- category: 'Accessibility',
- priority: 'high',
- status: 'idea',
- createdAt: Date.now() - 1000000,
- },
-]
-
export const CONNECTION_STYLE = {
stroke: '#a78bfa',
strokeWidth: 2.5
}
-export const CATEGORIES = [
- 'AI/ML',
- 'Collaboration',
- 'Community',
- 'DevOps',
- 'Testing',
- 'Performance',
- 'Design',
- 'Database',
- 'Mobile',
- 'Accessibility',
- 'Productivity',
- 'Security',
- 'Analytics',
- 'Other'
-]
-
-export const PRIORITIES = ['low', 'medium', 'high'] as const
-
-export const STATUSES = ['idea', 'planned', 'in-progress', 'completed'] as const
-
export const STATUS_COLORS = {
idea: 'bg-muted text-muted-foreground',
planned: 'bg-accent text-accent-foreground',
@@ -131,14 +15,3 @@ export const PRIORITY_COLORS = {
medium: 'border-amber-400/60 bg-amber-50/80 dark:bg-amber-950/40',
high: 'border-red-400/60 bg-red-50/80 dark:bg-red-950/40',
}
-
-export const GROUP_COLORS = [
- { name: 'Blue', value: '#3b82f6', bg: 'rgba(59, 130, 246, 0.08)', border: 'rgba(59, 130, 246, 0.3)' },
- { name: 'Purple', value: '#a855f7', bg: 'rgba(168, 85, 247, 0.08)', border: 'rgba(168, 85, 247, 0.3)' },
- { name: 'Green', value: '#10b981', bg: 'rgba(16, 185, 129, 0.08)', border: 'rgba(16, 185, 129, 0.3)' },
- { name: 'Red', value: '#ef4444', bg: 'rgba(239, 68, 68, 0.08)', border: 'rgba(239, 68, 68, 0.3)' },
- { name: 'Orange', value: '#f97316', bg: 'rgba(249, 115, 22, 0.08)', border: 'rgba(249, 115, 22, 0.3)' },
- { name: 'Pink', value: '#ec4899', bg: 'rgba(236, 72, 153, 0.08)', border: 'rgba(236, 72, 153, 0.3)' },
- { name: 'Cyan', value: '#06b6d4', bg: 'rgba(6, 182, 212, 0.08)', border: 'rgba(6, 182, 212, 0.3)' },
- { name: 'Amber', value: '#f59e0b', bg: 'rgba(245, 158, 11, 0.08)', border: 'rgba(245, 158, 11, 0.3)' },
-]
diff --git a/src/components/FeatureIdeaCloud/data/categories.json b/src/components/FeatureIdeaCloud/data/categories.json
new file mode 100644
index 0000000..569aa74
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/data/categories.json
@@ -0,0 +1,16 @@
+[
+ "AI/ML",
+ "Collaboration",
+ "Community",
+ "DevOps",
+ "Testing",
+ "Performance",
+ "Design",
+ "Database",
+ "Mobile",
+ "Accessibility",
+ "Productivity",
+ "Security",
+ "Analytics",
+ "Other"
+]
diff --git a/src/components/FeatureIdeaCloud/data/group-colors.json b/src/components/FeatureIdeaCloud/data/group-colors.json
new file mode 100644
index 0000000..4d4a322
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/data/group-colors.json
@@ -0,0 +1,10 @@
+[
+ { "name": "Blue", "value": "#3b82f6", "bg": "rgba(59, 130, 246, 0.08)", "border": "rgba(59, 130, 246, 0.3)" },
+ { "name": "Purple", "value": "#a855f7", "bg": "rgba(168, 85, 247, 0.08)", "border": "rgba(168, 85, 247, 0.3)" },
+ { "name": "Green", "value": "#10b981", "bg": "rgba(16, 185, 129, 0.08)", "border": "rgba(16, 185, 129, 0.3)" },
+ { "name": "Red", "value": "#ef4444", "bg": "rgba(239, 68, 68, 0.08)", "border": "rgba(239, 68, 68, 0.3)" },
+ { "name": "Orange", "value": "#f97316", "bg": "rgba(249, 115, 22, 0.08)", "border": "rgba(249, 115, 22, 0.3)" },
+ { "name": "Pink", "value": "#ec4899", "bg": "rgba(236, 72, 153, 0.08)", "border": "rgba(236, 72, 153, 0.3)" },
+ { "name": "Cyan", "value": "#06b6d4", "bg": "rgba(6, 182, 212, 0.08)", "border": "rgba(6, 182, 212, 0.3)" },
+ { "name": "Amber", "value": "#f59e0b", "bg": "rgba(245, 158, 11, 0.08)", "border": "rgba(245, 158, 11, 0.3)" }
+]
diff --git a/src/components/FeatureIdeaCloud/data/priorities.json b/src/components/FeatureIdeaCloud/data/priorities.json
new file mode 100644
index 0000000..0b1f153
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/data/priorities.json
@@ -0,0 +1,5 @@
+[
+ "low",
+ "medium",
+ "high"
+]
diff --git a/src/components/FeatureIdeaCloud/data/seed-ideas.json b/src/components/FeatureIdeaCloud/data/seed-ideas.json
new file mode 100644
index 0000000..607b2df
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/data/seed-ideas.json
@@ -0,0 +1,92 @@
+[
+ {
+ "id": "idea-1",
+ "title": "AI Code Assistant",
+ "description": "Integrate an AI assistant that can suggest code improvements and answer questions",
+ "category": "AI/ML",
+ "priority": "high",
+ "status": "completed",
+ "createdAtOffsetMs": 10000000
+ },
+ {
+ "id": "idea-2",
+ "title": "Real-time Collaboration",
+ "description": "Allow multiple developers to work on the same project simultaneously",
+ "category": "Collaboration",
+ "priority": "high",
+ "status": "idea",
+ "createdAtOffsetMs": 9000000
+ },
+ {
+ "id": "idea-3",
+ "title": "Component Marketplace",
+ "description": "A marketplace where users can share and download pre-built components",
+ "category": "Community",
+ "priority": "medium",
+ "status": "idea",
+ "createdAtOffsetMs": 8000000
+ },
+ {
+ "id": "idea-4",
+ "title": "Visual Git Integration",
+ "description": "Git operations through a visual interface with branch visualization",
+ "category": "DevOps",
+ "priority": "high",
+ "status": "planned",
+ "createdAtOffsetMs": 7000000
+ },
+ {
+ "id": "idea-5",
+ "title": "API Mock Server",
+ "description": "Built-in mock server for testing API integrations",
+ "category": "Testing",
+ "priority": "medium",
+ "status": "idea",
+ "createdAtOffsetMs": 6000000
+ },
+ {
+ "id": "idea-6",
+ "title": "Performance Profiler",
+ "description": "Analyze and optimize application performance with visual metrics",
+ "category": "Performance",
+ "priority": "medium",
+ "status": "idea",
+ "createdAtOffsetMs": 5000000
+ },
+ {
+ "id": "idea-7",
+ "title": "Theme Presets",
+ "description": "Pre-designed theme templates for quick project setup",
+ "category": "Design",
+ "priority": "low",
+ "status": "completed",
+ "createdAtOffsetMs": 4000000
+ },
+ {
+ "id": "idea-8",
+ "title": "Database Schema Migrations",
+ "description": "Visual tool for creating and managing database migrations",
+ "category": "Database",
+ "priority": "high",
+ "status": "in-progress",
+ "createdAtOffsetMs": 3000000
+ },
+ {
+ "id": "idea-9",
+ "title": "Mobile App Preview",
+ "description": "Live preview on actual mobile devices or simulators",
+ "category": "Mobile",
+ "priority": "medium",
+ "status": "planned",
+ "createdAtOffsetMs": 2000000
+ },
+ {
+ "id": "idea-10",
+ "title": "Accessibility Checker",
+ "description": "Automated accessibility testing and suggestions",
+ "category": "Accessibility",
+ "priority": "high",
+ "status": "idea",
+ "createdAtOffsetMs": 1000000
+ }
+]
diff --git a/src/components/FeatureIdeaCloud/data/statuses.json b/src/components/FeatureIdeaCloud/data/statuses.json
new file mode 100644
index 0000000..dc6b009
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/data/statuses.json
@@ -0,0 +1,6 @@
+[
+ "idea",
+ "planned",
+ "in-progress",
+ "completed"
+]
diff --git a/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts b/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts
new file mode 100644
index 0000000..3d7f85c
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/dispatchConnectionCountUpdate.ts
@@ -0,0 +1,6 @@
+export function dispatchConnectionCountUpdate(nodeId: string, counts: Record) {
+ const event = new CustomEvent('updateConnectionCounts', {
+ detail: { nodeId, counts }
+ })
+ window.dispatchEvent(event)
+}
diff --git a/src/components/FeatureIdeaCloud/dispatchEditGroup.ts b/src/components/FeatureIdeaCloud/dispatchEditGroup.ts
new file mode 100644
index 0000000..3af9800
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/dispatchEditGroup.ts
@@ -0,0 +1,6 @@
+import { IdeaGroup } from './types'
+
+export function dispatchEditGroup(group: IdeaGroup) {
+ const event = new CustomEvent('editGroup', { detail: group })
+ window.dispatchEvent(event)
+}
diff --git a/src/components/FeatureIdeaCloud/dispatchEditIdea.ts b/src/components/FeatureIdeaCloud/dispatchEditIdea.ts
new file mode 100644
index 0000000..2a7bfdd
--- /dev/null
+++ b/src/components/FeatureIdeaCloud/dispatchEditIdea.ts
@@ -0,0 +1,6 @@
+import { FeatureIdea } from './types'
+
+export function dispatchEditIdea(idea: FeatureIdea) {
+ const event = new CustomEvent('editIdea', { detail: idea })
+ window.dispatchEvent(event)
+}
diff --git a/src/components/FeatureIdeaCloud/utils.tsx b/src/components/FeatureIdeaCloud/generateHandles.tsx
similarity index 69%
rename from src/components/FeatureIdeaCloud/utils.tsx
rename to src/components/FeatureIdeaCloud/generateHandles.tsx
index 1a08ee7..01411c6 100644
--- a/src/components/FeatureIdeaCloud/utils.tsx
+++ b/src/components/FeatureIdeaCloud/generateHandles.tsx
@@ -11,7 +11,7 @@ interface GenerateHandlesProps {
export function generateHandles({ position, type, side, count }: GenerateHandlesProps): ReactElement[] {
const totalHandles = Math.max(2, count + 1)
const handles: ReactElement[] = []
-
+
for (let i = 0; i < totalHandles; i++) {
const handleId = `${side}-${i}`
const isVertical = position === Position.Top || position === Position.Bottom
@@ -20,7 +20,7 @@ export function generateHandles({ position, type, side, count }: GenerateHandles
const positionStyle = isVertical
? { left: `${leftPercent}%` }
: { top: `${topPercent}%` }
-
+
const element = (
) {
- const event = new CustomEvent('updateConnectionCounts', {
- detail: { nodeId, counts }
- })
- window.dispatchEvent(event)
-}
-
-export function dispatchEditIdea(idea: any) {
- const event = new CustomEvent('editIdea', { detail: idea })
- window.dispatchEvent(event)
-}
-
-export function dispatchEditGroup(group: any) {
- const event = new CustomEvent('editGroup', { detail: group })
- window.dispatchEvent(event)
-}
diff --git a/src/components/FeatureIdeaCloud/nodes.tsx b/src/components/FeatureIdeaCloud/nodes.tsx
index b1a7b88..7009579 100644
--- a/src/components/FeatureIdeaCloud/nodes.tsx
+++ b/src/components/FeatureIdeaCloud/nodes.tsx
@@ -5,7 +5,10 @@ import { Card } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { DotsThree } from '@phosphor-icons/react'
import { FeatureIdea, IdeaGroup } from './types'
-import { PRIORITY_COLORS, STATUS_COLORS, GROUP_COLORS } from './constants'
+import { PRIORITY_COLORS, STATUS_COLORS } from './constants'
+import groupColorsData from './data/group-colors.json'
+
+const GROUP_COLORS = groupColorsData as Array<{ name: string; value: string; bg: string; border: string }>
export function GroupNode({ data, selected }: NodeProps) {
const colorScheme = GROUP_COLORS.find(c => c.value === data.color) || GROUP_COLORS[0]
diff --git a/src/components/FeatureIdeaCloud/utils.ts b/src/components/FeatureIdeaCloud/utils.ts
deleted file mode 100644
index b096f6a..0000000
--- a/src/components/FeatureIdeaCloud/utils.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-export function dispatchConnectionCountUpdate(nodeId: string, counts: Record) {
- const event = new CustomEvent('updateConnectionCounts', {
- detail: { nodeId, counts }
- })
- window.dispatchEvent(event)
-}
-
-export function dispatchEditIdea(idea: any) {
- const event = new CustomEvent('editIdea', { detail: idea })
- window.dispatchEvent(event)
-}
-
-export function dispatchEditGroup(group: any) {
- const event = new CustomEvent('editGroup', { detail: group })
- window.dispatchEvent(event)
-}
diff --git a/src/components/ProjectSettingsDesigner.tsx b/src/components/ProjectSettingsDesigner.tsx
index f9a4419..404bd78 100644
--- a/src/components/ProjectSettingsDesigner.tsx
+++ b/src/components/ProjectSettingsDesigner.tsx
@@ -1,17 +1,15 @@
-import { useState } from 'react'
-import { NextJsConfig, NpmSettings, NpmPackage } from '@/types/project'
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
-import { Button } from '@/components/ui/button'
-import { Input } from '@/components/ui/input'
-import { Label } from '@/components/ui/label'
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
-import { Switch } from '@/components/ui/switch'
+import { NextJsConfig, NpmSettings } from '@/types/project'
import { ScrollArea } from '@/components/ui/scroll-area'
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
-import { Plus, Trash, Package, Cube, Code } from '@phosphor-icons/react'
-import { Badge } from '@/components/ui/badge'
-import { SeedDataManager } from '@/components/molecules'
+import { Cube } from '@phosphor-icons/react'
+import projectSettingsCopy from '@/data/project-settings.json'
+import { NextJsConfigTab } from '@/components/project-settings/NextJsConfigTab'
+import { PackagesTab } from '@/components/project-settings/PackagesTab'
+import { ScriptsTab } from '@/components/project-settings/ScriptsTab'
+import { DataTab } from '@/components/project-settings/DataTab'
+import { PackageDialog } from '@/components/project-settings/PackageDialog'
+import { ScriptDialog } from '@/components/project-settings/ScriptDialog'
+import { useProjectSettingsActions } from '@/components/project-settings/useProjectSettingsActions'
interface ProjectSettingsDesignerProps {
nextjsConfig: NextJsConfig
@@ -26,92 +24,27 @@ export function ProjectSettingsDesigner({
onNextjsConfigChange,
onNpmSettingsChange,
}: ProjectSettingsDesignerProps) {
- const [packageDialogOpen, setPackageDialogOpen] = useState(false)
- const [editingPackage, setEditingPackage] = useState(null)
- const [scriptDialogOpen, setScriptDialogOpen] = useState(false)
- const [scriptKey, setScriptKey] = useState('')
- const [scriptValue, setScriptValue] = useState('')
- const [editingScriptKey, setEditingScriptKey] = useState(null)
-
- const handleAddPackage = () => {
- setEditingPackage({
- id: `package-${Date.now()}`,
- name: '',
- version: 'latest',
- isDev: false,
- })
- setPackageDialogOpen(true)
- }
-
- const handleEditPackage = (pkg: NpmPackage) => {
- setEditingPackage({ ...pkg })
- setPackageDialogOpen(true)
- }
-
- const handleSavePackage = () => {
- if (!editingPackage || !editingPackage.name) return
-
- onNpmSettingsChange((current) => {
- const existingIndex = current.packages.findIndex((p) => p.id === editingPackage.id)
- if (existingIndex >= 0) {
- const updated = [...current.packages]
- updated[existingIndex] = editingPackage
- return { ...current, packages: updated }
- } else {
- return { ...current, packages: [...current.packages, editingPackage] }
- }
- })
-
- setPackageDialogOpen(false)
- setEditingPackage(null)
- }
-
- const handleDeletePackage = (packageId: string) => {
- onNpmSettingsChange((current) => ({
- ...current,
- packages: current.packages.filter((p) => p.id !== packageId),
- }))
- }
-
- const handleAddScript = () => {
- setScriptKey('')
- setScriptValue('')
- setEditingScriptKey(null)
- setScriptDialogOpen(true)
- }
-
- const handleEditScript = (key: string, value: string) => {
- setScriptKey(key)
- setScriptValue(value)
- setEditingScriptKey(key)
- setScriptDialogOpen(true)
- }
-
- const handleSaveScript = () => {
- if (!scriptKey || !scriptValue) return
-
- onNpmSettingsChange((current) => {
- const scripts = { ...current.scripts }
- if (editingScriptKey && editingScriptKey !== scriptKey) {
- delete scripts[editingScriptKey]
- }
- scripts[scriptKey] = scriptValue
- return { ...current, scripts }
- })
-
- setScriptDialogOpen(false)
- setScriptKey('')
- setScriptValue('')
- setEditingScriptKey(null)
- }
-
- const handleDeleteScript = (key: string) => {
- onNpmSettingsChange((current) => {
- const scripts = { ...current.scripts }
- delete scripts[key]
- return { ...current, scripts }
- })
- }
+ const {
+ packageDialogOpen,
+ setPackageDialogOpen,
+ editingPackage,
+ setEditingPackage,
+ scriptDialogOpen,
+ setScriptDialogOpen,
+ scriptKey,
+ setScriptKey,
+ scriptValue,
+ setScriptValue,
+ editingScriptKey,
+ handleAddPackage,
+ handleEditPackage,
+ handleSavePackage,
+ handleDeletePackage,
+ handleAddScript,
+ handleEditScript,
+ handleSaveScript,
+ handleDeleteScript,
+ } = useProjectSettingsActions({ onNpmSettingsChange })
return (
@@ -121,9 +54,9 @@ export function ProjectSettingsDesigner({
-
Project Settings
+
{projectSettingsCopy.header.title}
- Configure Next.js and npm settings
+ {projectSettingsCopy.header.description}