- 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>
104 lines
3.6 KiB
TypeScript
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)
|
|
}
|