Initial commit: Agile Project Manager

- Complete React + TypeScript application with Vite
- Dashboard with charts and metrics visualization
- Kanban board with drag-and-drop functionality
- Product backlog management with user stories
- Sprint planning and tracking features
- Comprehensive UI component library (shadcn/ui)
- Tailwind CSS styling with dark mode support
- Context-based state management
- Mock data for immediate testing and demonstration
This commit is contained in:
Your Name
2025-10-24 17:58:09 -07:00
commit bf1dbe39a8
73 changed files with 12773 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
import React, { useState, useEffect } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog';
import { Button } from './ui/button';
import { Input } from './ui/input';
import { Textarea } from './ui/textarea';
import { Label } from './ui/label';
import { useApp } from '../contexts/AppContext';
import { Task } from '../types';
import { Trash2 } from 'lucide-react';
interface EditTaskDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
task: Task | null;
}
export const EditTaskDialog: React.FC<EditTaskDialogProps> = ({
open,
onOpenChange,
task
}) => {
const { updateTask, deleteTask } = useApp();
const [title, setTitle] = useState('');
const [description, setDescription] = useState('');
const [timeComplexity, setTimeComplexity] = useState('');
useEffect(() => {
if (task) {
setTitle(task.title);
setDescription(task.description);
setTimeComplexity(task.timeComplexity);
}
}, [task]);
const handleSave = () => {
if (task && title.trim()) {
updateTask(task.id, {
title,
description,
timeComplexity
});
onOpenChange(false);
}
};
const handleDelete = () => {
if (task && confirm('Are you sure you want to delete this task?')) {
deleteTask(task.id);
onOpenChange(false);
}
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle>Edit Task</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<Label htmlFor="edit-title">Task Title</Label>
<Input
id="edit-title"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Enter task title"
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-description">Task Description</Label>
<Textarea
id="edit-description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Enter task description"
rows={4}
/>
</div>
<div className="space-y-2">
<Label htmlFor="edit-complexity">Time Complexity</Label>
<Input
id="edit-complexity"
value={timeComplexity}
onChange={(e) => setTimeComplexity(e.target.value)}
placeholder="e.g., 4 hours, 2 days"
/>
</div>
</div>
<div className="flex justify-between">
<Button variant="destructive" onClick={handleDelete}>
<Trash2 className="mr-2 h-4 w-4" />
Delete
</Button>
<div className="flex gap-2">
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button onClick={handleSave}>Save</Button>
</div>
</div>
</DialogContent>
</Dialog>
);
};