diff --git a/apps/client/src/pages/builder/sidebars/left/dialogs/custom-section.tsx b/apps/client/src/pages/builder/sidebars/left/dialogs/custom-section.tsx index 0ac077eb..0e4d8947 100644 --- a/apps/client/src/pages/builder/sidebars/left/dialogs/custom-section.tsx +++ b/apps/client/src/pages/builder/sidebars/left/dialogs/custom-section.tsx @@ -30,6 +30,10 @@ const formSchema = customSectionSchema; type FormValues = z.infer; +const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); +}; + export const CustomSectionDialog = () => { const { payload } = useDialog("custom"); @@ -40,6 +44,24 @@ export const CustomSectionDialog = () => { const [pendingKeyword, setPendingKeyword] = useState(""); + const [draggedIndex, setDraggedIndex] = useState(null); + + const handleDrop = ( + e: React.DragEvent, + dropIndex: number, + field: { value: string[]; onChange: (value: string[]) => void }, + ) => { + e.preventDefault(); + if (draggedIndex === null) return; + + const newKeywords = [...field.value]; + const [draggedItem] = newKeywords.splice(draggedIndex, 1); + newKeywords.splice(dropIndex, 0, draggedItem); + + field.onChange(newKeywords); + setDraggedIndex(null); + }; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!payload) return null; @@ -172,9 +194,17 @@ export const CustomSectionDialog = () => { { + setDraggedIndex(index); + }} + onDragOver={handleDragOver} + onDrop={(e) => { + handleDrop(e, index, field); + }} > ; +const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); +}; + export const InterestsDialog = () => { const form = useForm({ defaultValues: defaultInterest, @@ -31,6 +35,23 @@ export const InterestsDialog = () => { }); const [pendingKeyword, setPendingKeyword] = useState(""); + const [draggedIndex, setDraggedIndex] = useState(null); + + const handleDrop = ( + e: React.DragEvent, + dropIndex: number, + field: { value: string[]; onChange: (value: string[]) => void }, + ) => { + e.preventDefault(); + if (draggedIndex === null) return; + + const newKeywords = [...field.value]; + const [draggedItem] = newKeywords.splice(draggedIndex, 1); + newKeywords.splice(dropIndex, 0, draggedItem); + + field.onChange(newKeywords); + setDraggedIndex(null); + }; return ( @@ -76,9 +97,17 @@ export const InterestsDialog = () => { { + setDraggedIndex(index); + }} + onDragOver={handleDragOver} + onDrop={(e) => { + handleDrop(e, index, field); + }} > ; +const handleDragOver = (e: React.DragEvent) => { + e.preventDefault(); +}; + export const SkillsDialog = () => { const form = useForm({ defaultValues: defaultSkill, @@ -32,6 +36,23 @@ export const SkillsDialog = () => { }); const [pendingKeyword, setPendingKeyword] = useState(""); + const [draggedIndex, setDraggedIndex] = useState(null); + + const handleDrop = ( + e: React.DragEvent, + dropIndex: number, + field: { value: string[]; onChange: (value: string[]) => void }, + ) => { + e.preventDefault(); + if (draggedIndex === null) return; + + const newKeywords = [...field.value]; + const [draggedItem] = newKeywords.splice(draggedIndex, 1); + newKeywords.splice(dropIndex, 0, draggedItem); + + field.onChange(newKeywords); + setDraggedIndex(null); + }; return ( @@ -122,9 +143,17 @@ export const SkillsDialog = () => { { + setDraggedIndex(index); + }} + onDragOver={handleDragOver} + onDrop={(e) => { + handleDrop(e, index, field); + }} >