File size: 4,178 Bytes
b0c3c39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import React, { useState, useRef, useEffect } from 'react';
import styles from './MindMapItem.module.css';

interface MindMapItemProps {
  id: string;
  name: string;
  updatedAt: string;
  onSelect: () => void;
  onDelete: () => void;
  onRename: (newName: string) => void;
  onShare: () => void;
  isActive: boolean;
}

const MindMapItem: React.FC<MindMapItemProps> = ({

  id,

  name,

  updatedAt,

  onSelect,

  onDelete,

  onRename,

  onShare,

  isActive,

}) => {
  const [isMenuOpen, setIsMenuOpen] = useState(false);
  const [isEditing, setIsEditing] = useState(false);
  const [editedName, setEditedName] = useState(name);
  const menuRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
        setIsMenuOpen(false);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  useEffect(() => {
    if (isEditing && inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select();
    }
  }, [isEditing]);

  const handleMenuClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    setIsMenuOpen(!isMenuOpen);
  };

  const handleRename = () => {
    setIsEditing(true);
    setIsMenuOpen(false);
  };

  const handleRenameSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (editedName.trim()) {
      onRename(editedName.trim());
    }
    setIsEditing(false);
  };

  const handleDelete = () => {
    setIsMenuOpen(false);
    onDelete();
  };

  const handleShare = () => {
    setIsMenuOpen(false);
    onShare();
  };

  return (
    <div className={`${styles.mindMapItem} ${isActive ? styles.active : ''}`} onClick={onSelect} style={{ position: 'relative' }}>

      <div className={styles.mindMapInfo}>

        <span className={styles.mindMapName}>{name}</span>

        <span className={styles.mindMapDate}>

          {new Date(updatedAt).toLocaleDateString()}

        </span>

      </div>

      <div className={styles.verticalToolbar}>

        {isEditing ? (

          <form onSubmit={handleRenameSubmit} style={{ width: '100%' }}>

            <input

              ref={inputRef}

              type="text"

              value={editedName}

              onChange={(e) => setEditedName(e.target.value)}

              onBlur={handleRenameSubmit}

              className={styles.renameInput}

              placeholder="Rename mind map"

              style={{ marginBottom: 8 }}

            />

          </form>

        ) : null}

        <button onClick={handleRename} className={styles.toolbarButton} aria-label="Rename mind map">

          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" /><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" /></svg>

        </button>

        <button onClick={handleShare} className={styles.toolbarButton} aria-label="Share mind map">

          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="18" cy="5" r="3" /><circle cx="6" cy="12" r="3" /><circle cx="18" cy="19" r="3" /><line x1="8.59" y1="13.51" x2="15.42" y2="17.49" /><line x1="15.41" y1="6.51" x2="8.59" y2="10.49" /></svg>

        </button>

        <button onClick={handleDelete} className={`${styles.toolbarButton} ${styles.delete}`} aria-label="Delete mind map">

          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="3 6 5 6 21 6" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /></svg>

        </button>

      </div>

    </div>
  );
};

export default MindMapItem;