feat: implement market page with QueryProvider and dynamic listings
- wrap root layout with QueryProvider for React Query - replace market UnderConstruction placeholder with MarketClient and real data fetching - implement search, pagination, and sort via search params using getActiveListings - add necessary client components and queries - update dependencies (e.g., prisma, pkg-types)
This commit is contained in:
1 parent
55eebde0ba
commit
ab37b477df
106 files changed
+15261
-301
No files matched your search
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* Queries de personagens usando Prisma
|
||||
* Migrado de lib/db/queries/characters.ts
|
||||
*/
|
||||
|
||||
import { prisma } from "../app";
|
||||
|
||||
export interface Character {
|
||||
character_id: number;
|
||||
user_id: number;
|
||||
character_name: string;
|
||||
server_name: string;
|
||||
is_main: boolean;
|
||||
verified: boolean;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
export interface CreateCharacterData {
|
||||
character_name: string;
|
||||
server_name: string;
|
||||
is_main?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateCharacterData {
|
||||
character_name?: string;
|
||||
server_name?: string;
|
||||
is_main?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cria um novo personagem
|
||||
* Se isMain=true, desmarca outros personagens como main
|
||||
*/
|
||||
export async function createCharacter(
|
||||
userId: number,
|
||||
data: CreateCharacterData
|
||||
): Promise<Character> {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// Se este personagem será main, desmarcar outros
|
||||
if (data.is_main) {
|
||||
await tx.userCharacter.updateMany({
|
||||
where: { user_id: userId },
|
||||
data: { is_main: false },
|
||||
});
|
||||
}
|
||||
|
||||
// Inserir novo personagem
|
||||
return await tx.userCharacter.create({
|
||||
data: {
|
||||
user_id: userId,
|
||||
character_name: data.character_name,
|
||||
server_name: data.server_name,
|
||||
is_main: data.is_main || false,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Lista todos os personagens de um usuário
|
||||
*/
|
||||
export async function getUserCharacters(userId: number): Promise<Character[]> {
|
||||
return await prisma.userCharacter.findMany({
|
||||
where: { user_id: userId },
|
||||
orderBy: [
|
||||
{ is_main: "desc" },
|
||||
{ created_at: "asc" },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca personagem principal de um usuário em um servidor específico
|
||||
*/
|
||||
export async function getMainCharacterByUserId(
|
||||
userId: number,
|
||||
serverName: string
|
||||
): Promise<Character | null> {
|
||||
return await prisma.userCharacter.findFirst({
|
||||
where: {
|
||||
user_id: userId,
|
||||
server_name: serverName,
|
||||
},
|
||||
orderBy: [
|
||||
{ is_main: "desc" },
|
||||
{ created_at: "asc" },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca personagem por ID
|
||||
*/
|
||||
export async function getCharacterById(
|
||||
characterId: number
|
||||
): Promise<Character | null> {
|
||||
return await prisma.userCharacter.findUnique({
|
||||
where: { character_id: characterId },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza personagem
|
||||
* Verifica ownership e se isMain=true, desmarca outros
|
||||
*/
|
||||
export async function updateCharacter(
|
||||
characterId: number,
|
||||
userId: number,
|
||||
data: UpdateCharacterData
|
||||
): Promise<Character> {
|
||||
// Verificar ownership primeiro
|
||||
const existing = await getCharacterById(characterId);
|
||||
if (!existing) {
|
||||
throw new Error("Personagem não encontrado");
|
||||
}
|
||||
|
||||
if (existing.user_id !== userId) {
|
||||
throw new Error("Você não tem permissão para atualizar este personagem");
|
||||
}
|
||||
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
// Se este personagem será main, desmarcar outros
|
||||
if (data.is_main) {
|
||||
await tx.userCharacter.updateMany({
|
||||
where: {
|
||||
user_id: userId,
|
||||
character_id: { not: characterId },
|
||||
},
|
||||
data: { is_main: false },
|
||||
});
|
||||
}
|
||||
|
||||
// Atualizar personagem
|
||||
const updateData: any = {};
|
||||
if (data.character_name !== undefined) updateData.character_name = data.character_name;
|
||||
if (data.server_name !== undefined) updateData.server_name = data.server_name;
|
||||
if (data.is_main !== undefined) updateData.is_main = data.is_main;
|
||||
|
||||
if (Object.keys(updateData).length === 0) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
return await tx.userCharacter.update({
|
||||
where: { character_id: characterId },
|
||||
data: updateData,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove personagem
|
||||
* Verifica ownership antes de remover
|
||||
*/
|
||||
export async function deleteCharacter(
|
||||
characterId: number,
|
||||
userId: number
|
||||
): Promise<void> {
|
||||
// Verificar ownership
|
||||
const existing = await getCharacterById(characterId);
|
||||
if (!existing) {
|
||||
throw new Error("Personagem não encontrado");
|
||||
}
|
||||
|
||||
if (existing.user_id !== userId) {
|
||||
throw new Error("Você não tem permissão para remover este personagem");
|
||||
}
|
||||
|
||||
await prisma.userCharacter.delete({
|
||||
where: { character_id: characterId },
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user