bookwiz.io / components / ResponsiveDemo.tsx
ResponsiveDemo.tsx
Raw
'use client';

import { useState, useEffect } from 'react';
import { 
  FolderIcon,
  PencilIcon,
  SparklesIcon,
} from '@heroicons/react/24/outline';

interface ResponsiveDemoProps {
  activeStep: number;
}

export function ResponsiveDemo({ activeStep }: ResponsiveDemoProps) {
  const [currentView, setCurrentView] = useState<'desktop' | 'mobile'>('desktop');
  
  // Auto-detect mobile and set default view
  useEffect(() => {
    const checkMobile = () => {
      setCurrentView(window.innerWidth < 768 ? 'mobile' : 'desktop');
    };
    
    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);

  const fileStructure = [
    { name: "๐Ÿ“ The Enchanted Chronicles", type: "folder", level: 0, expanded: true },
    { name: "๐Ÿ“ Characters", type: "folder", level: 1, expanded: activeStep >= 0 },
    { name: "๐Ÿ“„ protagonist", type: "file", level: 2, selected: activeStep === 0 },
    { name: "๐Ÿ“„ villain", type: "file", level: 2, selected: false },
    { name: "๐Ÿ“ Chapters", type: "folder", level: 1, expanded: activeStep >= 1 },
    { name: "๐Ÿ“„ 1-awakening", type: "file", level: 2, selected: activeStep === 1 },
    { name: "๐Ÿ“„ 2-discovery", type: "file", level: 2, selected: false },
    { name: "๐Ÿ“ World", type: "folder", level: 1, expanded: activeStep >= 2 },
    { name: "๐Ÿ“„ magic", type: "file", level: 2, selected: activeStep === 2 },
    { name: "๐Ÿ“„ locations", type: "file", level: 2, selected: false },
  ];

  const editorContent: { [key: number]: { title: string; content: string[] } } = {
    0: { // protagonist
      title: "protagonist",
      content: [
        "# Elara Nightwhisper",
        "",
        "**Age:** 17",
        "**Occupation:** Apprentice Mage",
        "",
        "## Background",
        "Born in the village of Moonhaven, Elara discovered her",
        "magical abilities when she accidentally made flowers bloom",
        "in the middle of winter...",
        "",
        "## Abilities",
        "- Nature magic (specializing in plant growth)",
        "- Enhanced intuition",
        "- Can communicate with forest spirits"
      ]
    },
    1: { // ch01-awakening
      title: "ch01-awakening",
      content: [
        "# Chapter 1: The Awakening",
        "",
        "The morning mist clung to the cobblestones of Moonhaven",
        "like ghostly fingers, reluctant to let go of the night.",
        "Elara stepped carefully through the empty market square,",
        "her worn leather boots making soft whispers against",
        "the ancient stones.",
        "",
        "She had been having the dreams again. Dreams of a voice",
        "calling to her from the Whispering Woods, speaking words",
        "in a language she didn't recognize but somehow understood."
      ]
    },
    2: { // magic-system
      title: "magic-system",
      content: [
        "# Magic System: The Weave",
        "",
        "## Core Principles",
        "Magic in this world flows through 'The Weave' - an",
        "invisible network of energy that connects all living things.",
        "",
        "## Schools of Magic",
        "- **Elemental:** Fire, Water, Earth, Air",
        "- **Nature:** Plants, Animals, Weather",
        "- **Spirit:** Communication with otherworldly beings",
        "- **Mind:** Telepathy, illusions, memory manipulation"
      ]
    }
  };

  const chatMessages: { [key: number]: Array<{ type: string; content: string }> } = {
    0: [
      { type: "user", content: "I want to develop Elara's backstory more. Can you help?" },
      { type: "ai", content: "I'd love to help! I can see you're working on @protagonist. What specific aspects of her backstory would you like to explore? Her family history, the discovery of her powers, or her life in Moonhaven?\n\nI can also make edits directly to the file if you'd like me to expand any section." }
    ],
    1: [
      { type: "user", content: "@1-awakening feels a bit slow. Can you improve the opening?" },
      { type: "ai", content: "Looking at your opening chapter, I can help make it more engaging! Here's what I suggest:\n\nโ€ข Start with action or dialogue\nโ€ข Add more sensory details about the mist\nโ€ข Hint at the magical element earlier\n\nWould you like me to make these changes directly to the file? I can rewrite the opening paragraph to be more dynamic." }
    ],
    2: [
      { type: "user", content: "How should @magic connect to @protagonist? Can you update both files?" },
      { type: "ai", content: "Great question! Since Elara specializes in Nature magic, I can help connect these elements:\n\nโ€ข Explain how her plant abilities fit into The Weave\nโ€ข Show how her village upbringing connects to nature magic\nโ€ข Create limitations that add tension to your story\n\nI can update both files to weave these connections together. Would you like me to make these changes now?" }
    ]
  };

  // Mobile version with tabbed interface
  const MobileDemo = () => {
    const [activeTab, setActiveTab] = useState<'files' | 'editor' | 'chat'>('editor');
    
    return (
      <div className="relative w-full h-full rounded-2xl overflow-hidden shadow-2xl" style={{ backgroundColor: '#343F56' }}>
        {/* Mystical background effects - reduced for mobile */}
        <div className="absolute inset-0 bg-gradient-to-br from-teal-500/10 via-transparent to-cyan-500/10"></div>
        
        {/* Floating Magical Particles - fewer for mobile */}
        <div className="absolute inset-0 overflow-hidden pointer-events-none">
          {[...Array(6)].map((_, i) => (
            <div
              key={`mote-${i}`}
              className="absolute w-1 h-1 rounded-full animate-pulse"
              style={{ 
                backgroundColor: i % 3 === 0 ? '#0F766E' : i % 3 === 1 ? '#7C3AED' : '#0891B2',
                opacity: 0.6,
                left: `${Math.random() * 100}%`,
                top: `${Math.random() * 100}%`,
                animationDelay: `${Math.random() * 4}s`,
                animationDuration: `${3 + Math.random() * 4}s`,
                filter: 'blur(0.5px)',
                boxShadow: `0 0 4px ${i % 3 === 0 ? '#0F766E' : i % 3 === 1 ? '#7C3AED' : '#0891B2'}`
              }}
            />
          ))}
        </div>

        {/* Mobile Tab Navigation */}
        <div className="absolute top-0 left-0 right-0 z-20 bg-black/20 border-b border-white/10">
          <div className="flex">
            {[
              { id: 'files', label: 'Files', icon: FolderIcon },
              { id: 'editor', label: 'Editor', icon: PencilIcon },
              { id: 'chat', label: 'AI Chat', icon: SparklesIcon }
            ].map((tab) => (
              <button
                key={tab.id}
                onClick={() => setActiveTab(tab.id as 'files' | 'editor' | 'chat')}
                className={`flex-1 flex items-center justify-center py-2 text-xs font-medium transition-colors ${
                  activeTab === tab.id
                    ? 'text-white bg-black/30'
                    : 'text-slate-400 hover:text-slate-200 hover:bg-black/20'
                }`}
              >
                <tab.icon className="w-4 h-4 mr-1" />
                {tab.label}
              </button>
            ))}
          </div>
        </div>

        {/* Mobile Content Area */}
        <div className="absolute inset-0 pt-10">
          {activeTab === 'files' && (
            <div className="h-full p-4 overflow-y-auto">
              {fileStructure.map((item, index) => (
                <div
                  key={index}
                  className={`flex items-center py-1 px-2 rounded ${
                    item.selected ? 'bg-teal-500/20' : 'hover:bg-white/5'
                  }`}
                  style={{ marginLeft: `${item.level * 1}rem` }}
                >
                  <span className="text-slate-300">{item.name}</span>
                </div>
              ))}
            </div>
          )}

          {activeTab === 'editor' && (
            <div className="h-full p-4 overflow-y-auto">
              <div className="text-slate-300 font-mono text-sm">
                {editorContent[activeStep]?.content.map((line, i) => (
                  <div key={i} className="py-0.5">{line}</div>
                ))}
              </div>
            </div>
          )}

          {activeTab === 'chat' && (
            <div className="h-full flex flex-col">
              <div className="flex-1 p-4 overflow-y-auto">
                {chatMessages[activeStep]?.map((msg, i) => (
                  <div
                    key={i}
                    className={`mb-4 ${
                      msg.type === 'user' ? 'text-right' : 'text-left'
                    }`}
                  >
                    <div
                      className={`inline-block p-3 rounded-lg ${
                        msg.type === 'user'
                          ? 'bg-teal-500/20 text-white'
                          : 'bg-slate-700/50 text-slate-200'
                      }`}
                    >
                      {msg.content}
                    </div>
                  </div>
                ))}
              </div>
              <div className="p-4 border-t border-white/10">
                <div className="flex items-center bg-black/20 rounded-lg px-3 py-2">
                  <input
                    type="text"
                    placeholder="Ask AI for help..."
                    className="flex-1 bg-transparent border-none text-sm text-white placeholder-slate-400 focus:outline-none"
                  />
                  <button className="ml-2 p-1 text-slate-400 hover:text-white">
                    <SparklesIcon className="w-5 h-5" />
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    );
  };

  // Desktop version with side-by-side layout
  const DesktopDemo = () => (
    <div className="relative w-full h-full rounded-2xl overflow-hidden shadow-2xl" style={{ backgroundColor: '#343F56' }}>
      {/* Mystical background effects */}
      <div className="absolute inset-0 bg-gradient-to-br from-teal-500/10 via-transparent to-cyan-500/10"></div>
      
      {/* Floating Magical Particles */}
      <div className="absolute inset-0 overflow-hidden pointer-events-none">
        {[...Array(12)].map((_, i) => (
          <div
            key={`mote-${i}`}
            className="absolute w-1 h-1 rounded-full animate-pulse"
            style={{ 
              backgroundColor: i % 3 === 0 ? '#0F766E' : i % 3 === 1 ? '#7C3AED' : '#0891B2',
              opacity: 0.6,
              left: `${Math.random() * 100}%`,
              top: `${Math.random() * 100}%`,
              animationDelay: `${Math.random() * 4}s`,
              animationDuration: `${3 + Math.random() * 4}s`,
              filter: 'blur(0.5px)',
              boxShadow: `0 0 4px ${i % 3 === 0 ? '#0F766E' : i % 3 === 1 ? '#7C3AED' : '#0891B2'}`
            }}
          />
        ))}
      </div>

      {/* File Explorer */}
      <div className="absolute left-0 top-0 bottom-0 w-64 border-r border-white/10 bg-black/20">
        <div className="p-4">
          {fileStructure.map((item, index) => (
            <div
              key={index}
              className={`flex items-center py-1 px-2 rounded ${
                item.selected ? 'bg-teal-500/20' : 'hover:bg-white/5'
              }`}
              style={{ marginLeft: `${item.level * 1}rem` }}
            >
              <span className="text-slate-300">{item.name}</span>
            </div>
          ))}
        </div>
      </div>

      {/* Editor */}
      <div className="absolute left-64 top-0 right-0 bottom-0">
        <div className="h-1/2 border-b border-white/10 p-4 overflow-y-auto">
          <div className="text-slate-300 font-mono text-sm">
            {editorContent[activeStep]?.content.map((line, i) => (
              <div key={i} className="py-0.5">{line}</div>
            ))}
          </div>
        </div>

        {/* Chat */}
        <div className="h-1/2 flex flex-col">
          <div className="flex-1 p-4 overflow-y-auto">
            {chatMessages[activeStep]?.map((msg, i) => (
              <div
                key={i}
                className={`mb-4 ${
                  msg.type === 'user' ? 'text-right' : 'text-left'
                }`}
              >
                <div
                  className={`inline-block p-3 rounded-lg ${
                    msg.type === 'user'
                      ? 'bg-teal-500/20 text-white'
                      : 'bg-slate-700/50 text-slate-200'
                  }`}
                >
                  {msg.content}
                </div>
              </div>
            ))}
          </div>
          <div className="p-4 border-t border-white/10">
            <div className="flex items-center bg-black/20 rounded-lg px-3 py-2">
              <input
                type="text"
                placeholder="Ask AI for help..."
                className="flex-1 bg-transparent border-none text-sm text-white placeholder-slate-400 focus:outline-none"
              />
              <button className="ml-2 p-1 text-slate-400 hover:text-white">
                <SparklesIcon className="w-5 h-5" />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  return currentView === 'mobile' ? <MobileDemo /> : <DesktopDemo />;
}