QRCodeDialog Component

The QRCodeDialog component provides QR code generation and sharing functionality for AI assistants.

Overview

This component generates QR codes for assistant sharing URLs and provides multiple sharing options including copy, download, and native share functionality. It uses a modal dialog interface to display the QR code along with sharing controls.

Location

src/components/QRCodeDialog.tsx

Key Features

QR Code Generation

  • Generates QR codes using the qrcode.react library with QRCodeSVG component
  • Creates shareable URLs in format: {origin}/assistant/{assistantId}
  • Configurable QR code size (200px default) with medium error correction level
  • Includes proper margins and white background for scanning reliability
  • Uses SVG format for crisp rendering at any size

Advanced Download Functionality

  • Converts QR code to high-resolution PNG image with 3x scaling for print quality
  • Dynamically adds white background rectangle to SVG for better visibility
  • Downloads with sanitized filename: {assistantName}_qr_code.png
  • CSP-safe SVG serialization and canvas conversion process
  • Error handling for canvas context and blob creation failures
  • Automatic cleanup of object URLs to prevent memory leaks

Multiple Sharing Options

  • Copy URL: Uses modern Clipboard API with fallback error handling
  • Native Share: Leverages Web Share API when available with title, text, and URL
  • Download Image: High-quality PNG export with toast notifications
  • Visual feedback with icon changes (copy → check mark)
  • Comprehensive error handling with user-friendly toast messages

User Experience Enhancements

  • Responsive modal dialog with proper mobile layout
  • Real-time visual feedback for all actions
  • Keyboard shortcuts (Enter key support)
  • Loading states and error recovery
  • Clear visual hierarchy with assistant name and instructions

Props Interface

interface QRCodeDialogProps {
  isOpen: boolean;
  onOpenChange: (open: boolean) => void;
  assistantId: string;
  assistantName: string;
}

Implementation Examples

Basic Usage

import { QRCodeDialog } from '@/components/QRCodeDialog';

function AssistantCard({ assistant }) {
  const [qrOpen, setQrOpen] = useState(false);
  
  return (
    <>
      <button onClick={() => setQrOpen(true)}>
        Show QR Code
      </button>
      
      <QRCodeDialog
        isOpen={qrOpen}
        onOpenChange={setQrOpen}
        assistantId={assistant.id}
        assistantName={assistant.name}
      />
    </>
  );
}

Advanced Integration with Sharing Menu

function AssistantActions({ assistant }) {
  const [qrDialogOpen, setQrDialogOpen] = useState(false);
  
  const handleShare = () => {
    // Open QR dialog for comprehensive sharing options
    setQrDialogOpen(true);
  };
  
  return (
    <div className="assistant-actions">
      <Button onClick={handleShare} variant="outline">
        <Share2 className="h-4 w-4 mr-2" />
        Share Assistant
      </Button>
      
      <QRCodeDialog
        isOpen={qrDialogOpen}
        onOpenChange={setQrDialogOpen}
        assistantId={assistant.assistantId}
        assistantName={assistant.name}
      />
    </div>
  );
}

Key Implementation Details

Share URL Generation

// Automatically generates share URLs based on current domain
const shareUrl = `${window.location.origin}/assistant/${assistantId}`;

High-Quality Download Process

const handleDownload = () => {
  // Clone SVG and enhance for download
  const svgClone = svg.cloneNode(true) as SVGElement;
  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  rect.setAttribute('fill', 'white');
  svgClone.insertBefore(rect, svgClone.firstChild);

  // Create high-resolution canvas (3x scale)
  const canvas = document.createElement('canvas');
  canvas.width = svgWidth * 3;
  canvas.height = svgHeight * 3;
  
  // Convert to PNG with quality optimization
  canvas.toBlob((blob) => {
    const link = document.createElement('a');
    link.download = `${assistantName.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_qr_code.png`;
    link.href = URL.createObjectURL(blob);
    link.click();
  }, 'image/png', 1.0);
};

Dependencies

  • qrcode.react - QR code generation
  • lucide-react - Icons (Copy, Check, Download, Share2)
  • Custom UI components: Dialog, Button
  • Toast notifications for user feedback

Implementation Details

Security Considerations

  • Uses CSP-safe SVG serialization for image export
  • Sanitizes filenames by replacing special characters with underscores
  • No external API calls - QR generation is client-side

Error Handling

  • Graceful fallback for clipboard API failures
  • Toast notifications for success/error states
  • Handles missing browser share API with automatic fallback

Accessibility

  • Proper dialog semantics with title and description
  • Keyboard navigation support
  • Screen reader friendly button labels

Browser Compatibility

  • QR code generation: All modern browsers
  • Clipboard API: Chrome 66+, Firefox 63+, Safari 13.1+
  • Native Share API: Chrome 89+, Safari 14+, Edge 93+
  • Canvas export: All modern browsers
  • SharingStatus - Displays sharing permissions
  • AssistantLinkPreview - Shows assistant previews
  • Dialog UI components for modal interface