- 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>
105 lines
3.6 KiB
TypeScript
105 lines
3.6 KiB
TypeScript
import type { Prop } from "./types"
|
|
import { apiClient } from "./client"
|
|
import type { PaginatedResponse, PaginationParams } from "./client"
|
|
|
|
function mapBackendProp(item: any): Prop {
|
|
const attrs = item.attributes || {}
|
|
return {
|
|
id: String(item.id),
|
|
name: item.name,
|
|
description: item.description || "",
|
|
imageUrl: item.image_url || "/placeholder.svg?height=300&width=400",
|
|
rarity: item.rarity_display || item.rarity || "",
|
|
category: attrs.prop_type || "",
|
|
status: item.status_display || item.status || "",
|
|
publishedAt: item.published_at || "",
|
|
batchesCount: item.batches_count || 0,
|
|
activeCardsCount: item.active_cards_count || 0,
|
|
tags: attrs.material ? [attrs.material] : [],
|
|
createdAt: item.created_at || "",
|
|
updatedAt: item.updated_at || "",
|
|
}
|
|
}
|
|
|
|
export const getProps = async (params?: PaginationParams): Promise<PaginatedResponse<Prop>> => {
|
|
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/prop/?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(mapBackendProp),
|
|
total,
|
|
page,
|
|
pageSize,
|
|
totalPages: Math.ceil(total / pageSize),
|
|
}
|
|
}
|
|
|
|
export const getProp = async (id: string): Promise<Prop> => {
|
|
const response = await apiClient.get(`/card/templates/${id}/`)
|
|
const data = response.data?.data || response.data
|
|
return mapBackendProp(data)
|
|
}
|
|
|
|
export const createProp = async (propData: Partial<Prop> & { rarityValue?: string }): Promise<Prop> => {
|
|
const payload: any = {
|
|
name: propData.name,
|
|
category: "prop",
|
|
description: propData.description || "",
|
|
}
|
|
if (propData.rarityValue) {
|
|
payload.rarity = propData.rarityValue
|
|
}
|
|
if (propData.imageUrl) {
|
|
payload.image_url = propData.imageUrl
|
|
}
|
|
// 只在有实际属性值时才传 prop_attributes
|
|
if (propData.category) {
|
|
payload.prop_attributes = {
|
|
prop_type: propData.category,
|
|
}
|
|
}
|
|
|
|
const response = await apiClient.post(`/card/templates/`, payload)
|
|
const data = response.data?.data || response.data
|
|
return mapBackendProp(data)
|
|
}
|
|
|
|
export const updateProp = async (id: string, propData: Partial<Prop> & { rarityValue?: string }): Promise<Prop> => {
|
|
const payload: any = {}
|
|
if (propData.name !== undefined) payload.name = propData.name
|
|
if (propData.description !== undefined) payload.description = propData.description
|
|
if (propData.category !== undefined) payload.prop_attributes = { prop_type: propData.category }
|
|
if (propData.rarityValue) payload.rarity = propData.rarityValue
|
|
if (propData.imageUrl !== undefined) payload.image_url = propData.imageUrl
|
|
|
|
const response = await apiClient.patch(`/card/templates/${id}/`, payload)
|
|
const data = response.data?.data || response.data
|
|
return mapBackendProp(data)
|
|
}
|
|
|
|
export const deleteProp = async (id: string): Promise<boolean> => {
|
|
await apiClient.delete(`/card/templates/${id}/`)
|
|
return true
|
|
}
|
|
|
|
export const publishProp = async (id: string): Promise<Prop> => {
|
|
const response = await apiClient.post(`/card/templates/${id}/publish/`)
|
|
const data = response.data?.template || response.data
|
|
return mapBackendProp(data)
|
|
}
|
|
|
|
export const archiveProp = async (id: string): Promise<Prop> => {
|
|
const response = await apiClient.post(`/card/templates/${id}/archive/`)
|
|
const data = response.data?.template || response.data
|
|
return mapBackendProp(data)
|
|
}
|