VibeCoderzVibeCoderz
Telegram
All Prompts
NeumorphicTradeDashboard UI Preview

NeumorphicTradeDashboard

NeumorphicTradeDashboard: UI-компонент дашборда для трейдинга в стиле неоморфизм. Позволяет визуализировать рыночные данные.

by Arpan SahaniLive Preview

Prompt

# NeumorphicTradeDashboard

You are given a task to integrate an existing React component in the codebase

~~~/README.md
# Neumorphic Trade Dashboard

A visually stunning trading dashboard variant implementing a "Soft UI" design system.

## Design Philosophy
This component follows strict Neumorphism principles:
- **Monochromatic Palette**: Built on a `#E0E5EC` cool grey base.
- **Physical Depth**: Uses dual shadows (light top-left, dark bottom-right) to create extruded and inset elements.
- **Soft Shapes**: Hyper-rounded corners (32px) for an organic feel.
- **Typography**: Uses "Plus Jakarta Sans" for modern headings and "DM Sans" for clean body text.

## Features
- **Equity Curve**: Large, inset-container chart visualization.
- **Stats Cards**: Extruded cards with clear hierarchy.
- **Journaling**: Deep inset text areas for a tactile writing experience.
- **Responsive**: Mobile-first navigation with smooth transitions.

## Usage
```tsx
import { NeumorphicTradeDashboard } from '@/sd-components/4970efd4-871d-4d1e-a029-aac3f9fa44ec';

function App() {
  return <NeumorphicTradeDashboard />;
}
```
~~~

~~~/src/App.tsx
import React from 'react';
import NeumorphicTradeDashboard from './Component';

export default function App() {
  return <NeumorphicTradeDashboard />;
}
~~~

~~~/package.json
{
  "name": "trading-analytics-dashboard",
  "version": "1.0.0",
  "description": "Dark-themed trading analytics dashboard",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "framer-motion": "^11.0.0",
    "lucide-react": "^0.344.0",
    "clsx": "^2.1.0",
    "tailwind-merge": "^2.2.0",
    "recharts": "^2.12.0",
    "date-fns": "^3.3.0"
  }
}
~~~

~~~/src/Component.tsx
import React, { useState, useEffect } from 'react';
import { 
  LayoutDashboard, 
  BookOpen, 
  TrendingUp, 
  Settings, 
  Bell, 
  Search, 
  Menu, 
  X,
  ChevronRight,
  Plus,
  ArrowUpRight,
  ArrowDownRight,
  Wallet,
  Calendar,
  MoreHorizontal
} from 'lucide-react';
import { motion, AnimatePresence } from 'framer-motion';
import { Area, AreaChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts';

// --- Design System Constants ---
const COLORS = {
  bg: '#E0E5EC',
  text: {
    primary: '#3D4852',
    muted: '#6B7280',
    accent: '#6C63FF',
    success: '#38B2AC',
  },
  shadows: {
    extruded: '9px 9px 16px rgb(163,177,198,0.6), -9px -9px 16px rgba(255,255,255,0.5)',
    extrudedHover: '12px 12px 20px rgb(163,177,198,0.7), -12px -12px 20px rgba(255,255,255,0.6)',
    inset: 'inset 6px 6px 10px rgb(163,177,198,0.6), inset -6px -6px 10px rgba(255,255,255,0.5)',
    insetDeep: 'inset 10px 10px 20px rgb(163,177,198,0.7), inset -10px -10px 20px rgba(255,255,255,0.6)',
    insetSmall: 'inset 3px 3px 6px rgb(163,177,198,0.6), inset -3px -3px 6px rgba(255,255,255,0.5)',
  }
};

// --- Mock Data ---
const equityData = [
  { date: 'Mon', value: 10000 },
  { date: 'Tue', value: 10250 },
  { date: 'Wed', value: 10100 },
  { date: 'Thu', value: 10450 },
  { date: 'Fri', value: 10300 },
  { date: 'Sat', value: 10600 },
  { date: 'Sun', value: 10850 },
];

const recentTrades = [
  { id: 1, pair: 'EUR/USD', type: 'Long', result: 'Win', amount: '+$1,240', date: 'Today, 10:30 AM' },
  { id: 2, pair: 'GBP/JPY', type: 'Short', result: 'Loss', amount: '-$450', date: 'Yesterday, 2:15 PM' },
  { id: 3, pair: 'XAU/USD', type: 'Long', result: 'Win', amount: '+$890', date: 'Yesterday, 9:00 AM' },
];

// --- Reusable Components ---

const NeumorphicCard = ({ children, className = '', onClick }: { children: React.ReactNode, className?: string, onClick?: () => void }) => (
  <motion.div 
    whileHover={{ y: -2, boxShadow: COLORS.shadows.extrudedHover }}
    transition={{ duration: 0.3, ease: "easeOut" }}
    className={`bg-[#E0E5EC] rounded-[32px] p-8 ${className}`}
    style={{ boxShadow: COLORS.shadows.extruded }}
    onClick={onClick}
  >
    {children}
  </motion.div>
);

const NeumorphicButton = ({ children, active = false, className = '', iconOnly = false, onClick }: { children: React.ReactNode, active?: boolean, className?: string, iconOnly?: boolean, onClick?: () => void }) => (
  <motion.button
    whileHover={{ y: -1, boxShadow: COLORS.shadows.extrudedHover }}
    whileTap={{ y: 1, boxShadow: COLORS.shadows.insetSmall }}
    onClick={onClick}
    className={`
      ${iconOnly ? 'p-3 rounded-full' : 'px-6 py-3 rounded-2xl'}
      ${active ? 'text-[#6C63FF]' : 'text-[#6B7280]'}
      flex items-center justify-center font-medium transition-colors duration-300
      ${className}
    `}
    style={{ 
      boxShadow: active ? COLORS.shadows.inset : COLORS.shadows.extruded,
      color: active ? COLORS.text.accent : COLORS.text.muted
    }}
  >
    {children}
  </motion.button>
);

const NeumorphicInput = ({ placeholder, icon: Icon }: { placeholder: string, icon?: any }) => (
  <div className="relative w-full group">
    <input 
      type="text" 
      placeholder={placeholder}
      className="w-full bg-[#E0E5EC] rounded-2xl py-4 pl-12 pr-6 text-[#3D4852] placeholder-[#A0AEC0] outline-none transition-all duration-300 focus:ring-2 focus:ring-[#6C63FF] focus:ring-offset-2 focus:ring-offset-[#E0E5EC]"
      style={{ boxShadow: COLORS.shadows.insetDeep }}
    />
    {Icon && (
      <Icon className="absolute left-4 top-1/2 transform -translate-y-1/2 text-[#A0AEC0] w-5 h-5" />
    )}
  </div>
);

const IconButton = ({ icon: Icon, active = false }: { icon: any, active?: boolean }) => (
  <div 
    className={`
      w-12 h-12 rounded-full flex items-center justify-center
      ${active ? 'text-[#6C63FF]' : 'text-[#6B7280]'}
    `}
    style={{ boxShadow: active ? COLORS.shadows.insetDeep : COLORS.shadows.extruded }}
  >
    <Icon className="w-5 h-5" />
  </div>
);

const StatCard = ({ title, value, change, isPositive }: { title: string, value: string, change: string, isPositive: boolean }) => (
  <NeumorphicCard className="flex flex-col justify-between h-40">
    <div className="flex justify-between items-start">
      <h3 className="text-[#6B7280] font-medium text-sm font-dm-sans">{title}</h3>
      <div 
        className={`w-10 h-10 rounded-full flex items-center justify-center ${isPositive ? 'text-[#38B2AC]' : 'text-red-500'}`}
        style={{ boxShadow: COLORS.shadows.insetSmall }}
      >
        {isPositive ? <ArrowUpRight size={18} /> : <ArrowDownRight size={18} />}
      </div>
    </div>
    <div>
      <h2 className="text-3xl font-extrabold text-[#3D4852] font-jakarta tracking-tight">{value}</h2>
      <p className={`text-sm font-medium mt-1 ${isPositive ? 'text-[#38B2AC]' : 'text-red-500'}`}>
        {change} <span className="text-[#A0AEC0]">vs last week</span>
      </p>
    </div>
  </NeumorphicCard>
);

// --- Main Component ---

export function NeumorphicTradeDashboard() {
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);

  return (
    <div className="min-h-screen bg-[#E0E5EC] text-[#3D4852] font-dm-sans overflow-x-hidden selection:bg-[#6C63FF] selection:text-white">
      {/* Global Styles for Fonts & Scrollbar */}
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@500;600;700;800&family=DM+Sans:wght@400;500;700&display=swap');
        
        .font-jakarta { font-family: 'Plus Jakarta Sans', sans-serif; }
        .font-dm-sans { font-family: 'DM Sans', sans-serif; }
        
        ::-webkit-scrollbar {
          width: 8px;
        }
        ::-webkit-scrollbar-track {
          background: #E0E5EC; 
        }
        ::-webkit-scrollbar-thumb {
          background: #A0AEC0; 
          border-radius: 4px;
        }
        ::-webkit-scrollbar-thumb:hover {
          background: #6B7280; 
        }
      `}</style>

      {/* --- Mobile Navigation Overlay --- */}
      <AnimatePresence>
        {isMobileMenuOpen && (
          <motion.div 
            initial={{ opacity: 0, x: -100 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: -100 }}
            className="fixed inset-0 z-50 bg-[#E0E5EC] p-6 md:hidden"
          >
            <div className="flex justify-between items-center mb-8">
              <div className="flex items-center gap-3">
                <div className="w-10 h-10 rounded-xl bg-[#6C63FF] flex items-center justify-center text-white font-bold text-lg shadow-lg">
                  TG
                </div>
                <span className="font-jakarta font-bold text-xl text-[#3D4852]">TradeGrow</span>
              </div>
              <button onClick={() => setIsMobileMenuOpen(false)}>
                <IconButton icon={X} />
              </button>
            </div>
            <nav className="space-y-6">
              <NeumorphicButton active className="w-full justify-start gap-4">
                <LayoutDashboard size={20} /> Dashboard
              </NeumorphicButton>
              <NeumorphicButton className="w-full justify-start gap-4">
                <BookOpen size={20} /> Journal
              </NeumorphicButton>
              <NeumorphicButton className="w-full justify-start gap-4">
                <TrendingUp size={20} /> Analytics
              </NeumorphicButton>
              <NeumorphicButton className="w-full justify-start gap-4">
                <Settings size={20} /> Settings
              </NeumorphicButton>
            </nav>
          </motion.div>
        )}
      </AnimatePresence>

      <div className="flex max-w-[1600px] mx-auto">
        {/* --- Sidebar (Desktop) --- */}
        <aside className="hidden md:flex flex-col w-64 h-screen sticky top-0 py-8 pl-8 pr-4">
          <div className="flex items-center gap-3 mb-12 px-2">
            <div className="w-12 h-12 rounded-2xl bg-[#E0E5EC] flex items-center justify-center text-[#6C63FF]" style={{ boxShadow: COLORS.shadows.extruded }}>
              <TrendingUp size={24} strokeWidth={3} />
            </div>
            <span className="font-jakarta font-extrabold text-2xl tracking-tight text-[#3D4852]">TradeGrow</span>
          </div>

          <nav className="space-y-6 flex-1">
            <NeumorphicButton active className="w-full justify-start gap-4">
              <LayoutDashboard size={20} /> Dashboard
            </NeumorphicButton>
            <NeumorphicButton className="w-full justify-start gap-4">
              <BookOpen size={20} /> Journal
            </NeumorphicButton>
            <NeumorphicButton className="w-full justify-start gap-4">
              <Wallet size={20} /> Accounts
            </NeumorphicButton>
            <NeumorphicButton className="w-full justify-start gap-4">
              <Calendar size={20} /> Calendar
            </NeumorphicButton>
          </nav>

          <div className="mt-auto">
             <NeumorphicCard className="p-6 flex items-center gap-3">
               <div className="w-10 h-10 rounded-full bg-gray-300 overflow-hidden" style={{ boxShadow: COLORS.shadows.inset }}>
                 <img src="https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?q=80&w=100&auto=format&fit=crop" alt="User" className="w-full h-full object-cover opacity-80" />
               </div>
               <div className="flex-1 min-w-0">
                 <p className="text-sm font-bold text-[#3D4852] truncate">Alex Trader</p>
                 <p className="text-xs text-[#6B7280] truncate">Pro Account</p>
               </div>
               <Settings size={18} className="text-[#6B7280]" />
             </NeumorphicCard>
          </div>
        </aside>

        {/* --- Main Content --- */}
        <main className="flex-1 p-6 md:p-8 lg:p-12 overflow-y-auto">
          {/* Header */}
          <header className="flex justify-between items-center mb-12">
            <div className="md:hidden">
              <button onClick={() => setIsMobileMenuOpen(true)}>
                <IconButton icon={Menu} />
              </button>
            </div>
            
            <div className="hidden md:block">
              <h1 className="text-3xl font-jakarta font-extrabold text-[#3D4852]">Dashboard</h1>
              <p className="text-[#6B7280] mt-1 font-medium">Welcome back to your growth garden.</p>
            </div>

            <div className="flex items-center gap-6">
              <div className="hidden md:block w-96">
                <NeumorphicInput placeholder="Search trades, notes, or tags..." icon={Search} />
              </div>
              <IconButton icon={Bell} />
            </div>
          </header>

          {/* Stats Grid */}
          <section className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-12">
            <StatCard title="Total Equity" value="$10,850.00" change="+8.5%" isPositive={true} />
            <StatCard title="Win Rate" value="68.4%" change="+2.1%" isPositive={true} />
            <StatCard title="Profit Factor" value="2.45" change="-0.2" isPositive={false} />
          </section>

          {/* Main Chart Section */}
          <section className="mb-12">
            <div className="flex justify-between items-end mb-6">
              <h2 className="text-xl font-jakarta font-bold text-[#3D4852]">Equity Curve</h2>
              <div className="flex gap-4">
                <NeumorphicButton active className="text-xs py-2 px-4 rounded-xl">1W</NeumorphicButton>
                <NeumorphicButton className="text-xs py-2 px-4 rounded-xl">1M</NeumorphicButton>
                <NeumorphicButton className="text-xs py-2 px-4 rounded-xl">YTD</NeumorphicButton>
              </div>
            </div>
            
            <NeumorphicCard className="h-[400px] w-full p-6 relative overflow-hidden">
               {/* "Molded" look for the chart container */}
               <div className="absolute inset-0 rounded-[32px] pointer-events-none shadow-[inset_10px_10px_20px_rgb(163,177,198,0.3),inset_-10px_-10px_20px_rgba(255,255,255,0.8)] z-10" />
               
               <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={equityData}>
                  <defs>
                    <linearGradient id="colorValue" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="5%" stopColor="#6C63FF" stopOpacity={0.3}/>
                      <stop offset="95%" stopColor="#6C63FF" stopOpacity={0}/>
                    </linearGradient>
                  </defs>
                  <Tooltip 
                    contentStyle={{ 
                      backgroundColor: '#E0E5EC', 
                      borderRadius: '12px', 
                      border: 'none', 
                      boxShadow: '9px 9px 16px rgb(163,177,198,0.6), -9px -9px 16px rgba(255,255,255,0.5)',
                      color: '#3D4852'
                    }} 
                  />
                  <XAxis 
                    dataKey="date" 
                    axisLine={false} 
                    tickLine={false} 
                    tick={{ fill: '#6B7280', fontSize: 12 }} 
                    dy={10}
                  />
                  <YAxis 
                    axisLine={false} 
                    tickLine={false} 
                    tick={{ fill: '#6B7280', fontSize: 12 }} 
                    dx={-10}
                  />
                  <Area 
                    type="monotone" 
                    dataKey="value" 
                    stroke="#6C63FF" 
                    strokeWidth={4} 
                    fillOpacity={1} 
                    fill="url(#colorValue)" 
                  />
                </AreaChart>
              </ResponsiveContainer>
            </NeumorphicCard>
          </section>

          {/* Bottom Grid: Journal & Trades */}
          <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
            
            {/* Quick Journal */}
            <section className="lg:col-span-2">
              <h2 className="text-xl font-jakarta font-bold text-[#3D4852] mb-6">Daily Reflection</h2>
              <NeumorphicCard className="h-auto">
                <div className="mb-6">
                  <label className="block text-sm font-bold text-[#6B7280] mb-4 ml-1">What went well today?</label>
                  <textarea 
                    className="w-full h-32 bg-[#E0E5EC] rounded-2xl p-6 text-[#3D4852] placeholder-[#A0AEC0] outline-none resize-none transition-all duration-300 focus:ring-2 focus:ring-[#6C63FF] focus:ring-offset-2 focus:ring-offset-[#E0E5EC]"
                    style={{ boxShadow: COLORS.shadows.insetDeep }}
                    placeholder="I stuck to my plan and waited for the perfect setup..."
                  />
                </div>
                <div className="flex justify-end">
                   <NeumorphicButton active className="bg-[#E0E5EC]">
                     Save Entry
                   </NeumorphicButton>
                </div>
              </NeumorphicCard>
            </section>

            {/* Recent Trades */}
            <section>
              <div className="flex justify-between items-center mb-6">
                <h2 className="text-xl font-jakarta font-bold text-[#3D4852]">Recent Trades</h2>
                <button className="text-[#6C63FF] text-sm font-bold">View All</button>
              </div>
              
              <div className="space-y-6">
                {recentTrades.map((trade) => (
                  <NeumorphicCard key={trade.id} className="p-5 flex items-center justify-between !rounded-2xl cursor-pointer hover:translate-y-[-2px] transition-transform">
                    <div className="flex items-center gap-4">
                      <div 
                        className={`w-12 h-12 rounded-xl flex items-center justify-center font-bold text-sm ${trade.result === 'Win' ? 'text-[#38B2AC]' : 'text-red-500'}`}
                        style={{ boxShadow: COLORS.shadows.inset }}
                      >
                        {trade.pair.split('/')[0]}
                      </div>
                      <div>
                        <h4 className="font-bold text-[#3D4852]">{trade.pair}</h4>
                        <p className="text-xs text-[#6B7280] font-medium">{trade.type} • {trade.date}</p>
                      </div>
                    </div>
                    <div className={`font-bold ${trade.result === 'Win' ? 'text-[#38B2AC]' : 'text-red-500'}`}>
                      {trade.amount}
                    </div>
                  </NeumorphicCard>
                ))}
                
                <NeumorphicButton className="w-full !rounded-2xl border-2 border-transparent hover:border-[#E0E5EC]">
                  <Plus size={20} /> <span className="ml-2">Log New Trade</span>
                </NeumorphicButton>
              </div>
            </section>

          </div>
        </main>
      </div>
    </div>
  );
}

export default NeumorphicTradeDashboard;
~~~

Implementation Guidelines

1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system

Help me integrate this into my design
All Prompts