TrainingView.tsx 11.1 KB
import React, { useState } from 'react';
import { 
  Plus, 
  Search, 
  MapPin, 
  Store, 
  Pencil, 
  X, 
  FileText, 
  Image as ImageIcon,
  ChevronDown,
  ChevronRight,
  HelpCircle,
  ArrowUpDown,
  Lock
} from 'lucide-react';
import { Input } from "../ui/input";
import { Button } from "../ui/button";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "../ui/select";
import { cn } from "../ui/utils";

// Mock Data Types
type FileItem = {
  id: string;
  name: string;
  date: string;
  type: 'image' | 'doc';
  url?: string;
};

type SubCategory = {
  id: string;
  name: string;
  files: FileItem[];
  isOpen?: boolean;
};

type Category = {
  id: string;
  name: string;
  subcategories: SubCategory[];
  isOpen?: boolean;
};

export function TrainingView() {
  const [categories, setCategories] = useState<Category[]>([
    {
      id: '1',
      name: 'Pop',
      isOpen: true,
      subcategories: [
        {
          id: '1-1',
          name: '2024',
          isOpen: true,
          files: [
            { id: 'f1', name: 'uuuuu', date: '10/23/24, 12:21 AM', type: 'image' },
            { id: 'f2', name: '664EF167-DFCE-49C1-A417-DC09FEDF78D7.jpg', date: '11/24/25, 8:40 PM', type: 'image' }
          ]
        }
      ]
    },
    {
      id: '2',
      name: 'Training',
      isOpen: true,
      subcategories: [
        {
          id: '2-1',
          name: 'BOH',
          isOpen: false,
          files: []
        },
        {
          id: '2-2',
          name: 'FOH',
          isOpen: true,
          files: [] // Empty for demo to match screenshot structure which shows FILES section but maybe empty? 
          // Actually screenshot shows FOH expanded and FILES header but no files listed below it in the visible area, 
          // or maybe the FILES header is part of the subcategory content.
        }
      ]
    },
    {
      id: '3',
      name: 'ww',
      isOpen: false,
      subcategories: []
    }
  ]);

  const toggleCategory = (id: string) => {
    setCategories(prev => prev.map(cat => 
      cat.id === id ? { ...cat, isOpen: !cat.isOpen } : cat
    ));
  };

  const toggleSubcategory = (catId: string, subId: string) => {
    setCategories(prev => prev.map(cat => {
      if (cat.id !== catId) return cat;
      return {
        ...cat,
        subcategories: cat.subcategories.map(sub => 
          sub.id === subId ? { ...sub, isOpen: !sub.isOpen } : sub
        )
      };
    }));
  };

  return (
    <div className="space-y-6">
      {/* Controls: Search, Location — 与 Labels 等页一致的框样式:单行、圆角、细边框、统一高度 40px */}
      <div className="flex flex-wrap items-center gap-3" style={{ height: 40 }}>
        <Input
          placeholder="Search"
          className="bg-white border border-black rounded-lg w-[180px] shrink-0 py-0 leading-normal"
          style={{ height: 40 }}
        />
        <Select defaultValue="all">
          <SelectTrigger
            className="bg-white border border-black rounded-lg w-[180px] shrink-0 py-0"
            style={{ height: 40 }}
          >
            <SelectValue placeholder="Location" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">all</SelectItem>
            <SelectItem value="loc-a">Location A</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Header Bar */}
      <div className="bg-gray-100 p-2 flex justify-between items-center border-b border-gray-200">
        <h1 className="text-xl font-medium text-gray-700">Information</h1>
        <div className="flex items-center gap-4 text-gray-600">
          <div className="flex items-center gap-1 bg-gray-700 text-white text-[10px] px-1 py-0.5 rounded-sm font-bold">NEW</div>
          <Store className="h-5 w-5" />
          <span className="font-medium">55789</span>
        </div>
      </div>

      {/* Main Content Area */}
      <div className="space-y-4">
        
        {/* New Category Button */}
        <button className="w-full bg-[#2c7bb6] hover:bg-[#256b9e] text-white py-2 px-4 flex items-center gap-2 text-sm font-medium rounded-sm">
          <Plus className="h-4 w-4" />
          New Category
          <HelpCircle className="h-4 w-4 opacity-70" />
        </button>

        {/* Categories List */}
        <div className="space-y-4">
          {categories.map(category => (
            <div key={category.id} className="border border-gray-300 rounded-sm overflow-hidden">
              {/* Category Header */}
              <div className="bg-gradient-to-b from-gray-50 to-gray-100 border-b border-gray-200 p-2 flex items-center justify-between">
                <button 
                  onClick={() => toggleCategory(category.id)}
                  className="flex items-center gap-2 text-gray-700 font-medium text-sm flex-1 text-left"
                >
                  {category.isOpen ? <ChevronDown className="h-4 w-4 text-[#2c7bb6]" /> : <ChevronRight className="h-4 w-4 text-[#2c7bb6]" />}
                  {category.name}
                </button>
                <div className="flex items-center gap-2">
                  <button className="text-gray-400 hover:text-gray-600"><Pencil className="h-4 w-4" /></button>
                  <button className="text-red-400 hover:text-red-600"><X className="h-4 w-4" /></button>
                </div>
              </div>

              {/* Category Content */}
              {category.isOpen && (
                <div className="p-2 space-y-3 bg-white">
                  {/* New Subcategory Button */}
                  <button className="w-full bg-[#2c7bb6] hover:bg-[#256b9e] text-white py-2 px-4 flex items-center gap-2 text-sm font-medium rounded-sm">
                    <Plus className="h-4 w-4" />
                    New Subcategory
                    <HelpCircle className="h-4 w-4 opacity-70" />
                  </button>

                  {/* Subcategories List */}
                  <div className="space-y-3">
                    {category.subcategories.map(sub => (
                      <div key={sub.id} className="border border-gray-200 rounded-sm">
                        {/* Subcategory Header */}
                        <div className="bg-white border-b border-gray-200 p-2 flex items-center justify-between">
                          <button 
                            onClick={() => toggleSubcategory(category.id, sub.id)}
                            className="flex items-center gap-2 text-gray-700 font-medium text-sm flex-1 text-left"
                          >
                            {sub.isOpen ? <ChevronDown className="h-4 w-4 text-[#2c7bb6]" /> : <ChevronRight className="h-4 w-4 text-[#2c7bb6]" />}
                            {sub.name}
                          </button>
                          <div className="flex items-center gap-2">
                            <button className="text-gray-400 hover:text-gray-600"><Pencil className="h-4 w-4" /></button>
                            <button className="text-red-400 hover:text-red-600"><X className="h-4 w-4" /></button>
                          </div>
                        </div>

                        {/* Subcategory Content (Files) */}
                        {sub.isOpen && (
                          <div className="p-3 bg-gray-50/50">
                            <div className="mb-2 text-xs font-bold text-gray-500 uppercase tracking-wide">Files</div>
                            
                            {/* File Actions */}
                            <div className="flex flex-wrap gap-2 mb-3 justify-end">
                              <Button size="sm" className="h-8 bg-[#4CAF50] hover:bg-[#43a047] text-white text-xs border-none rounded-sm">
                                Upload Your Own File(s)
                              </Button>
                              <Button size="sm" className="h-8 bg-[#4CAF50] hover:bg-[#43a047] text-white text-xs border-none rounded-sm">
                                Create A Custom File
                              </Button>
                              <Button size="sm" className="h-8 bg-[#2c7bb6] hover:bg-[#256b9e] text-white text-xs border-none rounded-sm">
                                Edit File Permissions
                              </Button>
                              <Button size="sm" className="h-8 bg-[#2c7bb6] hover:bg-[#256b9e] text-white text-xs border-none rounded-sm gap-1">
                                Sort (A-Z) <ArrowUpDown className="h-3 w-3" />
                              </Button>
                            </div>

                            {/* Files List */}
                            <div className="space-y-1">
                              {sub.files.length > 0 ? (
                                sub.files.map(file => (
                                  <div key={file.id} className="flex items-center bg-gray-200/50 p-2 border border-gray-200 rounded-sm text-sm hover:bg-gray-200 transition-colors">
                                    <div className="flex-shrink-0 mr-3">
                                      {file.type === 'image' ? (
                                        <ImageIcon className="h-5 w-5 text-[#2c7bb6]" />
                                      ) : (
                                        <FileText className="h-5 w-5 text-[#2c7bb6]" />
                                      )}
                                    </div>
                                    <div className="flex-1 min-w-0">
                                      <div className="font-medium text-gray-700 truncate">{file.name}</div>
                                    </div>
                                    <div className="text-xs text-gray-500 mr-4 whitespace-nowrap">{file.date}</div>
                                    <div className="flex items-center gap-1">
                                      <button className="p-1 text-gray-400 hover:text-gray-600 bg-white border border-gray-300 rounded-sm"><FileText className="h-3 w-3" /></button>
                                      <button className="p-1 text-gray-400 hover:text-gray-600 bg-white border border-gray-300 rounded-sm"><Pencil className="h-3 w-3" /></button>
                                      <button className="p-1 text-red-400 hover:text-red-600 bg-white border border-gray-300 rounded-sm"><X className="h-3 w-3" /></button>
                                    </div>
                                  </div>
                                ))
                              ) : (
                                <div className="p-4 border-2 border-dashed border-gray-300 rounded-sm text-center text-gray-400 text-sm">
                                  No files in this subcategory
                                </div>
                              )}
                            </div>
                          </div>
                        )}
                      </div>
                    ))}
                    {category.subcategories.length === 0 && (
                       <div className="p-2 text-sm text-gray-400 italic">No subcategories</div>
                    )}
                  </div>
                </div>
              )}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}