lty/qy-lty-admin/lib/api/outfits.ts
pmc bd95ba470c feat: update admin panel, API modules, and add migrations
- Update food, outfits, props, home-decor pages and components
- Add permissions page and sidebar updates
- Update API client and all API modules (auth, food, dances, etc.)
- Add card model migrations for optional fields
- Update Django views, serializers, and authentication
- Add affinity level migrations and user app updates
- Add project documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:06:50 +08:00

104 lines
3.6 KiB
TypeScript

import type { Outfit } from "./types"
import { apiClient } from "./client"
import type { PaginatedResponse, PaginationParams } from "./client"
function mapBackendOutfit(item: any): Outfit {
const attrs = item.attributes || {}
return {
id: String(item.id),
name: item.name,
description: item.description || "",
imageUrl: item.image_url || "",
rarity: item.rarity_display || item.rarity || "",
category: attrs.style || item.card_type_display || "",
status: item.status_display || item.status || "",
publishedAt: item.published_at || "",
batchesCount: item.batches_count || 0,
activeCardsCount: item.active_cards_count || 0,
tags: attrs.season ? [attrs.season] : [],
createdAt: item.created_at || "",
updatedAt: item.updated_at || "",
}
}
export const getOutfits = async (params?: PaginationParams): Promise<PaginatedResponse<Outfit>> => {
const page = params?.page || 1
const pageSize = params?.pageSize || 10
const searchParam = params?.search ? `&search=${encodeURIComponent(params.search)}` : ""
const response = await apiClient.get(
`/card/category/clothing/?page=${page}&page_size=${pageSize}${searchParam}`
)
const data = response.data?.data || response.data
const results: any[] = data.results || data
const total = data.count || results.length
return {
items: results.map(mapBackendOutfit),
total,
page,
pageSize,
totalPages: Math.ceil(total / pageSize),
}
}
export const getOutfit = async (id: string): Promise<Outfit> => {
const response = await apiClient.get(`/card/templates/${id}/`)
const data = response.data?.data || response.data
return mapBackendOutfit(data)
}
export const createOutfit = async (outfitData: Partial<Outfit> & { rarityValue?: string }): Promise<Outfit> => {
const payload: any = {
name: outfitData.name,
category: "clothing",
description: outfitData.description || "",
}
if (outfitData.rarityValue) {
payload.rarity = outfitData.rarityValue
}
if (outfitData.imageUrl) {
payload.image_url = outfitData.imageUrl
}
if (outfitData.category) {
payload.clothing_attributes = {
style: outfitData.category,
}
}
const response = await apiClient.post(`/card/templates/`, payload)
const data = response.data?.data || response.data
return mapBackendOutfit(data)
}
export const updateOutfit = async (id: string, outfitData: Partial<Outfit> & { rarityValue?: string }): Promise<Outfit> => {
const payload: any = {}
if (outfitData.name !== undefined) payload.name = outfitData.name
if (outfitData.description !== undefined) payload.description = outfitData.description
if (outfitData.category !== undefined) payload.clothing_attributes = { style: outfitData.category }
if (outfitData.rarityValue) payload.rarity = outfitData.rarityValue
if (outfitData.imageUrl !== undefined) payload.image_url = outfitData.imageUrl
const response = await apiClient.patch(`/card/templates/${id}/`, payload)
const data = response.data?.data || response.data
return mapBackendOutfit(data)
}
export const deleteOutfit = async (id: string): Promise<boolean> => {
await apiClient.delete(`/card/templates/${id}/`)
return true
}
export const publishOutfit = async (id: string): Promise<Outfit> => {
const response = await apiClient.post(`/card/templates/${id}/publish/`)
const data = response.data?.template || response.data
return mapBackendOutfit(data)
}
export const archiveOutfit = async (id: string): Promise<Outfit> => {
const response = await apiClient.post(`/card/templates/${id}/archive/`)
const data = response.data?.template || response.data
return mapBackendOutfit(data)
}