@@ -20,4 +20,4 @@ const BestSelling = () => {
)
}
-export default BestSelling
\ No newline at end of file
+export default BestSelling
diff --git a/components/CategoriesMarquee.jsx b/src/components/CategoriesMarquee.tsx
similarity index 95%
rename from components/CategoriesMarquee.jsx
rename to src/components/CategoriesMarquee.tsx
index d2c45402..bc95a417 100644
--- a/components/CategoriesMarquee.jsx
+++ b/src/components/CategoriesMarquee.tsx
@@ -1,4 +1,4 @@
-import { categories } from "@/assets/assets";
+import { categories } from "@/src/assets/assets";
const CategoriesMarquee = () => {
diff --git a/components/Counter.jsx b/src/components/Counter.tsx
similarity index 64%
rename from components/Counter.jsx
rename to src/components/Counter.tsx
index 20124268..dd2e4d59 100644
--- a/components/Counter.jsx
+++ b/src/components/Counter.tsx
@@ -1,12 +1,12 @@
'use client'
-import { addToCart, removeFromCart } from "@/lib/features/cart/cartSlice";
-import { useDispatch, useSelector } from "react-redux";
+import { addToCart, removeFromCart } from "@/src/lib/features/cart/cartSlice";
+import { useAppDispatch, useAppSelector } from "@/src/lib/hooks";
-const Counter = ({ productId }) => {
+const Counter = ({ productId }: { productId: string }) => {
- const { cartItems } = useSelector(state => state.cart);
+ const { cartItems } = useAppSelector(state => state.cart);
- const dispatch = useDispatch();
+ const dispatch = useAppDispatch();
const addToCartHandler = () => {
dispatch(addToCart({ productId }))
@@ -25,4 +25,4 @@ const Counter = ({ productId }) => {
)
}
-export default Counter
\ No newline at end of file
+export default Counter
diff --git a/components/Footer.jsx b/src/components/Footer.tsx
similarity index 100%
rename from components/Footer.jsx
rename to src/components/Footer.tsx
diff --git a/components/Hero.jsx b/src/components/Hero.tsx
similarity index 98%
rename from components/Hero.jsx
rename to src/components/Hero.tsx
index abcc2bbc..36a99c06 100644
--- a/components/Hero.jsx
+++ b/src/components/Hero.tsx
@@ -1,5 +1,5 @@
'use client'
-import { assets } from '@/assets/assets'
+import { assets } from '@/src/assets/assets'
import { ArrowRightIcon, ChevronRightIcon } from 'lucide-react'
import Image from 'next/image'
import React from 'react'
diff --git a/components/LatestProducts.jsx b/src/components/LatestProducts.tsx
similarity index 73%
rename from components/LatestProducts.jsx
rename to src/components/LatestProducts.tsx
index fc67c72c..9d4cb4ca 100644
--- a/components/LatestProducts.jsx
+++ b/src/components/LatestProducts.tsx
@@ -1,19 +1,18 @@
'use client'
-import React from 'react'
import Title from './Title'
import ProductCard from './ProductCard'
-import { useSelector } from 'react-redux'
+import { useAppSelector } from '@/src/lib/hooks'
const LatestProducts = () => {
const displayQuantity = 4
- const products = useSelector(state => state.product.list)
+ const products = useAppSelector(state => state.product.list)
return (
- {products.slice().sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)).slice(0, displayQuantity).map((product, index) => (
+ {products.slice().sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, displayQuantity).map((product, index) => (
))}
@@ -21,4 +20,4 @@ const LatestProducts = () => {
)
}
-export default LatestProducts
\ No newline at end of file
+export default LatestProducts
diff --git a/components/Loading.jsx b/src/components/Loading.tsx
similarity index 100%
rename from components/Loading.jsx
rename to src/components/Loading.tsx
diff --git a/components/Navbar.jsx b/src/components/Navbar.tsx
similarity index 95%
rename from components/Navbar.jsx
rename to src/components/Navbar.tsx
index d7fb5c82..700d3bb2 100644
--- a/components/Navbar.jsx
+++ b/src/components/Navbar.tsx
@@ -3,14 +3,14 @@ import { Search, ShoppingCart } from "lucide-react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
-import { useSelector } from "react-redux";
+import { useAppSelector } from "@/src/lib/hooks";
const Navbar = () => {
const router = useRouter();
const [search, setSearch] = useState('')
- const cartCount = useSelector(state => state.cart.total)
+ const cartCount = useAppSelector(state => state.cart.total)
const handleSearch = (e) => {
e.preventDefault()
@@ -66,4 +66,4 @@ const Navbar = () => {
)
}
-export default Navbar
\ No newline at end of file
+export default Navbar
diff --git a/components/Newsletter.jsx b/src/components/Newsletter.tsx
similarity index 96%
rename from components/Newsletter.jsx
rename to src/components/Newsletter.tsx
index a9399b85..fe1302ec 100644
--- a/components/Newsletter.jsx
+++ b/src/components/Newsletter.tsx
@@ -1,4 +1,3 @@
-import React from 'react'
import Title from './Title'
const Newsletter = () => {
diff --git a/components/OrderItem.jsx b/src/components/OrderItem.tsx
similarity index 97%
rename from components/OrderItem.jsx
rename to src/components/OrderItem.tsx
index 29b68410..aaef2ca3 100644
--- a/components/OrderItem.jsx
+++ b/src/components/OrderItem.tsx
@@ -1,7 +1,7 @@
'use client'
import Image from "next/image";
import { DotIcon } from "lucide-react";
-import { useSelector } from "react-redux";
+import { useAppSelector } from "@/src/lib/hooks";
import Rating from "./Rating";
import { useState } from "react";
import RatingModal from "./RatingModal";
@@ -11,7 +11,7 @@ const OrderItem = ({ order }) => {
const currency = process.env.NEXT_PUBLIC_CURRENCY_SYMBOL || '$';
const [ratingModal, setRatingModal] = useState(null);
- const { ratings } = useSelector(state => state.rating);
+ const { ratings } = useAppSelector(state => state.rating);
return (
<>
@@ -90,4 +90,4 @@ const OrderItem = ({ order }) => {
)
}
-export default OrderItem
\ No newline at end of file
+export default OrderItem
diff --git a/components/OrderSummary.jsx b/src/components/OrderSummary.tsx
similarity index 93%
rename from components/OrderSummary.jsx
rename to src/components/OrderSummary.tsx
index af01f853..abfcc1fe 100644
--- a/components/OrderSummary.jsx
+++ b/src/components/OrderSummary.tsx
@@ -1,9 +1,12 @@
import { PlusIcon, SquarePenIcon, XIcon } from 'lucide-react';
-import React, { useState } from 'react'
+import { useState } from 'react'
import AddressModal from './AddressModal';
-import { useSelector } from 'react-redux';
+import { useAppSelector } from '@/src/lib/hooks';
import toast from 'react-hot-toast';
import { useRouter } from 'next/navigation';
+import { couponDummyData } from '@/src/assets/assets';
+
+type Coupon = (typeof couponDummyData)[number]
const OrderSummary = ({ totalPrice, items }) => {
@@ -11,13 +14,13 @@ const OrderSummary = ({ totalPrice, items }) => {
const router = useRouter();
- const addressList = useSelector(state => state.address.list);
+ const addressList = useAppSelector(state => state.address.list);
const [paymentMethod, setPaymentMethod] = useState('COD');
const [selectedAddress, setSelectedAddress] = useState(null);
const [showAddressModal, setShowAddressModal] = useState(false);
const [couponCodeInput, setCouponCodeInput] = useState('');
- const [coupon, setCoupon] = useState('');
+ const [coupon, setCoupon] = useState
(null);
const handleCouponCode = async (event) => {
event.preventDefault();
@@ -92,7 +95,7 @@ const OrderSummary = ({ totalPrice, items }) => {
Code: {coupon.code.toUpperCase()}
{coupon.description}
-
setCoupon('')} className='hover:text-red-700 transition cursor-pointer' />
+ setCoupon(null)} className='hover:text-red-700 transition cursor-pointer' />
)
}
@@ -109,4 +112,4 @@ const OrderSummary = ({ totalPrice, items }) => {
)
}
-export default OrderSummary
\ No newline at end of file
+export default OrderSummary
diff --git a/components/OrdersAreaChart.jsx b/src/components/OrdersAreaChart.tsx
similarity index 100%
rename from components/OrdersAreaChart.jsx
rename to src/components/OrdersAreaChart.tsx
diff --git a/components/OurSpec.jsx b/src/components/OurSpec.tsx
similarity index 95%
rename from components/OurSpec.jsx
rename to src/components/OurSpec.tsx
index f5a3acb5..45244b5d 100644
--- a/components/OurSpec.jsx
+++ b/src/components/OurSpec.tsx
@@ -1,6 +1,5 @@
-import React from 'react'
import Title from './Title'
-import { ourSpecsData } from '@/assets/assets'
+import { ourSpecsData } from '@/src/assets/assets'
const OurSpecs = () => {
diff --git a/components/PageTitle.jsx b/src/components/PageTitle.tsx
similarity index 100%
rename from components/PageTitle.jsx
rename to src/components/PageTitle.tsx
diff --git a/components/ProductCard.jsx b/src/components/ProductCard.tsx
similarity index 98%
rename from components/ProductCard.jsx
rename to src/components/ProductCard.tsx
index 69b7501f..f4245452 100644
--- a/components/ProductCard.jsx
+++ b/src/components/ProductCard.tsx
@@ -2,7 +2,6 @@
import { StarIcon } from 'lucide-react'
import Image from 'next/image'
import Link from 'next/link'
-import React from 'react'
const ProductCard = ({ product }) => {
diff --git a/components/ProductDescription.jsx b/src/components/ProductDescription.tsx
similarity index 100%
rename from components/ProductDescription.jsx
rename to src/components/ProductDescription.tsx
diff --git a/components/ProductDetails.jsx b/src/components/ProductDetails.tsx
similarity index 90%
rename from components/ProductDetails.jsx
rename to src/components/ProductDetails.tsx
index 28dd6995..d2989cc0 100644
--- a/components/ProductDetails.jsx
+++ b/src/components/ProductDetails.tsx
@@ -1,20 +1,21 @@
'use client'
-import { addToCart } from "@/lib/features/cart/cartSlice";
+import { addToCart } from "@/src/lib/features/cart/cartSlice";
import { StarIcon, TagIcon, EarthIcon, CreditCardIcon, UserIcon } from "lucide-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import Image from "next/image";
import Counter from "./Counter";
-import { useDispatch, useSelector } from "react-redux";
+import { useAppDispatch, useAppSelector } from "@/src/lib/hooks";
+import type { Product } from "@/src/lib/features/product/productSlice";
-const ProductDetails = ({ product }) => {
+const ProductDetails = ({ product }: { product: Product }) => {
const productId = product.id;
const currency = process.env.NEXT_PUBLIC_CURRENCY_SYMBOL || '$';
- const cart = useSelector(state => state.cart.cartItems);
- const dispatch = useDispatch();
+ const cart = useAppSelector(state => state.cart.cartItems);
+ const dispatch = useAppDispatch();
const router = useRouter()
@@ -81,4 +82,4 @@ const ProductDetails = ({ product }) => {
)
}
-export default ProductDetails
\ No newline at end of file
+export default ProductDetails
diff --git a/components/Rating.jsx b/src/components/Rating.tsx
similarity index 94%
rename from components/Rating.jsx
rename to src/components/Rating.tsx
index 9ce03313..dc98de10 100644
--- a/components/Rating.jsx
+++ b/src/components/Rating.tsx
@@ -1,5 +1,4 @@
import { Star } from "lucide-react";
-import React from "react";
const Rating = ({ value = 4 }) => {
diff --git a/components/RatingModal.jsx b/src/components/RatingModal.tsx
similarity index 95%
rename from components/RatingModal.jsx
rename to src/components/RatingModal.tsx
index 3fce715f..4d6e787f 100644
--- a/components/RatingModal.jsx
+++ b/src/components/RatingModal.tsx
@@ -1,7 +1,7 @@
'use client'
import { Star } from 'lucide-react';
-import React, { useState } from 'react'
+import { useState } from 'react'
import { XIcon } from 'lucide-react';
import toast from 'react-hot-toast';
@@ -40,7 +40,7 @@ const RatingModal = ({ ratingModal, setRatingModal }) => {
@@ -52,4 +52,4 @@ const RatingModal = ({ ratingModal, setRatingModal }) => {
)
}
-export default RatingModal
\ No newline at end of file
+export default RatingModal
diff --git a/components/Title.jsx b/src/components/Title.tsx
similarity index 96%
rename from components/Title.jsx
rename to src/components/Title.tsx
index d0038d18..bb3e1047 100644
--- a/components/Title.jsx
+++ b/src/components/Title.tsx
@@ -1,7 +1,6 @@
'use client'
import { ArrowRight } from 'lucide-react'
import Link from 'next/link'
-import React from 'react'
const Title = ({ title, description, visibleButton = true, href = '' }) => {
diff --git a/components/admin/AdminLayout.jsx b/src/components/admin/AdminLayout.tsx
similarity index 100%
rename from components/admin/AdminLayout.jsx
rename to src/components/admin/AdminLayout.tsx
diff --git a/components/admin/AdminNavbar.jsx b/src/components/admin/AdminNavbar.tsx
similarity index 100%
rename from components/admin/AdminNavbar.jsx
rename to src/components/admin/AdminNavbar.tsx
diff --git a/components/admin/AdminSidebar.jsx b/src/components/admin/AdminSidebar.tsx
similarity index 97%
rename from components/admin/AdminSidebar.jsx
rename to src/components/admin/AdminSidebar.tsx
index 5cc5dbd1..8744d9a9 100644
--- a/components/admin/AdminSidebar.jsx
+++ b/src/components/admin/AdminSidebar.tsx
@@ -4,7 +4,7 @@ import { usePathname } from "next/navigation"
import { HomeIcon, ShieldCheckIcon, StoreIcon, TicketPercentIcon } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
-import { assets } from "@/assets/assets"
+import { assets } from "@/src/assets/assets"
const AdminSidebar = () => {
diff --git a/components/admin/StoreInfo.jsx b/src/components/admin/StoreInfo.jsx
similarity index 100%
rename from components/admin/StoreInfo.jsx
rename to src/components/admin/StoreInfo.jsx
diff --git a/components/store/StoreLayout.jsx b/src/components/store/StoreLayout.tsx
similarity index 96%
rename from components/store/StoreLayout.jsx
rename to src/components/store/StoreLayout.tsx
index c9b3481d..53d98c31 100644
--- a/components/store/StoreLayout.jsx
+++ b/src/components/store/StoreLayout.tsx
@@ -5,7 +5,7 @@ import Link from "next/link"
import { ArrowRightIcon } from "lucide-react"
import SellerNavbar from "./StoreNavbar"
import SellerSidebar from "./StoreSidebar"
-import { dummyStoreData } from "@/assets/assets"
+import { dummyStoreData } from "@/src/assets/assets"
const StoreLayout = ({ children }) => {
diff --git a/components/store/StoreNavbar.jsx b/src/components/store/StoreNavbar.tsx
similarity index 100%
rename from components/store/StoreNavbar.jsx
rename to src/components/store/StoreNavbar.tsx
diff --git a/components/store/StoreSidebar.jsx b/src/components/store/StoreSidebar.tsx
similarity index 100%
rename from components/store/StoreSidebar.jsx
rename to src/components/store/StoreSidebar.tsx
diff --git a/src/lib/features/address/addressSlice.ts b/src/lib/features/address/addressSlice.ts
new file mode 100644
index 00000000..141c2107
--- /dev/null
+++ b/src/lib/features/address/addressSlice.ts
@@ -0,0 +1,26 @@
+import { addressDummyData } from '@/src/assets/assets'
+import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
+
+export type Address = typeof addressDummyData
+
+interface AddressState {
+ list: Address[]
+}
+
+const initialState: AddressState = {
+ list: [addressDummyData],
+}
+
+const addressSlice = createSlice({
+ name: 'address',
+ initialState,
+ reducers: {
+ addAddress: (state, action: PayloadAction) => {
+ state.list.push(action.payload)
+ },
+ }
+})
+
+export const { addAddress } = addressSlice.actions
+
+export default addressSlice.reducer
diff --git a/lib/features/cart/cartSlice.js b/src/lib/features/cart/cartSlice.ts
similarity index 65%
rename from lib/features/cart/cartSlice.js
rename to src/lib/features/cart/cartSlice.ts
index ddfc4684..d26c82e9 100644
--- a/lib/features/cart/cartSlice.js
+++ b/src/lib/features/cart/cartSlice.ts
@@ -1,13 +1,24 @@
-import { createSlice } from '@reduxjs/toolkit'
+import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
+
+type ProductIdPayload = {
+ productId: string
+}
+
+export interface CartState {
+ total: number
+ cartItems: Record
+}
+
+const initialState: CartState = {
+ total: 0,
+ cartItems: {},
+}
const cartSlice = createSlice({
name: 'cart',
- initialState: {
- total: 0,
- cartItems: {},
- },
+ initialState,
reducers: {
- addToCart: (state, action) => {
+ addToCart: (state, action: PayloadAction) => {
const { productId } = action.payload
if (state.cartItems[productId]) {
state.cartItems[productId]++
@@ -16,17 +27,17 @@ const cartSlice = createSlice({
}
state.total += 1
},
- removeFromCart: (state, action) => {
+ removeFromCart: (state, action: PayloadAction) => {
const { productId } = action.payload
if (state.cartItems[productId]) {
state.cartItems[productId]--
if (state.cartItems[productId] === 0) {
delete state.cartItems[productId]
}
+ state.total -= 1
}
- state.total -= 1
},
- deleteItemFromCart: (state, action) => {
+ deleteItemFromCart: (state, action: PayloadAction) => {
const { productId } = action.payload
state.total -= state.cartItems[productId] ? state.cartItems[productId] : 0
delete state.cartItems[productId]
diff --git a/src/lib/features/product/productSlice.ts b/src/lib/features/product/productSlice.ts
new file mode 100644
index 00000000..d0b1e5e1
--- /dev/null
+++ b/src/lib/features/product/productSlice.ts
@@ -0,0 +1,29 @@
+import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
+import { productDummyData } from '@/src/assets/assets'
+
+export type Product = (typeof productDummyData)[number]
+
+interface ProductState {
+ list: Product[]
+}
+
+const initialState: ProductState = {
+ list: productDummyData,
+}
+
+const productSlice = createSlice({
+ name: 'product',
+ initialState,
+ reducers: {
+ setProduct: (state, action: PayloadAction) => {
+ state.list = action.payload
+ },
+ clearProduct: (state) => {
+ state.list = []
+ }
+ }
+})
+
+export const { setProduct, clearProduct } = productSlice.actions
+
+export default productSlice.reducer
diff --git a/src/lib/features/rating/ratingSlice.ts b/src/lib/features/rating/ratingSlice.ts
new file mode 100644
index 00000000..4313a264
--- /dev/null
+++ b/src/lib/features/rating/ratingSlice.ts
@@ -0,0 +1,28 @@
+import { dummyRatingsData } from '@/src/assets/assets'
+import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
+
+export type Rating = (typeof dummyRatingsData)[number] & {
+ orderId?: string
+}
+
+interface RatingState {
+ ratings: Rating[]
+}
+
+const initialState: RatingState = {
+ ratings: [],
+}
+
+const ratingSlice = createSlice({
+ name: 'rating',
+ initialState,
+ reducers: {
+ addRating: (state, action: PayloadAction) => {
+ state.ratings.push(action.payload)
+ },
+ }
+})
+
+export const { addRating } = ratingSlice.actions
+
+export default ratingSlice.reducer
diff --git a/src/lib/hooks.ts b/src/lib/hooks.ts
new file mode 100644
index 00000000..a2901974
--- /dev/null
+++ b/src/lib/hooks.ts
@@ -0,0 +1,5 @@
+import { useDispatch, useSelector, type TypedUseSelectorHook } from 'react-redux'
+import type { AppDispatch, RootState } from './store'
+
+export const useAppDispatch = () => useDispatch()
+export const useAppSelector: TypedUseSelectorHook = useSelector
diff --git a/lib/store.js b/src/lib/store.ts
similarity index 76%
rename from lib/store.js
rename to src/lib/store.ts
index 4e4f2e77..dc3df58d 100644
--- a/lib/store.js
+++ b/src/lib/store.ts
@@ -13,4 +13,8 @@ export const makeStore = () => {
rating: ratingReducer,
},
})
-}
\ No newline at end of file
+}
+
+export type AppStore = ReturnType
+export type RootState = ReturnType
+export type AppDispatch = AppStore['dispatch']
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..5cdba716
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,40 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "paths": {
+ "@/*": ["./*"]
+ },
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "noEmit": true,
+ "incremental": true,
+ "module": "esnext",
+ "esModuleInterop": true,
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts",
+ "**/*.mts",
+ "**/*.ts",
+ "**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}