create-mcp-use-app 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/templates/api/README.md +224 -0
- package/dist/templates/api/package.json +24 -0
- package/dist/templates/api/src/server.ts +229 -0
- package/dist/templates/api/tsconfig.json +20 -0
- package/dist/templates/basic/README.md +64 -0
- package/dist/templates/basic/package.json +23 -0
- package/dist/templates/basic/src/server.ts +67 -0
- package/dist/templates/basic/tsconfig.json +20 -0
- package/dist/templates/filesystem/README.md +139 -0
- package/dist/templates/filesystem/package.json +23 -0
- package/dist/templates/filesystem/src/server.ts +155 -0
- package/dist/templates/filesystem/tsconfig.json +20 -0
- package/dist/templates/ui/README.md +454 -0
- package/dist/templates/ui/package-lock.json +2870 -0
- package/dist/templates/ui/package.json +45 -0
- package/dist/templates/ui/resources/data-visualization.tsx +475 -0
- package/dist/templates/ui/resources/kanban-board.tsx +306 -0
- package/dist/templates/ui/resources/todo-list.tsx +408 -0
- package/dist/templates/ui/src/server.ts +153 -0
- package/dist/templates/ui/tsconfig.json +20 -0
- package/package.json +63 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
|
|
4
|
+
interface Task {
|
|
5
|
+
id: string
|
|
6
|
+
title: string
|
|
7
|
+
description: string
|
|
8
|
+
status: 'todo' | 'in-progress' | 'done'
|
|
9
|
+
priority: 'low' | 'medium' | 'high'
|
|
10
|
+
assignee?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface KanbanBoardProps {
|
|
14
|
+
initialTasks?: Task[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const KanbanBoard: React.FC<KanbanBoardProps> = ({ initialTasks = [] }) => {
|
|
18
|
+
const [tasks, setTasks] = useState<Task[]>(initialTasks)
|
|
19
|
+
const [newTask, setNewTask] = useState({ title: '', description: '', priority: 'medium' as const })
|
|
20
|
+
|
|
21
|
+
// Load tasks from URL parameters or use defaults
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
24
|
+
const tasksParam = urlParams.get('tasks')
|
|
25
|
+
|
|
26
|
+
if (tasksParam) {
|
|
27
|
+
try {
|
|
28
|
+
const parsedTasks = JSON.parse(decodeURIComponent(tasksParam))
|
|
29
|
+
setTasks(parsedTasks)
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error('Error parsing tasks from URL:', error)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Default tasks for demo
|
|
37
|
+
setTasks([
|
|
38
|
+
{ id: '1', title: 'Design UI mockups', description: 'Create wireframes for the new dashboard', status: 'todo', priority: 'high', assignee: 'Alice' },
|
|
39
|
+
{ id: '2', title: 'Implement authentication', description: 'Add login and registration functionality', status: 'in-progress', priority: 'high', assignee: 'Bob' },
|
|
40
|
+
{ id: '3', title: 'Write documentation', description: 'Document the API endpoints', status: 'done', priority: 'medium', assignee: 'Charlie' },
|
|
41
|
+
{ id: '4', title: 'Setup CI/CD', description: 'Configure automated testing and deployment', status: 'todo', priority: 'medium' },
|
|
42
|
+
{ id: '5', title: 'Code review', description: 'Review pull requests from the team', status: 'in-progress', priority: 'low', assignee: 'David' },
|
|
43
|
+
])
|
|
44
|
+
}
|
|
45
|
+
}, [])
|
|
46
|
+
|
|
47
|
+
const addTask = () => {
|
|
48
|
+
if (newTask.title.trim()) {
|
|
49
|
+
const task: Task = {
|
|
50
|
+
id: Date.now().toString(),
|
|
51
|
+
title: newTask.title,
|
|
52
|
+
description: newTask.description,
|
|
53
|
+
status: 'todo',
|
|
54
|
+
priority: newTask.priority,
|
|
55
|
+
}
|
|
56
|
+
setTasks([...tasks, task])
|
|
57
|
+
setNewTask({ title: '', description: '', priority: 'medium' })
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const moveTask = (taskId: string, newStatus: Task['status']) => {
|
|
62
|
+
setTasks(tasks.map(task =>
|
|
63
|
+
task.id === taskId ? { ...task, status: newStatus } : task,
|
|
64
|
+
))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const deleteTask = (taskId: string) => {
|
|
68
|
+
setTasks(tasks.filter(task => task.id !== taskId))
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const getTasksByStatus = (status: Task['status']) => {
|
|
72
|
+
return tasks.filter(task => task.status === status)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const getPriorityColor = (priority: Task['priority']) => {
|
|
76
|
+
switch (priority) {
|
|
77
|
+
case 'high': return '#ff4757'
|
|
78
|
+
case 'medium': return '#ffa502'
|
|
79
|
+
case 'low': return '#2ed573'
|
|
80
|
+
default: return '#57606f'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const columns = [
|
|
85
|
+
{ id: 'todo', title: 'To Do', color: '#57606f' },
|
|
86
|
+
{ id: 'in-progress', title: 'In Progress', color: '#ffa502' },
|
|
87
|
+
{ id: 'done', title: 'Done', color: '#2ed573' },
|
|
88
|
+
] as const
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div style={{ padding: '20px' }}>
|
|
92
|
+
<div style={{ marginBottom: '30px' }}>
|
|
93
|
+
<h1 style={{ margin: '0 0 20px 0', color: '#2c3e50' }}>Kanban Board</h1>
|
|
94
|
+
|
|
95
|
+
{/* Add new task form */}
|
|
96
|
+
<div style={{
|
|
97
|
+
background: 'white',
|
|
98
|
+
padding: '20px',
|
|
99
|
+
borderRadius: '8px',
|
|
100
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
101
|
+
marginBottom: '20px',
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
<h3 style={{ margin: '0 0 15px 0' }}>Add New Task</h3>
|
|
105
|
+
<div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
|
|
106
|
+
<input
|
|
107
|
+
type="text"
|
|
108
|
+
placeholder="Task title"
|
|
109
|
+
value={newTask.title}
|
|
110
|
+
onChange={e => setNewTask({ ...newTask, title: e.target.value })}
|
|
111
|
+
style={{
|
|
112
|
+
padding: '8px 12px',
|
|
113
|
+
border: '1px solid #ddd',
|
|
114
|
+
borderRadius: '4px',
|
|
115
|
+
flex: '1',
|
|
116
|
+
minWidth: '200px',
|
|
117
|
+
}}
|
|
118
|
+
/>
|
|
119
|
+
<input
|
|
120
|
+
type="text"
|
|
121
|
+
placeholder="Description"
|
|
122
|
+
value={newTask.description}
|
|
123
|
+
onChange={e => setNewTask({ ...newTask, description: e.target.value })}
|
|
124
|
+
style={{
|
|
125
|
+
padding: '8px 12px',
|
|
126
|
+
border: '1px solid #ddd',
|
|
127
|
+
borderRadius: '4px',
|
|
128
|
+
flex: '1',
|
|
129
|
+
minWidth: '200px',
|
|
130
|
+
}}
|
|
131
|
+
/>
|
|
132
|
+
<select
|
|
133
|
+
title="Priority"
|
|
134
|
+
value={newTask.priority}
|
|
135
|
+
onChange={e => setNewTask({ ...newTask, priority: e.target.value as Task['priority'] })}
|
|
136
|
+
style={{
|
|
137
|
+
padding: '8px 12px',
|
|
138
|
+
border: '1px solid #ddd',
|
|
139
|
+
borderRadius: '4px',
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
<option value="low">Low Priority</option>
|
|
143
|
+
<option value="medium">Medium Priority</option>
|
|
144
|
+
<option value="high">High Priority</option>
|
|
145
|
+
</select>
|
|
146
|
+
<button
|
|
147
|
+
onClick={addTask}
|
|
148
|
+
style={{
|
|
149
|
+
padding: '8px 16px',
|
|
150
|
+
background: '#3498db',
|
|
151
|
+
color: 'white',
|
|
152
|
+
border: 'none',
|
|
153
|
+
borderRadius: '4px',
|
|
154
|
+
cursor: 'pointer',
|
|
155
|
+
}}
|
|
156
|
+
>
|
|
157
|
+
Add Task
|
|
158
|
+
</button>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
{/* Kanban columns */}
|
|
164
|
+
<div style={{ display: 'flex', gap: '20px', overflowX: 'auto' }}>
|
|
165
|
+
{columns.map(column => (
|
|
166
|
+
<div
|
|
167
|
+
key={column.id}
|
|
168
|
+
style={{
|
|
169
|
+
flex: '1',
|
|
170
|
+
minWidth: '300px',
|
|
171
|
+
background: 'white',
|
|
172
|
+
borderRadius: '8px',
|
|
173
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
174
|
+
overflow: 'hidden',
|
|
175
|
+
}}
|
|
176
|
+
>
|
|
177
|
+
<div
|
|
178
|
+
style={{
|
|
179
|
+
background: column.color,
|
|
180
|
+
color: 'white',
|
|
181
|
+
padding: '15px 20px',
|
|
182
|
+
fontWeight: 'bold',
|
|
183
|
+
display: 'flex',
|
|
184
|
+
justifyContent: 'space-between',
|
|
185
|
+
alignItems: 'center',
|
|
186
|
+
}}
|
|
187
|
+
>
|
|
188
|
+
<span>{column.title}</span>
|
|
189
|
+
<span style={{
|
|
190
|
+
background: 'rgba(255,255,255,0.2)',
|
|
191
|
+
padding: '4px 8px',
|
|
192
|
+
borderRadius: '12px',
|
|
193
|
+
fontSize: '12px',
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
{getTasksByStatus(column.id).length}
|
|
197
|
+
</span>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div style={{ padding: '20px', minHeight: '400px' }}>
|
|
201
|
+
{getTasksByStatus(column.id).map(task => (
|
|
202
|
+
<div
|
|
203
|
+
key={task.id}
|
|
204
|
+
style={{
|
|
205
|
+
background: '#f8f9fa',
|
|
206
|
+
border: '1px solid #e9ecef',
|
|
207
|
+
borderRadius: '6px',
|
|
208
|
+
padding: '15px',
|
|
209
|
+
marginBottom: '10px',
|
|
210
|
+
cursor: 'grab',
|
|
211
|
+
}}
|
|
212
|
+
draggable
|
|
213
|
+
onDragStart={(e) => {
|
|
214
|
+
e.dataTransfer.setData('text/plain', task.id)
|
|
215
|
+
}}
|
|
216
|
+
onDragOver={e => e.preventDefault()}
|
|
217
|
+
onDrop={(e) => {
|
|
218
|
+
e.preventDefault()
|
|
219
|
+
const taskId = e.dataTransfer.getData('text/plain')
|
|
220
|
+
if (taskId === task.id) {
|
|
221
|
+
// Move to next column
|
|
222
|
+
const currentIndex = columns.findIndex(col => col.id === column.id)
|
|
223
|
+
const nextColumn = columns[currentIndex + 1]
|
|
224
|
+
if (nextColumn) {
|
|
225
|
+
moveTask(taskId, nextColumn.id)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}}
|
|
229
|
+
>
|
|
230
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '8px' }}>
|
|
231
|
+
<h4 style={{ margin: '0', color: '#2c3e50' }}>{task.title}</h4>
|
|
232
|
+
<button
|
|
233
|
+
onClick={() => deleteTask(task.id)}
|
|
234
|
+
style={{
|
|
235
|
+
background: 'none',
|
|
236
|
+
border: 'none',
|
|
237
|
+
color: '#e74c3c',
|
|
238
|
+
cursor: 'pointer',
|
|
239
|
+
fontSize: '16px',
|
|
240
|
+
}}
|
|
241
|
+
>
|
|
242
|
+
×
|
|
243
|
+
</button>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
{task.description && (
|
|
247
|
+
<p style={{ margin: '0 0 10px 0', color: '#6c757d', fontSize: '14px' }}>
|
|
248
|
+
{task.description}
|
|
249
|
+
</p>
|
|
250
|
+
)}
|
|
251
|
+
|
|
252
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
253
|
+
<div
|
|
254
|
+
style={{
|
|
255
|
+
background: getPriorityColor(task.priority),
|
|
256
|
+
color: 'white',
|
|
257
|
+
padding: '2px 8px',
|
|
258
|
+
borderRadius: '12px',
|
|
259
|
+
fontSize: '12px',
|
|
260
|
+
fontWeight: 'bold',
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
{task.priority.toUpperCase()}
|
|
264
|
+
</div>
|
|
265
|
+
|
|
266
|
+
{task.assignee && (
|
|
267
|
+
<span style={{
|
|
268
|
+
background: '#e9ecef',
|
|
269
|
+
padding: '2px 8px',
|
|
270
|
+
borderRadius: '12px',
|
|
271
|
+
fontSize: '12px',
|
|
272
|
+
color: '#495057',
|
|
273
|
+
}}
|
|
274
|
+
>
|
|
275
|
+
{task.assignee}
|
|
276
|
+
</span>
|
|
277
|
+
)}
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
))}
|
|
281
|
+
|
|
282
|
+
{getTasksByStatus(column.id).length === 0 && (
|
|
283
|
+
<div style={{
|
|
284
|
+
textAlign: 'center',
|
|
285
|
+
color: '#6c757d',
|
|
286
|
+
padding: '40px 20px',
|
|
287
|
+
fontStyle: 'italic',
|
|
288
|
+
}}
|
|
289
|
+
>
|
|
290
|
+
No tasks in this column
|
|
291
|
+
</div>
|
|
292
|
+
)}
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
))}
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Mount the component
|
|
302
|
+
const container = document.getElementById('widget-root')
|
|
303
|
+
if (container) {
|
|
304
|
+
const root = createRoot(container)
|
|
305
|
+
root.render(<KanbanBoard />)
|
|
306
|
+
}
|