fix(frontend/backend): suppress unauth toast on init, fix admin-login DTO validation and RSC directives
Some checks failed
Deploy Canina / deploy (push) Failing after 29s

This commit is contained in:
parsa aghaei 2026-08-08 18:02:43 +03:30
parent acc662fce8
commit adbfa60343
6 changed files with 25 additions and 4 deletions

View File

@ -12,6 +12,8 @@ import {
ApiBadRequestResponse,
} from '@nestjs/swagger';
import { AdminLoginDto } from './dto/admin-login.dto';
@ApiTags('Auth - احراز هویت')
@Controller('auth')
@ApiResponse({
@ -124,7 +126,7 @@ export class AuthController {
@ApiOperation({ summary: 'ورود ادمین به پنل مدیریت' })
@ApiOkResponse({ description: 'ورود موفق ادمین به همراه توکن' })
@ApiBadRequestResponse({ description: 'اطلاعات ورود ادمین اشتباه است' })
adminLogin(@Body() body: AdminLoginInput) {
adminLogin(@Body() body: AdminLoginDto) {
return this.authService.adminLogin(body);
}
}

View File

@ -0,0 +1,15 @@
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
export class AdminLoginDto {
@ApiProperty({ description: 'ایمیل ادمین', example: 'admin@canina-iran.com' })
@IsEmail({}, { message: 'فرمت ایمیل وارد شده معتبر نمی‌باشد.' })
@IsNotEmpty({ message: 'ایمیل الزامی است.' })
email!: string;
@ApiProperty({ description: 'رمز عبور ادمین', example: 'admin123' })
@IsString({ message: 'رمز عبور باید رشته متنی باشد.' })
@MinLength(6, { message: 'رمز عبور باید حداقل ۶ کاراکتر باشد.' })
@IsNotEmpty({ message: 'رمز عبور الزامی است.' })
password!: string;
}

View File

@ -1,3 +1,5 @@
"use client";
import { useEffect } from "react";
import Header from "../components/Header";
import Footer from "../components/Footer";

View File

@ -1,3 +1,5 @@
"use client";
import React, { useState, useRef, useEffect } from "react";
import { Search, ChevronDown, Menu, X, Pill, ShieldCheck, HeartPulse, Sparkles, ShoppingBag, User, Check, Building2, LogIn, LogOut, FileHeart, Dog, BookOpen, FileText, Video, Award, PhoneCall, Activity } from "lucide-react";
import { motion, AnimatePresence } from "motion/react";

View File

@ -78,8 +78,8 @@ api.interceptors.response.use(
}
}
// Show formatted Farsi toast if not explicitly suppressed and not 404
if (!error.config?.hideErrorToast && status !== 404) {
// Show formatted Farsi toast if not explicitly suppressed and not 401/403/404
if (!error.config?.hideErrorToast && status !== 401 && status !== 403 && status !== 404) {
if (responseData?.details && Array.isArray(responseData.details) && responseData.details.length > 0) {
const firstDetailMessage = responseData.details[0]?.message || farsiMessage;
toast.error(firstDetailMessage);

View File

@ -117,7 +117,7 @@ export class AuthService {
*/
public async getProfile(): Promise<User | null> {
try {
const response = await api.get('/users/profile');
const response = await api.get('/users/profile', { hideErrorToast: true } as unknown as import('axios').AxiosRequestConfig);
return response.data;
} catch (error) {
const err = error as ApiErr;