diff --git a/app/components/action/Draggable.vue b/app/components/action/Draggable.vue
new file mode 100644
index 0000000..83726e9
--- /dev/null
+++ b/app/components/action/Draggable.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/components/ui/musiccard/MusicCard.vue b/app/components/internal/musiccard/MusicCard.vue
similarity index 100%
rename from app/components/ui/musiccard/MusicCard.vue
rename to app/components/internal/musiccard/MusicCard.vue
diff --git a/app/pages/edit.vue b/app/pages/edit.vue
index e606e06..ad78dd5 100644
--- a/app/pages/edit.vue
+++ b/app/pages/edit.vue
@@ -2,9 +2,11 @@
import { Search } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { InputWithIcon } from '@/components/ui/input'
-import MusicCard from '@/components/ui/musiccard/MusicCard.vue'
import { Outline } from '@/components/ui/outline'
import { SidebarTrigger } from '@/components/ui/sidebar'
+import MusicCard from '~/components/internal/musiccard/MusicCard.vue'
+import { DnDOperations, useDroppable } from '@vue-dnd-kit/core'
+import Draggable from '~/components/action/Draggable.vue'
const searchValue = ref('')
@@ -66,6 +68,15 @@ const selectTrack = (trackId: number) => {
track.selected = track.id === trackId
})
}
+
+const { elementRef: tracksRef } = useDroppable({
+ data: {
+ source: tracks.value,
+ },
+ events: {
+ onDrop: DnDOperations.applyTransfer,
+ },
+});
@@ -88,9 +99,16 @@ const selectTrack = (trackId: number) => {
-
+
+
+
+
+
+
+
@@ -104,3 +122,25 @@ const selectTrack = (trackId: number) => {
+
+
diff --git a/app/plugins/vue-dnd-kit.client.ts b/app/plugins/vue-dnd-kit.client.ts
new file mode 100644
index 0000000..81d96fd
--- /dev/null
+++ b/app/plugins/vue-dnd-kit.client.ts
@@ -0,0 +1,6 @@
+// ~/plugins/vue-dnd-kit.client.ts
+import VueDnDKitPlugin from '@vue-dnd-kit/core';
+
+export default defineNuxtPlugin((nuxtApp) => {
+ nuxtApp.vueApp.use(VueDnDKitPlugin);
+});
diff --git a/bun.lock b/bun.lock
index d339ed5..d7e4c40 100644
--- a/bun.lock
+++ b/bun.lock
@@ -11,6 +11,7 @@
"@tailwindcss/vite": "^4.1.16",
"@tanstack/vue-query": "^5.90.7",
"@vee-validate/zod": "^4.15.1",
+ "@vue-dnd-kit/core": "^1.7.0",
"@vueuse/core": "^14.0.0",
"axios": "^1.13.2",
"class-variance-authority": "^0.7.1",
@@ -611,6 +612,8 @@
"@volar/source-map": ["@volar/source-map@2.4.23", "", {}, "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q=="],
+ "@vue-dnd-kit/core": ["@vue-dnd-kit/core@1.7.0", "", { "peerDependencies": { "@vueuse/core": "^13.1.0", "vue": "^3.5.13" } }, "sha512-6Otpo/9Fp/cX5EiUoN6XmIPtm/mOreAXi8clr9HgzVvDHD0sfkgVOFxCUiVbH46yAzr6KBU1Q1tjSWLBqua+5g=="],
+
"@vue-macros/common": ["@vue-macros/common@3.1.1", "", { "dependencies": { "@vue/compiler-sfc": "^3.5.22", "ast-kit": "^2.1.2", "local-pkg": "^1.1.2", "magic-string-ast": "^1.0.2", "unplugin-utils": "^0.3.0" }, "peerDependencies": { "vue": "^2.7.0 || ^3.2.25" }, "optionalPeers": ["vue"] }, "sha512-afW2DMjgCBVs33mWRlz7YsGHzoEEupnl0DK5ZTKsgziAlLh5syc5m+GM7eqeYrgiQpwMaVxa1fk73caCvPxyAw=="],
"@vue/babel-helper-vue-transform-on": ["@vue/babel-helper-vue-transform-on@1.5.0", "", {}, "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA=="],
diff --git a/package.json b/package.json
index 706a1f0..4f2a6b8 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@tailwindcss/vite": "^4.1.16",
"@tanstack/vue-query": "^5.90.7",
"@vee-validate/zod": "^4.15.1",
+ "@vue-dnd-kit/core": "^1.7.0",
"@vueuse/core": "^14.0.0",
"axios": "^1.13.2",
"class-variance-authority": "^0.7.1",