Skip to content

Commit

Permalink
improved error handling for root route
Browse files Browse the repository at this point in the history
  • Loading branch information
Meirbek-dev committed Dec 16, 2024
1 parent 60fcc02 commit b2b5d34
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 32 deletions.
30 changes: 24 additions & 6 deletions app/(root)/(routes)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,37 @@
'use client';

import { useEffect } from 'react';
import { useEffect, useCallback } from 'react';
import { useRouter } from 'next/navigation';

import { useStoreModal } from '@/hooks/use-store-modal';

// Компонент настройки магазина
const SetupPage = () => {
const onOpen = useStoreModal((state) => state.onOpen);
const isOpen = useStoreModal((state) => state.isOpen);
const router = useRouter();

// Используем селекторы из хука с мемоизацией
const { onOpen, isOpen } = useStoreModal(
useCallback(
(state) => ({
onOpen: state.onOpen,
isOpen: state.isOpen,
}),
[],
),
);

useEffect(() => {
if (!isOpen) {
onOpen();
try {
if (!isOpen) {
onOpen();
}
} catch (error) {
console.error('[SETUP_PAGE]', error);
}
}, [isOpen, onOpen]);

return null;
// Возвращаем пустой фрагмент вместо null для лучшей производительности
return <></>;
};

export default SetupPage;
49 changes: 36 additions & 13 deletions app/(root)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import { auth } from '@clerk/nextjs/server';
import { redirect } from 'next/navigation';
import { cache } from 'react';
import { z } from 'zod';

import prismadb from '@/lib/prismadb';
import { errorResponses } from '@/lib/error-responses';

// Кэширование запроса на получение магазина
const getStore = cache(async (userId: string) => {
return prismadb.store.findFirst({
where: { userId },
select: {
id: true,
name: true,
createdAt: true,
},
});
});

// Схема валидации для userId
const userIdSchema = z.string().min(1, 'ID пользователя обязателен');

export default async function SetupLayout({ children }: { children: React.ReactNode }) {
const { userId }: { userId: string | null } = await auth();
try {
const { userId } = await auth();

if (!userId) {
redirect('/sign-in');
}
// Валидация userId
const validationResult = userIdSchema.safeParse(userId);

const store = await prismadb.store.findFirst({
where: {
userId,
},
});
if (!validationResult.success) {
redirect('/sign-in');
}

if (store) {
redirect(`/${store.id}`);
}
// Используем кэшированную функцию для получения магазина
const store = await getStore(validationResult.data);

return <>{children}</>;
if (store) {
redirect(`/${store.id}`);
}

return <div className="min-h-screen">{children}</div>;
} catch (error) {
console.error('[SETUP_LAYOUT]', error);
redirect('/error');
}
}
12 changes: 4 additions & 8 deletions app/api/[storeId]/billboards/[billboardId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ const getBillboards = cache(async (storeId: string) => {

// Расширенная схема валидации для создания билборда
const billboardSchema = z.object({
label: z
.string()
.min(1, 'Укажите метку')
.max(100, 'Метка слишком длинная')
.trim(),
label: z.string().min(1, 'Укажите метку').max(100, 'Метка слишком длинная').trim(),
imageUrl: z
.string()
.url('Укажите корректный URL изображения')
Expand Down Expand Up @@ -108,9 +104,9 @@ export async function POST(request: Request, props: { params: Promise<{ storeId:
status: 201,
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0',
}
Pragma: 'no-cache',
Expires: '0',
},
});
} catch (error) {
console.error('[BILLBOARDS_POST]', error);
Expand Down
20 changes: 16 additions & 4 deletions app/api/[storeId]/sizes/[sizeId]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ export async function GET(request: Request, props: { params: Promise<{ sizeId: s
const params = await props.params;

if (!params.sizeId) {
return new NextResponse('Необходим идентификатор размера.', { status: 400 });
return new NextResponse('Необходим идентификатор размера.', {
status: 400,
});
}

const size = await prismadb.size.findUnique({
where: { id: params.sizeId },
select: { id: true, name: true, value: true, createdAt: true, updatedAt: true },
select: {
id: true,
name: true,
value: true,
createdAt: true,
updatedAt: true,
},
});

if (!size) {
Expand Down Expand Up @@ -50,7 +58,9 @@ export async function DELETE(
}

if (!params.sizeId) {
return new NextResponse('Необходим идентификатор размера.', { status: 400 });
return new NextResponse('Необходим идентификатор размера.', {
status: 400,
});
}

const size = await prismadb.$transaction(async (tx) => {
Expand Down Expand Up @@ -95,7 +105,9 @@ export async function PATCH(
}

if (!params.sizeId) {
return new NextResponse('Необходим идентификатор размера.', { status: 400 });
return new NextResponse('Необходим идентификатор размера.', {
status: 400,
});
}

// Валидация входных данных
Expand Down
4 changes: 3 additions & 1 deletion app/api/webhook/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ export async function POST(request: Request) {

// Validate session and metadata
if (!session?.metadata?.orderId) {
return new NextResponse('Missing order ID in session metadata', { status: 400 });
return new NextResponse('Missing order ID in session metadata', {
status: 400,
});
}

const orderId = session.metadata.orderId;
Expand Down

0 comments on commit b2b5d34

Please sign in to comment.