File size: 3,647 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 115 116 117 118 119 120 121 122 123 124 |
import React, { useState, useEffect } from 'react';
import axios from '../utils/axios';
import { MindMapData } from '../utils/jsonUtils';
import styles from './MindMapList.module.css';
import MindMapItem from './MindMapItem';
interface MindMap {
id: string;
name: string;
updatedAt: string;
nodes: any[];
edges: any[];
}
interface MindMapListProps {
isCollapsed: boolean;
onSelectMindMap: (mindMap: MindMapData) => void;
onNewMindMap: () => void;
onDeleteMindMap: (id: string) => void;
}
const MindMapList: React.FC<MindMapListProps> = ({
isCollapsed,
onSelectMindMap,
onNewMindMap,
onDeleteMindMap,
}) => {
const [mindMaps, setMindMaps] = useState<MindMapData[]>([]);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const fetchMindMaps = async () => {
setLoading(true);
setError(null);
try {
const res = await axios.get('/api/workflows');
setMindMaps(res.data);
} catch (err: any) {
setError('Failed to load mind maps');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchMindMaps();
}, []);
const handleDelete = async (id: string) => {
try {
await axios.delete(`/api/workflows/${id}`);
await fetchMindMaps();
if (selectedId === id) setSelectedId(null);
onDeleteMindMap(id);
} catch {
setError('Failed to delete mind map');
}
};
const handleRename = async (id: string, newName: string) => {
try {
await axios.put(`/api/workflows/${id}`, { name: newName });
await fetchMindMaps();
} catch {
setError('Failed to rename mind map');
}
};
return (
<div className={styles.mindMapList}>
<div className={styles.header}>
<h3 className={styles.title}>Your Mind Maps</h3>
<button
onClick={onNewMindMap}
className={styles.newButton}
title="Create new mind map"
>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
style={{ marginRight: isCollapsed ? 0 : 4 }}
>
<circle cx="12" cy="12" r="10" />
<line x1="12" y1="8" x2="12" y2="16" />
<line x1="8" y1="12" x2="16" y2="12" />
</svg>
{!isCollapsed && <span>New</span>}
</button>
</div>
<div className={styles.list}>
{loading && <div className={styles.loading}>Loading...</div>}
{error && <div className={styles.error}>{error}</div>}
{!loading && !error && mindMaps.length === 0 && (
<div className={styles.empty}>No mind maps found.</div>
)}
{!loading && !error && mindMaps.map((mindMap) => (
<MindMapItem
key={mindMap.id}
id={mindMap.id}
name={mindMap.name}
updatedAt={mindMap.updatedAt}
isActive={selectedId === mindMap.id}
onSelect={() => {
setSelectedId(mindMap.id);
onSelectMindMap(mindMap);
}}
onDelete={() => handleDelete(mindMap.id)}
onRename={(newName) => handleRename(mindMap.id, newName)}
onShare={() => {}}
/>
))}
</div>
</div>
);
};
export default MindMapList; |