릴리스: v1.3.53 관리자 featured/custom item 로직 분리
This commit is contained in:
93
frontend/src/composables/useAdminFeaturedGames.js
Normal file
93
frontend/src/composables/useAdminFeaturedGames.js
Normal file
@@ -0,0 +1,93 @@
|
||||
import { nextTick } from 'vue'
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export function useAdminFeaturedGames({
|
||||
api,
|
||||
featuredListEl,
|
||||
featuredSortable,
|
||||
featuredGameIds,
|
||||
games,
|
||||
resetMessages,
|
||||
success,
|
||||
error,
|
||||
}) {
|
||||
function destroyFeaturedSortable() {
|
||||
if (featuredSortable.value) {
|
||||
featuredSortable.value.destroy()
|
||||
featuredSortable.value = null
|
||||
}
|
||||
}
|
||||
|
||||
async function syncFeaturedSortable() {
|
||||
await nextTick()
|
||||
destroyFeaturedSortable()
|
||||
if (!featuredListEl.value) return
|
||||
|
||||
featuredSortable.value = Sortable.create(featuredListEl.value, {
|
||||
animation: 160,
|
||||
draggable: '[data-featured-id]',
|
||||
handle: '[data-featured-handle]',
|
||||
ghostClass: 'ghost',
|
||||
chosenClass: 'chosen',
|
||||
onEnd: (evt) => {
|
||||
if (evt.oldIndex == null || evt.newIndex == null || evt.oldIndex === evt.newIndex) return
|
||||
const nextIds = [...featuredGameIds.value]
|
||||
const [moved] = nextIds.splice(evt.oldIndex, 1)
|
||||
nextIds.splice(evt.newIndex, 0, moved)
|
||||
featuredGameIds.value = nextIds
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function addFeaturedGame(gameId) {
|
||||
resetMessages()
|
||||
if (!gameId || featuredGameIds.value.includes(gameId)) return
|
||||
if (featuredGameIds.value.length >= 50) {
|
||||
error.value = '상단 고정 게임은 최대 50개까지만 설정할 수 있어요.'
|
||||
return
|
||||
}
|
||||
featuredGameIds.value = [...featuredGameIds.value, gameId]
|
||||
syncFeaturedSortable()
|
||||
}
|
||||
|
||||
function removeFeaturedGame(gameId) {
|
||||
resetMessages()
|
||||
featuredGameIds.value = featuredGameIds.value.filter((id) => id !== gameId)
|
||||
syncFeaturedSortable()
|
||||
}
|
||||
|
||||
function moveFeaturedGame(gameId, direction) {
|
||||
const currentIndex = featuredGameIds.value.indexOf(gameId)
|
||||
const nextIndex = currentIndex + direction
|
||||
if (currentIndex < 0 || nextIndex < 0 || nextIndex >= featuredGameIds.value.length) return
|
||||
const nextIds = [...featuredGameIds.value]
|
||||
const [moved] = nextIds.splice(currentIndex, 1)
|
||||
nextIds.splice(nextIndex, 0, moved)
|
||||
featuredGameIds.value = nextIds
|
||||
syncFeaturedSortable()
|
||||
}
|
||||
|
||||
async function saveFeaturedOrder() {
|
||||
resetMessages()
|
||||
try {
|
||||
const data = await api.updateAdminGameDisplayOrder({ gameIds: featuredGameIds.value })
|
||||
games.value = data.games || []
|
||||
featuredGameIds.value = games.value
|
||||
.filter((game) => game.displayRank != null)
|
||||
.sort((a, b) => a.displayRank - b.displayRank)
|
||||
.map((game) => game.id)
|
||||
success.value = '홈 화면 게임 순서를 저장했어요.'
|
||||
} catch (e) {
|
||||
error.value = '게임 순서 저장에 실패했어요.'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
destroyFeaturedSortable,
|
||||
syncFeaturedSortable,
|
||||
addFeaturedGame,
|
||||
removeFeaturedGame,
|
||||
moveFeaturedGame,
|
||||
saveFeaturedOrder,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user