diff --git a/client/src/pages/new-post.tsx b/client/src/pages/new-post.tsx
index 92969f2..b165cdf 100644
--- a/client/src/pages/new-post.tsx
+++ b/client/src/pages/new-post.tsx
@@ -1,8 +1,25 @@
import { useState, useCallback, useRef } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { useLocation } from "wouter";
-import { Send, Sparkles, Image as ImageIcon, Calendar, Upload, Camera } from "lucide-react";
+import { Send, Sparkles, Image as ImageIcon, Calendar, Upload, Camera, GripVertical } from "lucide-react";
import { useDropzone } from "react-dropzone";
+import {
+ DndContext,
+ closestCenter,
+ KeyboardSensor,
+ PointerSensor,
+ useSensor,
+ useSensors,
+ DragEndEvent,
+} from "@dnd-kit/core";
+import {
+ arrayMove,
+ SortableContext,
+ sortableKeyboardCoordinates,
+ rectSortingStrategy,
+ useSortable,
+} from "@dnd-kit/sortable";
+import { CSS } from "@dnd-kit/utilities";
import Sidebar from "@/components/sidebar";
import TopBar from "@/components/topbar";
import { Button } from "@/components/ui/button";
@@ -16,6 +33,69 @@ import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient";
import type { SocialPage, Media } from "@shared/schema";
+function SortableMediaItem({
+ media,
+ index,
+ isSelected,
+ onToggle
+}: {
+ media: Media;
+ index: number;
+ isSelected: boolean;
+ onToggle: () => void;
+}) {
+ const {
+ attributes,
+ listeners,
+ setNodeRef,
+ transform,
+ transition,
+ } = useSortable({ id: media.id });
+
+ const style = {
+ transform: CSS.Transform.toString(transform),
+ transition,
+ };
+
+ return (
+
+
+ {isSelected && (
+ <>
+
+ {index + 1}
+
+
+
+
+ >
+ )}
+
+ );
+}
+
export default function NewPost() {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [, navigate] = useLocation();
@@ -208,6 +288,25 @@ export default function NewPost() {
}
};
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ })
+ );
+
+ const handleDragEnd = (event: DragEndEvent) => {
+ const { active, over } = event;
+
+ if (over && active.id !== over.id) {
+ setSelectedMedia((items) => {
+ const oldIndex = items.indexOf(active.id as string);
+ const newIndex = items.indexOf(over.id as string);
+ return arrayMove(items, oldIndex, newIndex);
+ });
+ }
+ };
+
return (
{sidebarOpen && (
@@ -309,50 +408,90 @@ export default function NewPost() {
) : (
-
- {mediaList.map((media) => {
- const isSelected = selectedMedia.includes(media.id);
- const selectionIndex = selectedMedia.indexOf(media.id);
-
- return (
-