first
This commit is contained in:
1 parent
655fd7ff2c
commit
632cac3d19
14 files changed
+217
-99
No files matched your search
Generated
+37
-22
@@ -21,7 +21,7 @@
|
|||||||
"autoprefixer": "10.4.15",
|
"autoprefixer": "10.4.15",
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.1.0",
|
||||||
"eslint": "8.47.0",
|
"eslint": "8.47.0",
|
||||||
"eslint-config-next": "^14.1.0",
|
"eslint-config-next": "^14.1.0",
|
||||||
"lucide-react": "^0.298.0",
|
"lucide-react": "^0.298.0",
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-redux": "^8.1.3",
|
"react-redux": "^8.1.3",
|
||||||
"tailwind-merge": "^2.1.0",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss": "3.3.3",
|
"tailwindcss": "3.3.3",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript": "5.1.6"
|
"typescript": "5.1.6"
|
||||||
@@ -62,9 +62,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.23.6",
|
"version": "7.23.9",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
|
||||||
"integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
|
"integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@@ -1616,15 +1616,23 @@
|
|||||||
"url": "https://joebell.co.uk"
|
"url": "https://joebell.co.uk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/class-variance-authority/node_modules/clsx": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/client-only": {
|
"node_modules/client-only": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||||
},
|
},
|
||||||
"node_modules/clsx": {
|
"node_modules/clsx": {
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
|
||||||
"integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==",
|
"integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@@ -4625,11 +4633,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwind-merge": {
|
"node_modules/tailwind-merge": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.1.tgz",
|
||||||
"integrity": "sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==",
|
"integrity": "sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.23.5"
|
"@babel/runtime": "^7.23.7"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -5129,9 +5137,9 @@
|
|||||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="
|
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.23.6",
|
"version": "7.23.9",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz",
|
||||||
"integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
|
"integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
}
|
}
|
||||||
@@ -6055,6 +6063,13 @@
|
|||||||
"integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==",
|
"integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"clsx": "2.0.0"
|
"clsx": "2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"clsx": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"client-only": {
|
"client-only": {
|
||||||
@@ -6063,9 +6078,9 @@
|
|||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||||
},
|
},
|
||||||
"clsx": {
|
"clsx": {
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
|
||||||
"integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="
|
"integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg=="
|
||||||
},
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -8120,11 +8135,11 @@
|
|||||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||||
},
|
},
|
||||||
"tailwind-merge": {
|
"tailwind-merge": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.1.tgz",
|
||||||
"integrity": "sha512-l11VvI4nSwW7MtLSLYT4ldidDEUwQAMWuSHk7l4zcXZDgnCRa0V3OdCwFfM7DCzakVXMNRwAeje9maFFXT71dQ==",
|
"integrity": "sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.23.5"
|
"@babel/runtime": "^7.23.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tailwindcss": {
|
"tailwindcss": {
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,7 @@
|
|||||||
"autoprefixer": "10.4.15",
|
"autoprefixer": "10.4.15",
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.1.0",
|
||||||
"eslint": "8.47.0",
|
"eslint": "8.47.0",
|
||||||
"eslint-config-next": "^14.1.0",
|
"eslint-config-next": "^14.1.0",
|
||||||
"lucide-react": "^0.298.0",
|
"lucide-react": "^0.298.0",
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-redux": "^8.1.3",
|
"react-redux": "^8.1.3",
|
||||||
"tailwind-merge": "^2.1.0",
|
"tailwind-merge": "^2.2.1",
|
||||||
"tailwindcss": "3.3.3",
|
"tailwindcss": "3.3.3",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript": "5.1.6"
|
"typescript": "5.1.6"
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import { Fragment } from "react"
|
import { Fragment } from "react"
|
||||||
import { headers } from 'next/headers';
|
import { headers } from 'next/headers';
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { redirect } from 'next/navigation'
|
||||||
|
|
||||||
|
|
||||||
const Page = ()=>{
|
const Page = ()=>{
|
||||||
|
|
||||||
const headersList = headers();
|
const headersList = headers();
|
||||||
const activePath = headersList.get('x-invoke-path');
|
const activePath = headersList.get('x-invoke-path');
|
||||||
|
redirect('/shop')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -44,7 +47,7 @@ const Page = ()=>{
|
|||||||
: null }
|
: null }
|
||||||
|
|
||||||
<div className="">
|
<div className="">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,18 +6,30 @@ import { useRouter } from 'next/navigation'
|
|||||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
import axiosInstance from '@/axios/axiosInstance'
|
import axiosInstance from '@/axios/axiosInstance'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCaption,
|
||||||
|
TableCell,
|
||||||
|
TableFooter,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table"
|
||||||
|
|
||||||
const Page = ({ params }: { params: { id: string } })=>{
|
const Page = ({ params }: { params: { id: string } })=>{
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const [products, setProducts] = useState<{category_name: string, category_img: string, products:[{id:number, name:string, price: number}]}>()
|
const [products, setProducts] = useState<{category_name: string, category_img: string,
|
||||||
|
products:[{id:number, name:string, price: number, view_only: boolean}],
|
||||||
|
view_only_products:[{id:number, name:string, price: number, view_only: boolean}]
|
||||||
|
}>()
|
||||||
|
|
||||||
const query = useQuery({ queryKey: ['productListByCat'], queryFn: async ()=>{
|
const query = useQuery({ queryKey: ['productListByCat'], queryFn: async ()=>{
|
||||||
return await axiosInstance.get(`shop/product/list/${params.id}/`)
|
return await axiosInstance.get(`shop/product/list/${params.id}/`)
|
||||||
}, onSuccess(data:any) {
|
}, onSuccess(result:any) {
|
||||||
setProducts(data.data)
|
setProducts(result.data)
|
||||||
}, });
|
}, });
|
||||||
|
|
||||||
if(query.isLoading){
|
if(query.isLoading){
|
||||||
@@ -33,41 +45,64 @@ const Page = ({ params }: { params: { id: string } })=>{
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mx-auto bg-white w-full md:w-[35rem] border-[1px] rounded p-2 shadow">
|
<div className="mx-auto bg-white w-full md:w-[35rem] border-[1px] rounded p-2 shadow">
|
||||||
<div className='flex justify-between border-b-[1px] pb-2'>
|
<div className='disable-select flex justify-between border-b-[1px] pb-2'>
|
||||||
|
|
||||||
<span>
|
<span className='disable-select'>
|
||||||
{products?.category_name}
|
{products?.category_name}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span onClick={()=>{ router.push('/shop', { scroll: false }) }} className='cursor-pointer bg-cyan-700 pr-1 pl-1 text-white text-[0.9rem] rounded'>بازگشت</span>
|
<span onClick={()=>{ router.push('/shop', { scroll: false }) }} className='disable-select cursor-pointer bg-cyan-700 pr-1 pl-1 text-white text-[0.9rem] rounded'>بازگشت</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className='w-full'>
|
<div className='disable-select w-full'>
|
||||||
<Image className='mx-auto' alt="" src={`https://loolegostar-api.liara.run/${products?.category_img}`} height={150} width={150} />
|
<Image className='disable-select mx-auto' alt="" src={`https://loolegostar-api.liara.run/${products?.category_img}`} height={150} width={150} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='grid grid-cols-2 gap-2 mt-2'>
|
<div className='grid grid-cols-2 gap-2 mt-2'>
|
||||||
|
|
||||||
{products?.products.map((iteam)=>{
|
{products?.products.map((iteam)=>{
|
||||||
return (<Products key={iteam.id} iteam={iteam} />)
|
if (iteam.view_only!=true){
|
||||||
|
return (<Products key={iteam.id} iteam={iteam} />)
|
||||||
|
}
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-row mt-10 mb-10 border-t-[1px] pt-2'>
|
{products?.view_only_products ? (
|
||||||
|
|
||||||
<h2 className='text-center'>محصول زیر فقط بر مبنای سفارش قابل تولید است</h2>
|
<div className='flex flex-col mt-10 mb-10 pt-2'>
|
||||||
|
|
||||||
|
<h2 className='text-center text-sm'>محصولات زیر فقط بر مبنای سفارش قابل تولید است</h2>
|
||||||
|
<Table className='border-t-[1px] mt-4'>
|
||||||
|
<TableCaption></TableCaption>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead className='text-center'>کد محصول</TableHead>
|
||||||
|
<TableHead className='text-center'>نام محصول</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
|
||||||
|
<TableBody>
|
||||||
|
{products?.view_only_products.map((iteam:any, key:any)=>{
|
||||||
|
return (
|
||||||
|
<TableRow key={key}>
|
||||||
|
<TableCell className='text-center'>-----</TableCell>
|
||||||
|
<TableCell className='text-center'>{iteam.name}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</TableBody>
|
||||||
|
|
||||||
|
</Table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
|
||||||
<div onClick={()=>{ router.push('/shop', { scroll: false }) }} className='w-full text-center bg-gray-800 text-white rounded mt-2 p-2'>
|
<div onClick={()=>{ router.push('/shop', { scroll: false }) }} className='disable-select w-full text-center bg-gray-800 text-white rounded mt-2 p-2'>
|
||||||
<span>بازگشت به صفحه قبل</span>
|
<span>بازگشت به صفحه قبل</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ const CustomerInfo = ()=>{
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row gap-x-2">
|
<div className="flex flex-row gap-x-2">
|
||||||
<div>{nameFamily}</div>
|
<div className="disable-select">{nameFamily}</div>
|
||||||
<div onClick={onLogout} className="bg-slate-950 rounded-md pr-1 pl-1 cursor-pointer">خروج</div>
|
<div onClick={onLogout} className="disable-select bg-slate-950 rounded-md pr-1 pl-1 cursor-pointer">خروج</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useState } from "react"
|
import { useState } from "react"
|
||||||
import TopMenu from "./top-menu"
|
import TopMenu from "./top-menu"
|
||||||
|
import { IoMenu } from "react-icons/io5";
|
||||||
|
|
||||||
|
|
||||||
const HamberMenu = ()=>{
|
const HamberMenu = ()=>{
|
||||||
const [showMenu, setShowMenu] = useState(false)
|
const [showMenu, setShowMenu] = useState(false)
|
||||||
return (
|
return (
|
||||||
<div className="md:hidden">
|
<div className="md:hidden">
|
||||||
<span onClick={()=>{ setShowMenu(!showMenu) }} >منو</span>
|
<span onClick={()=>{ setShowMenu(!showMenu) }} >
|
||||||
|
<IoMenu size={'25'} color={'#fff'} />
|
||||||
|
</span>
|
||||||
<TopMenu setShowMenu={setShowMenu} showMenu={showMenu} />
|
<TopMenu setShowMenu={setShowMenu} showMenu={showMenu} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ import { RootState } from "@/app/redux/store"
|
|||||||
import axiosInstance from "@/axios/axiosInstance"
|
import axiosInstance from "@/axios/axiosInstance"
|
||||||
import { addAllToCars, removeAllFromCart } from '@/app/redux/features/cartSlice';
|
import { addAllToCars, removeAllFromCart } from '@/app/redux/features/cartSlice';
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
import {useRouter} from "next/navigation";
|
||||||
|
|
||||||
const OrdersList = ()=>{
|
const OrdersList = ()=>{
|
||||||
|
|
||||||
const {orderList} = useOrderContext()
|
const {orderList} = useOrderContext()
|
||||||
const cartData = useSelector((state: RootState) => state.cart)
|
const cartData = useSelector((state: RootState) => state.cart)
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const query = useQuery({ queryKey: ['cartList1'], queryFn: async ()=>{
|
const query = useQuery({ queryKey: ['cartList1'], queryFn: async ()=>{
|
||||||
return await axiosInstance.get(`shop/cart/`)
|
return await axiosInstance.get(`shop/cart/`)
|
||||||
@@ -24,8 +26,12 @@ const OrdersList = ()=>{
|
|||||||
}, });
|
}, });
|
||||||
|
|
||||||
const [cartIsOpen, setCartIsOpen ] = useState<boolean>(false)
|
const [cartIsOpen, setCartIsOpen ] = useState<boolean>(false)
|
||||||
|
const [disableSubmit, setDisableSubmit] = useState<boolean>(false)
|
||||||
|
|
||||||
const submitOrder = async ()=>{
|
const submitOrder = async ()=>{
|
||||||
|
|
||||||
|
|
||||||
|
setDisableSubmit(true)
|
||||||
const orderData = await cartData.map((item)=>{
|
const orderData = await cartData.map((item)=>{
|
||||||
return {
|
return {
|
||||||
product_id: item.product.id,
|
product_id: item.product.id,
|
||||||
@@ -38,8 +44,11 @@ const OrdersList = ()=>{
|
|||||||
})
|
})
|
||||||
|
|
||||||
if(newOrder.status == 201){
|
if(newOrder.status == 201){
|
||||||
|
setDisableSubmit(false)
|
||||||
alert("ثبت سفارش انجام شد")
|
alert("ثبت سفارش انجام شد")
|
||||||
dispatch(removeAllFromCart())
|
dispatch(removeAllFromCart())
|
||||||
|
router.push('/orders')
|
||||||
|
//window.location.reload()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +60,7 @@ const OrdersList = ()=>{
|
|||||||
|
|
||||||
<div className={`${cartIsOpen ? null : 'hidden' } bg-white lg:block w-full md:w-[17rem] h-screen border-r-[1px] fixed top-0 left-0`}>
|
<div className={`${cartIsOpen ? null : 'hidden' } bg-white lg:block w-full md:w-[17rem] h-screen border-r-[1px] fixed top-0 left-0`}>
|
||||||
<div className='text-center bg-slate-600 p-4 text-white flex flex-row items-center justify-between md:justify-center'>
|
<div className='text-center bg-slate-600 p-4 text-white flex flex-row items-center justify-between md:justify-center'>
|
||||||
<span>سبد خرید شما</span>
|
<span className="disable-select">سبد خرید شما</span>
|
||||||
<span onClick={()=>{ setCartIsOpen(false) }} className="md:hidden bg-slate-900 rounded-lg pr-2 pl-2 pt-1 pb-1">بستن</span>
|
<span onClick={()=>{ setCartIsOpen(false) }} className="md:hidden bg-slate-900 rounded-lg pr-2 pl-2 pt-1 pb-1">بستن</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -59,25 +68,44 @@ const OrdersList = ()=>{
|
|||||||
{cartData?cartData.map((iteam, key)=>{
|
{cartData?cartData.map((iteam, key)=>{
|
||||||
return <OrderItem key={key} iteam={iteam} />
|
return <OrderItem key={key} iteam={iteam} />
|
||||||
}):null }
|
}):null }
|
||||||
|
|
||||||
|
<div className={'md:hidden'}>
|
||||||
|
<p className='disable-select text-center mb-2 text-gray-500'>مشاهده کامل سبد خرید</p>
|
||||||
|
|
||||||
|
{!disableSubmit ? (
|
||||||
|
<div onClick={submitOrder}
|
||||||
|
className='md:hidden disable-select w-full bg-green-900 cursor-pointer text-white mb-2 rounded text-center pt-2 pb-2'>
|
||||||
|
ثبت نهایی
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div className='absolute bg-white bottom-0 right-0 w-full p-4'>
|
<div className='hidden md:block absolute bg-white bottom-0 right-0 w-full p-4'>
|
||||||
|
|
||||||
|
<p className='disable-select text-center mb-2 text-gray-500'>مشاهده کامل سبد خرید</p>
|
||||||
|
|
||||||
|
{!disableSubmit ? (
|
||||||
|
<div onClick={submitOrder}
|
||||||
|
className='disable-select w-full bg-green-900 cursor-pointer text-white mb-2 rounded text-center pt-2 pb-2'>
|
||||||
|
ثبت نهایی
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
|
||||||
<p className='text-center mb-2 text-gray-500'>مشاهده کامل سبد خرید</p>
|
|
||||||
<div onClick={submitOrder} className='w-full bg-green-900 cursor-pointer text-white mb-2 rounded text-center pt-2 pb-2'>
|
|
||||||
ثبت نهایی
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{cartData.length > 0 ? (
|
{cartData.length > 0 ? (
|
||||||
<div className={`${cartIsOpen? 'hidden': null } md:hidden fixed bottom-0 right-0 pb-4 flex w-full flex-row items-center justify-center`}>
|
<div
|
||||||
|
className={`${cartIsOpen ? 'hidden' : null} md:hidden fixed bottom-8 right-0 pb-0 flex w-full flex-row items-center justify-center`}>
|
||||||
<div onClick={()=>{ setCartIsOpen(true) }} className='bg-cyan-800 cursor-pointer text-white rounded-lg pt-2 pb-2 pr-4 pl-4'>
|
<div onClick={()=>{ setCartIsOpen(true) }} className='bg-cyan-800 cursor-pointer text-white rounded-lg pt-2 pb-2 pr-4 pl-4'>
|
||||||
<span className="pr-1 pl-1" >مشاهده سبد خرید</span>
|
<span className="pr-1 pl-1 disable-select" >مشاهده سبد خرید</span>
|
||||||
<span className="rounded bg-cyan-950 inline-block text-center h-[30px] w-[30px] cursor-pointer">{cartData ? cartData.length : null}</span>
|
<span className="disable-select rounded bg-cyan-950 inline-block text-center h-[30px] w-[30px] cursor-pointer">{cartData ? cartData.length : null}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ const ProductCategoryBox: any = (props:any)=>{
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col bg-white text-center rounded overflow-hidden text-white border-solid border-[1px] border-slate-700">
|
<div className="flex flex-col bg-white text-center rounded overflow-hidden text-white border-solid border-[1px] border-slate-700">
|
||||||
<h2 className="bg-slate-600 mb-2">{props.iteam.name}</h2>
|
<h2 className="bg-slate-600 mb-2 disable-select">{props.iteam.name}</h2>
|
||||||
|
|
||||||
<Image loader={imageLoader} className="p-1 mx-auto" alt="a" width={"200"} height={"200"} src={`${process.env.NEXT_PUBLIC_API_URL}/${props.iteam.image}`} />
|
<Image loader={imageLoader} className="disable-select p-1 mx-auto" alt="a" width={"200"} height={"200"} src={`${process.env.NEXT_PUBLIC_API_URL}/${props.iteam.image}`} />
|
||||||
|
|
||||||
<div className="flex justify-between text-black border-t-[1px] mt-2 p-1">
|
<div className="flex justify-between text-black border-t-[1px] mt-2 p-1">
|
||||||
|
|
||||||
<span >
|
<span className="disable-select" >
|
||||||
{`${props.iteam.product_count} نوع`}
|
{`${props.iteam.product_count} نوع`}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<Link onClick={getScrollPostion} href={`shop/product/${props.iteam.id}/`} scroll={false} className="bg-emerald-800 rounded text-white text-[0.8rem] pr-2 pl-2">
|
<Link onClick={getScrollPostion} href={`shop/product/${props.iteam.id}/`} scroll={false} className="disable-select bg-emerald-800 rounded text-white text-[0.8rem] pr-2 pl-2">
|
||||||
<span>مشاهده</span>
|
<span>مشاهده</span>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -70,13 +70,13 @@ const Products = (props:any)=>{
|
|||||||
<div className={`flex flex-col justify-between border-[1px] rounded p-4 shadow ${isInCart ? 'bg-slate-100' : ''} `}>
|
<div className={`flex flex-col justify-between border-[1px] rounded p-4 shadow ${isInCart ? 'bg-slate-100' : ''} `}>
|
||||||
|
|
||||||
<div className='flex flex-row justify-center'>
|
<div className='flex flex-row justify-center'>
|
||||||
<span className="text-justify font-[0.8rem]">{props.iteam.name}</span>
|
<span className="disable-select text-justify font-[0.8rem]">{props.iteam.name}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className='flex flex-row gap-x-2 justify-center mb-2 border-t-[1px] pt-2 mt-2'>
|
<div className='disable-select flex flex-row gap-x-2 justify-center mb-2 border-t-[1px] pt-2 mt-2'>
|
||||||
<span>{formatCurrency(props.iteam.price)}</span>
|
<span className="disable-select">{formatCurrency(props.iteam.price)}</span>
|
||||||
<span>تومان</span>
|
<span className="disable-select">تومان</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex justify-center mb-2'>
|
<div className='flex justify-center mb-2'>
|
||||||
@@ -84,8 +84,8 @@ const Products = (props:any)=>{
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className='flex justify-center mb-2'>
|
<div className='flex justify-center mb-2 disable-select'>
|
||||||
<span onClick={()=>{ addIteamToCart(props.iteam) }} className='cursor-pointer bg-lime-600 text-white rounded pt-1 pb-1 w-full text-center'>
|
<span onClick={()=>{ addIteamToCart(props.iteam) }} className='disable-select cursor-pointer bg-lime-600 text-white rounded pt-1 pb-1 w-full text-center'>
|
||||||
{isInCart? "ویرایش":"ثبت"}
|
{isInCart? "ویرایش":"ثبت"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
|
||||||
interface TopMenuProps {
|
interface TopMenuProps {
|
||||||
showMenu: boolean,
|
showMenu: boolean,
|
||||||
setShowMenu: Function,
|
setShowMenu: Function,
|
||||||
@@ -7,15 +8,20 @@ interface TopMenuProps {
|
|||||||
|
|
||||||
const TopMenu = (props: TopMenuProps)=>{
|
const TopMenu = (props: TopMenuProps)=>{
|
||||||
return (
|
return (
|
||||||
<ul className={ props.showMenu ? 'mt-[40px] md:hidden h-screen fixed top-0 right-0 bg-slate-700 list-none text-center border-l-[1px] border-slate-800' : 'hidden'}>
|
<ul className={ props.showMenu ? 'z-50 mt-[40px] md:hidden h-screen fixed top-0 right-0 bg-slate-700 list-none text-center border-l-[1px] border-slate-800' : 'hidden'}>
|
||||||
<Link onClick={()=>{ props.setShowMenu(false) }} href={"/"}>
|
|
||||||
|
<Link onClick={()=>{ props.setShowMenu(false) }} href={"/shop"}>
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>صفحه اصلی</li>
|
<li className='border-b-[1px] border-slate-800 p-4'>صفحه اصلی</li>
|
||||||
</Link>
|
</Link>
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>سفارشات</li>
|
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>تیکت ها</li>
|
<Link onClick={()=>{ props.setShowMenu(false) }} href={"/orders"}>
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>چک ها</li>
|
<li className='border-b-[1px] border-slate-800 p-4'>سفارشات</li>
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>واریزی ها</li>
|
</Link>
|
||||||
<li className='border-b-[1px] border-slate-800 p-4'>صورت حساب</li>
|
|
||||||
|
<Link onClick={()=>{ props.setShowMenu(false) }} href={"/tickets"}>
|
||||||
|
<li className='border-b-[1px] border-slate-800 p-4'>تیکت ها</li>
|
||||||
|
</Link>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,4 +73,12 @@
|
|||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
|
.disable-select {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+37
-21
@@ -39,31 +39,47 @@ axiosInstance.interceptors.response.use((response)=> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/token/refresh/`, {
|
if (localStorage.getItem('refresh') != 'undefined'){
|
||||||
method: "POST",
|
const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/token/refresh/`, {
|
||||||
headers: {
|
method: "POST",
|
||||||
'Content-Type': 'application/json; charset=UTF-8',
|
headers: {
|
||||||
},
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
body: JSON.stringify({
|
},
|
||||||
'refresh': localStorage.getItem('refresh')
|
body: JSON.stringify({
|
||||||
})
|
'refresh': localStorage.getItem('refresh')
|
||||||
});
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if(res.status==200){
|
||||||
|
setCookieFn('isAuth', 'true', 365)
|
||||||
|
const tokenData = await res.json()
|
||||||
|
localStorage.setItem('access', tokenData.access)
|
||||||
|
localStorage.setItem('refresh',tokenData.refresh)
|
||||||
|
originalRequest.headers.Authorization = `Bearer ${tokenData.access}`
|
||||||
|
return axiosInstance(originalRequest)
|
||||||
|
}else{
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
localStorage.removeItem('access');
|
||||||
|
localStorage.removeItem('refresh');
|
||||||
|
document.cookie = "isAuth=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
setTimeout(()=>{
|
||||||
|
window.location.replace('/login')
|
||||||
|
}, 200)
|
||||||
|
|
||||||
if(res.status==200){
|
|
||||||
setCookieFn('isAuth', 'true', 365)
|
|
||||||
const tokenData = await res.json()
|
|
||||||
localStorage.setItem('access', tokenData.access)
|
|
||||||
localStorage.setItem('refresh',tokenData.refresh)
|
|
||||||
originalRequest.headers.Authorization = `Bearer ${tokenData.access}`
|
|
||||||
return axiosInstance(originalRequest)
|
|
||||||
}else{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch(refreshError) {
|
} catch(refreshError) {
|
||||||
|
|
||||||
|
localStorage.removeItem('access');
|
||||||
|
localStorage.removeItem('refresh');
|
||||||
|
document.cookie = "isAuth=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
setTimeout(()=>{
|
||||||
|
window.location.replace('/login')
|
||||||
|
}, 200)
|
||||||
|
|
||||||
throw refreshError;
|
throw refreshError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
import { type ClassValue, clsx } from "clsx"
|
import { type ClassValue, clsx } from "clsx"
|
||||||
import { twMerge } from "tailwind-merge"
|
import { twMerge } from "tailwind-merge"
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs))
|
return twMerge(clsx(inputs))
|
||||||
}
|
}
|
||||||
+9
-5
@@ -1,5 +1,6 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
import type { Config } from "tailwindcss"
|
||||||
module.exports = {
|
|
||||||
|
const config = {
|
||||||
darkMode: ["class"],
|
darkMode: ["class"],
|
||||||
content: [
|
content: [
|
||||||
'./pages/**/*.{ts,tsx}',
|
'./pages/**/*.{ts,tsx}',
|
||||||
@@ -7,6 +8,7 @@ module.exports = {
|
|||||||
'./app/**/*.{ts,tsx}',
|
'./app/**/*.{ts,tsx}',
|
||||||
'./src/**/*.{ts,tsx}',
|
'./src/**/*.{ts,tsx}',
|
||||||
],
|
],
|
||||||
|
prefix: "",
|
||||||
theme: {
|
theme: {
|
||||||
container: {
|
container: {
|
||||||
center: true,
|
center: true,
|
||||||
@@ -58,12 +60,12 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
"accordion-down": {
|
"accordion-down": {
|
||||||
from: { height: 0 },
|
from: { height: "0" },
|
||||||
to: { height: "var(--radix-accordion-content-height)" },
|
to: { height: "var(--radix-accordion-content-height)" },
|
||||||
},
|
},
|
||||||
"accordion-up": {
|
"accordion-up": {
|
||||||
from: { height: "var(--radix-accordion-content-height)" },
|
from: { height: "var(--radix-accordion-content-height)" },
|
||||||
to: { height: 0 },
|
to: { height: "0" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
animation: {
|
animation: {
|
||||||
@@ -73,4 +75,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [require("tailwindcss-animate")],
|
plugins: [require("tailwindcss-animate")],
|
||||||
}
|
} satisfies Config
|
||||||
|
|
||||||
|
export default config
|
||||||
Reference in new issue
Block a user