feat(backup): add backup.json for feature tracking and status updates

- Introduced a new `backup.json` file to track feature statuses, descriptions, and summaries for better project management.
- Updated `.automaker/feature_list.json` to reflect verified statuses for several features, ensuring accurate representation of progress.
- Enhanced `memory.md` with details on drag-and-drop functionality for features in `waiting_approval` status.
- Improved auto mode service to allow running tasks to complete when auto mode is stopped, enhancing user experience.
This commit is contained in:
Cody Seibert
2025-12-10 14:29:05 -05:00
parent d83eb86f22
commit c502fbc57a
26 changed files with 2497 additions and 298 deletions

View File

@@ -12,6 +12,7 @@ interface ImageDropZoneProps {
className?: string;
children?: React.ReactNode;
disabled?: boolean;
images?: ImageAttachment[]; // Optional controlled images prop
}
const ACCEPTED_IMAGE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
@@ -24,12 +25,24 @@ export function ImageDropZone({
className,
children,
disabled = false,
images,
}: ImageDropZoneProps) {
const [isDragOver, setIsDragOver] = useState(false);
const [isProcessing, setIsProcessing] = useState(false);
const [selectedImages, setSelectedImages] = useState<ImageAttachment[]>([]);
const [internalImages, setInternalImages] = useState<ImageAttachment[]>([]);
const fileInputRef = useRef<HTMLInputElement>(null);
// Use controlled images if provided, otherwise use internal state
const selectedImages = images ?? internalImages;
// Update images - for controlled mode, just call the callback; for uncontrolled, also update internal state
const updateImages = useCallback((newImages: ImageAttachment[]) => {
if (images === undefined) {
setInternalImages(newImages);
}
onImagesSelected(newImages);
}, [images, onImagesSelected]);
const processFiles = useCallback(async (files: FileList) => {
if (disabled || isProcessing) return;
@@ -79,12 +92,11 @@ export function ImageDropZone({
if (newImages.length > 0) {
const allImages = [...selectedImages, ...newImages];
setSelectedImages(allImages);
onImagesSelected(allImages);
updateImages(allImages);
}
setIsProcessing(false);
}, [disabled, isProcessing, maxFiles, maxFileSize, selectedImages, onImagesSelected]);
}, [disabled, isProcessing, maxFiles, maxFileSize, selectedImages, updateImages]);
const handleDrop = useCallback((e: React.DragEvent) => {
e.preventDefault();
@@ -132,14 +144,12 @@ export function ImageDropZone({
const removeImage = useCallback((imageId: string) => {
const updated = selectedImages.filter(img => img.id !== imageId);
setSelectedImages(updated);
onImagesSelected(updated);
}, [selectedImages, onImagesSelected]);
updateImages(updated);
}, [selectedImages, updateImages]);
const clearAllImages = useCallback(() => {
setSelectedImages([]);
onImagesSelected([]);
}, [onImagesSelected]);
updateImages([]);
}, [updateImages]);
return (
<div className={cn("relative", className)}>