diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx index 74eb113..32b356d 100644 --- a/src/app/(auth)/login/page.tsx +++ b/src/app/(auth)/login/page.tsx @@ -6,25 +6,24 @@ import Typography from "@mui/material/Typography"; import Grid from "@mui/material/Grid"; import { UTILITY_CONSTANT } from "@/utilities/utilityConstant"; import Link from "next/link"; -import CustomizedInputsStyled from "@/ui/CustomizedInputsStyled"; import CustomizedButtons from "@/ui/customizedButtons"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useState } from "react"; import { loginApi } from "@/services/api/loginApi"; -import { FormControl } from "@mui/material"; import CustomTextField from "@/ui/CustomTextField"; import { useRouter } from "next/navigation"; -import { useDispatch, useSelector } from "react-redux"; -import { RootState } from "@/services/store"; +import { useDispatch } from "react-redux"; import { setAuthTokens, setUserDetails } from "@/services/store/authSlice"; import { routes } from "constant/route.constant"; import { grey } from "@mui/material/colors"; +import Snackbar, { SnackbarCloseReason } from '@mui/material/Snackbar'; const loginSchema = z.object({ username: z.string(), - password: z.string(), + password: z.string().min(6, { message: "Password is too short" }) + .max(20, { message: "Password is too long" }), }); type LoginFormValues = z.infer; @@ -33,7 +32,6 @@ export default function LoginPage() { const [loader, setLoader] = useState(false); const router = useRouter(); const { - register, handleSubmit, formState: { errors }, control, @@ -55,16 +53,37 @@ export default function LoginPage() { }) ); dispatch(setUserDetails(response)); + router.push(routes.PRODUCTS) setLoader(false); - router.push(routes.PRODUCTS); } catch (err) { setLoader(false); - setError("Invalid credentials"); + setError("Invalid username or password"); } }; + const handleClose = ( + _event: React.SyntheticEvent | Event, + reason?: SnackbarCloseReason, + ) => { + if (reason === 'clickaway') { + return; + } + setError(""); + }; return (
+ { - const [tableData, setTableData] = useState([]); +interface TanStackTableProps { + data: IProducts; +} +const TanStackTable = ({ data }: TanStackTableProps) => { + const [tableData, setTableData] = useState([]); const [open, setOpen] = useState(false); const [reviewModalData, setReviewModalData] = useState([]); const [sortOrder, setSortOrder] = useState<"asc" | "desc" | null>(null); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); - const handleSort = (key: string) => { + const handleSort = (key: keyof Product) => { let sortedData; if (sortOrder === "asc") { - sortedData = [...tableData].sort((a, b) => (a[key] > b[key] ? -1 : 1)); + sortedData = [...tableData.sort((a, b) => (a[key] && b[key] ? (a[key] > b[key] ? -1 : 1) : 0))]; setSortOrder("desc"); } else { - sortedData = [...tableData].sort((a, b) => (a[key] > b[key] ? 1 : -1)); + sortedData = [...tableData].sort((a, b) => (a[key] && b[key] ? (a[key] > b[key] ? 1 : -1) : 0)); setSortOrder("asc"); } setTableData(sortedData); @@ -56,16 +60,16 @@ const TanStackTable = ({ data }: any) => { { header: "Title", accessorKey: "title", + }, { header: "Description", accessorKey: "description", cell: ({ row }: any) => ( - <> - -

{row.original.description}

-
- + + +

{row.original.description}

+
), }, { @@ -128,7 +132,7 @@ const TanStackTable = ({ data }: any) => { }); useEffect(() => { - setTableData(data?.products); + setTableData(data.products); }, [data]); return ( @@ -136,9 +140,9 @@ const TanStackTable = ({ data }: any) => {
- {table.getHeaderGroups().map((headerGroup: any) => ( + {table.getHeaderGroups().map((headerGroup) => ( - {headerGroup.headers.map((header: any) => ( + {headerGroup.headers.map((header) => ( - {table.getRowModel().rows.map((row: any) => ( + {table.getRowModel().rows.map((row) => ( - {row.getVisibleCells().map((cell: any) => ( + {row.getVisibleCells().map((cell) => ( diff --git a/src/interface/login.interface.ts b/src/interface/login.interface.ts new file mode 100644 index 0000000..78e5d12 --- /dev/null +++ b/src/interface/login.interface.ts @@ -0,0 +1,16 @@ +export interface LoginResponse { + id: number; + username: string; + email: string; + firstName: string; + lastName: string; + gender: string; + image: string; + token: string; + refreshToken: string; +} + +export interface LoginData { + username: string; + password: string; +} diff --git a/src/interface/products.interface.ts b/src/interface/products.interface.ts new file mode 100644 index 0000000..2f08a10 --- /dev/null +++ b/src/interface/products.interface.ts @@ -0,0 +1,72 @@ +export interface IProducts { + products: Product[]; + total: number; + skip: number; + limit: number; +} + +export interface Product { + id: number; + title: string; + description: string; + category: Category; + price: number; + discountPercentage: number; + rating: number; + stock: number; + tags: string[]; + brand?: string; + sku: string; + weight: number; + dimensions: Dimensions; + warrantyInformation: string; + shippingInformation: string; + availabilityStatus: AvailabilityStatus; + reviews: Review[]; + returnPolicy: ReturnPolicy; + minimumOrderQuantity: number; + meta: Meta; + images: string[]; + thumbnail: string; +} + +export enum AvailabilityStatus { + InStock = 'In Stock', + LowStock = 'Low Stock', +} + +export enum Category { + Beauty = 'beauty', + Fragrances = 'fragrances', + Furniture = 'furniture', + Groceries = 'groceries', +} + +export interface Dimensions { + width: number; + height: number; + depth: number; +} + +export interface Meta { + createdAt: Date; + updatedAt: Date; + barcode: string; + qrCode: string; +} + +export enum ReturnPolicy { + NoReturnPolicy = 'No return policy', + The30DaysReturnPolicy = '30 days return policy', + The60DaysReturnPolicy = '60 days return policy', + The7DaysReturnPolicy = '7 days return policy', + The90DaysReturnPolicy = '90 days return policy', +} + +export interface Review { + rating: number; + comment: string; + date: Date; + reviewerName: string; + reviewerEmail: string; +} diff --git a/src/services/api/loginApi.ts b/src/services/api/loginApi.ts index b686e6b..eb2d665 100644 --- a/src/services/api/loginApi.ts +++ b/src/services/api/loginApi.ts @@ -1,25 +1,9 @@ // api.ts -import axiosInstance from "../axios/axiosInstance"; - -export interface LoginResponse { - id: number; - username: string; - email: string; - firstName: string; - lastName: string; - gender: string; - image: string; - token: string; - refreshToken: string; -} - -interface LoginData { - username: string; - password: string; -} +import { LoginData, LoginResponse } from '@/interface/login.interface'; +import axiosInstance from '../axios/axiosInstance'; /** Login API POST */ export const loginApi = async (data: LoginData): Promise => { - const response = await axiosInstance.post("/auth/login", data); + const response = await axiosInstance.post('/auth/login', data); return response.data; };
{flexRender( header.column.columnDef.header, @@ -150,9 +154,9 @@ const TanStackTable = ({ data }: any) => { ))}
{flexRender(cell.column.columnDef.cell, cell.getContext())}