DevStackBoxGitHub ↗

Components

React component inventory for contributors.

DevStackBox - Component Inventory

Single Source of Truth for all React components.
Before writing a new component, check this file to see if one already exists that can be reused or extended.

Primary rule: If the UI, action, or layout is similar to an existing component, extend the existing component with props, slots, or children before creating a sibling component.

Reuse Workflow

  1. Check the Quick Lookup table for an existing match.
  2. If the behavior is similar, extend the existing component instead of copying its JSX or logic.
  3. If the logic is shared across services, move it into the shared component or a shared helper.
  4. If you must create something new, make it generic enough for the next similar use case and document it here immediately.

Reuse Priorities

  • Service presentation: reuse ServiceCard, StatusBadge, ServiceActions, and LogViewer.
  • Shared dialogs and modal flows: reuse ConfigEditor, PHPVersionSelector, and shadcn Dialog primitives.
  • Navigation and app shell: reuse Sidebar, CommandPalette, ThemeToggle, LanguageSwitcher, and AutoUpdater.
  • Shared service logic: reuse ServiceManager, safeInvoke(), TAURI_COMMANDS, and types in src/types/services.ts.

Quick Lookup

ComponentFilePurposeReusable?
ThemeProvidercomponents/theme-provider.tsxWraps entire app with dark/light contextNo (app-level)
ThemeTogglecomponents/theme-toggle.tsxDark/Light mode buttonYes
LanguageSwitchercomponents/language-switcher.tsxEN/HI dropdownYes
Sidebarcomponents/sidebar.tsxLeft navigation railNo (app-level)
CommandPalettecomponents/command-palette.tsxCtrl+P search/action paletteNo (app-level)
ConfigEditorcomponents/config-editor.tsxModal for editing config filesYes (pass service prop)
AutoUpdatercomponents/auto-updater.tsxUpdate check + install UINo (app-level)
PHPVersionSelectorcomponents/php-version-selector.tsxPHP version picker modalNo (service-specific)
DebugPanelcomponents/DebugPanel.tsxDev-only debug info panelNo (dev only)
WindowControlscomponents/WindowControls.tsxCustom title bar buttonsNo (app-level)
ServiceManagercomponents/services/service-manager.tsxPolls + manages all servicesNo (orchestrator)
ServiceCardcomponents/services/service-card.tsxSingle service display cardYes
ServiceActionscomponents/services/service-actions.tsxStart/Stop/Open buttonsYes
StatusBadgecomponents/services/status-badge.tsxRunning/Stopped badgeYes
LogViewercomponents/services/log-viewer.tsxScrollable log outputYes
MySQLServicecomponents/services/mysql-service.tsxMySQL-specific service UINo
ApacheServicecomponents/services/apache-service.tsxApache-specific service UINo
PHPServicecomponents/services/php-service.tsxPHP-specific service UINo

Pages

Page ComponentFileRouteStatus
DashboardPagepages/dashboard.tsx/Working
ServicesPagepages/services.tsx/servicesWorking
LogsLayoutpages/logs/layout.tsx/logs/*Working
SettingsPagepages/settings/index.tsx/settingsWorking
BackupPagepages/settings/backup.tsx/settings/backupWorking
AboutPagepages/about.tsx/aboutWorking
SecurityPagepages/security.tsx/securityWorking
TerminalLayoutpages/terminal/layout.tsx/terminal/*Working

Detailed Component Docs

App.tsx (Root)

File: src/App.tsx
Purpose: Top-level application shell. Hosts HashRouter, app chrome, keyboard shortcuts, and shared modal state.
State managed here:

  • sidebarCollapsed - sidebar collapsed state
  • commandPaletteOpen - Ctrl+P modal open
  • currentPhpVersion - active PHP version badge state

Do NOT add feature logic to App.tsx. It should only handle layout and routing.


ThemeProvider

File: src/components/theme-provider.tsx
Purpose: Wraps the entire app and provides dark/light theme context.
Usage: Already wraps everything in App.tsx. Do not move or duplicate.
Pattern: Uses shadcn/ui's theme system. Class dark on <html> element.


ThemeToggle

File: src/components/theme-toggle.tsx
Purpose: Button to switch between dark and light mode.
Props: None
Usage: <ThemeToggle />
Reuse: Can be placed anywhere in the top bar.


LanguageSwitcher

File: src/components/language-switcher.tsx
Purpose: Dropdown to switch between English and Hindi (i18next).
Props: None
Usage: <LanguageSwitcher />
Translation keys used: common.english, common.hindi


File: src/components/sidebar.tsx
Purpose: Main navigation sidebar with page links and collapse toggle.
Props:

interface SidebarProps {
  collapsed: boolean;
  onToggleCollapse: () => void;
}

Pages registered: comes from SIDEBAR_ROUTES in src/lib/routes.ts.
Rule: Add new top-level pages through src/lib/routes.ts and App.tsx routes together.


CommandPalette

File: src/components/command-palette.tsx
Purpose: Ctrl+P / Cmd+P quick-action palette using shadcn/ui Command.
Props:

interface CommandPaletteProps {
  isOpen: boolean;
  onClose: () => void;
  onPageChange: (page: string) => void;
  onServiceToggle: (service: string) => void;
}

Trigger: Keyboard shortcut in App.tsx.


ConfigEditor

File: src/components/config-editor.tsx
Purpose: Modal dialog for reading/editing/backing up config files.
Props:

interface ConfigEditorProps {
  isOpen: boolean;
  onClose: () => void;
  service: ServiceName; // "mysql" | "apache" | "php" | "phpmyadmin"
}

Tauri commands used: read_config, update_config, backup_config
Reuse: Yes. Pass a different service prop to edit any supported service config.
Extension rule: Add validation, syntax helpers, or backup history to this component instead of building separate config dialogs per service.


AutoUpdater

File: src/components/auto-updater.tsx
Purpose: Checks GitHub Releases for app updates and shows install prompt.
Status: Partially working. Tauri updater plugin is configured but not fully tested.
Tauri plugin used: @tauri-apps/plugin-updater


PHPVersionSelector

File: src/components/php-version-selector.tsx
Purpose: Modal to view installed PHP versions and switch/download versions.
Props:

interface PHPVersionSelectorProps {
  isOpen: boolean;
  onClose: () => void;
  currentVersion: string;
  onVersionChange: (version: string) => void;
}

Status: Currently a frontend-managed selector with simulated downloads and local version switching state.
Extension rule: Keep version-card layout centralized here. Do not create separate selectors elsewhere.


ServiceManager (Orchestrator - Do Not Duplicate Its Logic)

File: src/components/services/service-manager.tsx
Purpose: Central component that polls service status every 5 seconds and exposes start/stop handlers to children.
Props:

interface ServiceManagerProps {
  compact?: boolean;
  onServiceToggle?: (service: string, status: boolean) => void;
  onOpenConfig?: (service: string) => void;
  onViewLogs?: (service: string) => void;
  onOpenPHPVersionSelector?: () => void;
  currentPhpVersion?: string;
  onStatusesChange?: (statuses: {
    apache: ServiceStatus;
    mysql: ServiceStatus;
    php: ServiceStatus;
  }) => void;
}

Tauri commands used: get_apache_status, get_mysql_status, get_php_status, toggle_mysql, toggle_apache, toggle_php, backup_mysql_database, open_php_terminal
Rule: All service polling logic lives here. Do NOT create another polling loop in any other component. Extension rule: New cross-service actions should be added here or below this layer, not reimplemented in each service card.


ServiceCard

File: src/components/services/service-card.tsx
Purpose: Generic card shell for displaying a service (name, icon, status, actions).
Props:

interface ServiceCardProps {
  name: string;
  icon: ReactNode;
  status: ServiceStatus;
  children?: ReactNode; // Extra content below the header
}

Reuse: Use this for any service. Pass children for service-specific controls.


ServiceActions

File: src/components/services/service-actions.tsx
Purpose: Start / Stop / Open Browser buttons for a service.
Props:

interface ServiceActionsProps {
  service: string;
  status: ServiceStatus;
  onToggle: () => void;
  url?: string; // URL to open in browser on "Open" click
  loading?: boolean;
}

StatusBadge

File: src/components/services/status-badge.tsx
Purpose: Small badge showing "Running" (green) or "Stopped" (gray).
Props:

interface StatusBadgeProps {
  running: boolean;
}

Reuse: Use anywhere a running/stopped status needs to be displayed.


LogViewer

File: src/components/services/log-viewer.tsx
Purpose: Scrollable, auto-scrolling log output area.
Props:

interface LogViewerProps {
  logs: string;
  onClear?: () => void;
  onRefresh?: () => void;
  title?: string;
  description?: string;
  searchable?: boolean;
  autoScroll?: boolean;
  onAutoScrollChange?: (enabled: boolean) => void;
  loading?: boolean;
}

Reuse: Use this for log display, search, copy, download, and clear behavior instead of making per-service log blocks.
Note: Currently renders plain text with manual refresh. Real-time streaming is not implemented yet.


MySQLService / ApacheService / PHPService

Files: components/services/mysql-service.tsx, apache-service.tsx, php-service.tsx
Purpose: Service-specific UI sections combining ServiceCard + StatusBadge + ServiceActions + LogViewer.
Props: Each takes status: ServiceStatus and onToggle: () => void.
Rule: Service-specific UI logic goes here, not in ServiceManager.


shadcn/ui Base Components (src/components/ui/)

These are standard shadcn/ui components. Do NOT modify these files.
If you need a new shadcn component, add it via npx shadcn add <component>.

ComponentFileNotes
Buttonui/button.tsxStandard button with variants
Badgeui/badge.tsxInline status badge
Cardui/card.tsxCard container with header/content
Dialogui/dialog.tsxModal dialogs
DropdownMenuui/dropdown-menu.tsxDropdown menus
Inputui/input.tsxText input
Textareaui/textarea.tsxMulti-line text
Progressui/progress.tsxProgress bar
Toastui/toast.tsxToast notification
Toasterui/toaster.tsxToast container (app-level)
Skeletonui/skeleton.tsxLoading skeleton
EmptyStateui/empty-state.tsxCustom empty state (NOT shadcn - local)

TypeScript Shared Types (src/types/services.ts)

Rule: All shared types live in this one file. Never duplicate a type.

// Current types in src/types/services.ts
export type ServiceName = "mysql" | "apache" | "php" | "phpmyadmin";

export interface ServiceStatus {
  running: boolean;
  pid?: number;
  port?: number;
  version?: string;
}

export interface PHPVersion {
  version: string;
  status: "installed" | "available" | "downloading";
  path: string;
  is_active: boolean;
  installed: boolean;
  download_url: string;
}

Utility Functions (src/lib/)

FunctionFilePurpose
isTauri()lib/tauri.tsReturns true if running in Tauri (not browser)
safeInvoke<T>()lib/tauri.tsCalls a Tauri command safely; returns null in browser mode
getMockServiceStatus()lib/tauri.tsReturns fake status for browser-mode dev
getMockBinariesStatus()lib/tauri.tsReturns fake binary status for browser-mode dev
cn(...classes)lib/utils.tsMerges Tailwind class names (from shadcn)
APP_VERSIONlib/version.tsCurrent version string ("0.1.6")

Component Creation Rules

  1. All styling uses Tailwind CSS classes only. No inline styles, no custom CSS files.
  2. All animations use Framer Motion. No CSS keyframes.
  3. All text that shows to the user goes through useTranslation() from i18next.
  4. All Tauri calls go through safeInvoke() from lib/tauri.ts.
  5. Command names must come from src/lib/commands.ts. Do not hardcode command strings in new components.
  6. Support dark/light mode automatically by using Tailwind dark: variants or shadcn/ui components.
  7. Use shadcn/ui Dialog for modals, DropdownMenu for menus, Tabs for sub-navigation.
  8. Extend existing shared components before creating parallel ones for similar UI.
  9. Mark new components in this file as soon as you create them.
Last updated: July 17, 2026Edit this page