Create file constant
This commit is contained in:
@@ -4,11 +4,6 @@ import withPWA from "next-pwa";
|
||||
const nextConfig: NextConfig = {
|
||||
output: "standalone",
|
||||
poweredByHeader: false,
|
||||
env: {
|
||||
NEXT_PUBLIC_API_BASE_URL: process.env.NEXT_PUBLIC_API_BASE_URL,
|
||||
NEXT_PUBLIC_TOKEN_NAME: process.env.NEXT_PUBLIC_TOKEN_NAME,
|
||||
NEXT_PUBLIC_REFRESH_TOKEN_NAME: process.env.NEXT_PUBLIC_REFRESH_TOKEN_NAME,
|
||||
},
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
|
||||
@@ -1,32 +1,67 @@
|
||||
'use client';
|
||||
|
||||
import { useGetAddresses } from '@/app/[name]/(Profile)/profile/address/hooks/useAddressData';
|
||||
import { Address } from '@/app/[name]/(Profile)/profile/address/types/Types';
|
||||
import PrimaryButton from '@/components/button/PrimaryButton';
|
||||
import { ChevronLeft } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type AddressSectionProps = {
|
||||
address: string;
|
||||
const formatAddress = (address: Address) => {
|
||||
return `${address.address}، ${address.city}، ${address.province}`;
|
||||
};
|
||||
|
||||
export const AddressSection = ({ address }: AddressSectionProps) => {
|
||||
|
||||
export const AddressSection = () => {
|
||||
const params = useParams<{ name: string; id: string }>();
|
||||
const { t } = useTranslation('parallels', { keyPrefix: 'OrderDetail' });
|
||||
const { data: addresses } = useGetAddresses();
|
||||
const { data: addressesResponse, isLoading } = useGetAddresses();
|
||||
const addresses = addressesResponse?.data || [];
|
||||
const redirectUrl = `/${params.name}/order/checkout/${params.id}`;
|
||||
|
||||
console.log(addresses);
|
||||
// اگر در حال بارگذاری است، چیزی نمایش نده
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// اگر آدرس ندارد
|
||||
if (addresses.length === 0) {
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<h3 className="text-sm2 font-medium leading-5 mb-4">{t("SectionAddress.Title")}</h3>
|
||||
<p className='text-sm2 text-disabled-text mb-4'>
|
||||
آدرسی ثبت نشده است
|
||||
</p>
|
||||
<Link href={`/${params.name}/profile/address/new?redirect=${encodeURIComponent(redirectUrl)}`}>
|
||||
<PrimaryButton>
|
||||
افزودن آدرس جدید
|
||||
</PrimaryButton>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
// فیلتر کردن آدرسهای غیر پیشفرض
|
||||
const nonDefaultAddresses = addresses.filter(addr => !addr.isDefault);
|
||||
|
||||
// اگر فقط آدرس پیشفرض دارد، نمایش نده
|
||||
if (nonDefaultAddresses.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// آدرس اول غیر پیشفرض را نمایش بده
|
||||
const firstNonDefaultAddress = nonDefaultAddresses[0];
|
||||
|
||||
return (
|
||||
<section className="bg-container rounded-container box-shadow-normal p-4">
|
||||
<div className="py-3">
|
||||
<div className='w-full flex justify-between items-center gap-2'>
|
||||
<h3 className="text-sm2 font-medium leading-5 inline-block">{t("SectionAddress.Title")}</h3>
|
||||
<Link href={`/${params.name}/profile/address?redirect=/${params.name}/order/checkout/${params.id}`}>
|
||||
<Link href={`/${params.name}/profile/address?redirect=${encodeURIComponent(redirectUrl)}`}>
|
||||
<button
|
||||
className='text-sm2 text-primary dark:text-foreground cursor-pointer'
|
||||
onClick={() => { /* Handle address change */ }}
|
||||
>
|
||||
{t("SectionAddress.ButtonChangeAddress")}
|
||||
<ChevronLeft className='inline-block mr-1 mb-0.5 stroke-primary dark:stroke-foreground' size='16' />
|
||||
@@ -34,7 +69,7 @@ export const AddressSection = ({ address }: AddressSectionProps) => {
|
||||
</Link>
|
||||
</div>
|
||||
<p className='mt-6 text-sm2'>
|
||||
{address}
|
||||
{formatAddress(firstNonDefaultAddress)}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -17,7 +17,6 @@ function OrderDetailInex() {
|
||||
const [couponCode, setCouponCode] = React.useState<string>('');
|
||||
const [couponCodeError, setCouponCodeError] = React.useState<string>('');
|
||||
const [tableNumber, setTableNumber] = useState(0);
|
||||
const address = "اراک، مصطفی خمینی، خیابان سینا کوچه چمران ساختمان شهرزاد";
|
||||
const { state: cartModal, toggle: toggleCartModal } = useToggle();
|
||||
|
||||
const incrementTableNumber = () => setTableNumber((prev) => prev + 1);
|
||||
@@ -51,7 +50,7 @@ function OrderDetailInex() {
|
||||
/>
|
||||
|
||||
{deliveryType === '0' && (
|
||||
<AddressSection address={address} />
|
||||
<AddressSection />
|
||||
)}
|
||||
|
||||
{deliveryType === '1' && (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useCreateAddress, useUpdateAddress } from '../../hooks/useAddressData';
|
||||
import { toast } from '@/components/Toast';
|
||||
import { CreateAddressType, UpdateAddressType, NominatimReverseGeocodingResponse, Address } from '../../types/Types';
|
||||
@@ -20,6 +20,8 @@ export const useAddressForm = ({
|
||||
addressData = null,
|
||||
}: UseAddressFormProps) => {
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
const redirect = searchParams.get('redirect');
|
||||
const { mutate: createAddress, isPending: isCreating } = useCreateAddress();
|
||||
const { mutate: updateAddress, isPending: isUpdating } = useUpdateAddress();
|
||||
const isPending = isCreating || isUpdating;
|
||||
@@ -92,7 +94,11 @@ export const useAddressForm = ({
|
||||
updateAddress(updateData, {
|
||||
onSuccess: () => {
|
||||
toast('آدرس با موفقیت بهروزرسانی شد', 'success');
|
||||
router.back();
|
||||
if (redirect) {
|
||||
router.replace(redirect);
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
const errorMessage = error instanceof Error ? error.message : 'خطا در بهروزرسانی آدرس';
|
||||
@@ -105,7 +111,11 @@ export const useAddressForm = ({
|
||||
createAddress(createData, {
|
||||
onSuccess: () => {
|
||||
toast('آدرس با موفقیت ثبت شد', 'success');
|
||||
router.back();
|
||||
if (redirect) {
|
||||
router.replace(redirect);
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
const errorMessage = error instanceof Error ? error.message : 'خطا در ثبت آدرس';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export const API_BASE_URL = "https://dmenuplus-api.dev.danakcorp.com";
|
||||
export const TOKEN_NAME = "dmenu-t";
|
||||
export const REFRESH_TOKEN_NAME = "dmenu-rt";
|
||||
@@ -10,6 +10,7 @@ import Button from '@/components/button/PrimaryButton'
|
||||
import { extractErrorMessage } from '@/lib/func'
|
||||
import { useReceiptStore } from '@/zustand/receiptStore'
|
||||
import { useBulkCart } from '@/app/[name]/(Dialogs)/cart/hooks/useCartData'
|
||||
import { setRefreshToken, setToken } from '@/lib/api/func'
|
||||
|
||||
|
||||
type Props = {
|
||||
@@ -38,8 +39,8 @@ const StepOtp = ({ phone, slug }: Props) => {
|
||||
mutateOtpVerify(values, {
|
||||
onSuccess: (data) => {
|
||||
toast(t('otp_verified'), 'success')
|
||||
localStorage.setItem(process.env.NEXT_PUBLIC_TOKEN_NAME as string, data?.data?.tokens?.accessToken?.token as string)
|
||||
localStorage.setItem(process.env.NEXT_PUBLIC_REFRESH_TOKEN_NAME as string, data?.data?.tokens?.refreshToken?.token as string)
|
||||
setToken(data?.data?.tokens?.accessToken?.token as string)
|
||||
setRefreshToken(data?.data?.tokens?.refreshToken?.token as string)
|
||||
|
||||
if (Object.keys(items).length > 0) {
|
||||
const bulkCartItems = Object.entries(items).map(([key, value]) => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import axios from "axios";
|
||||
import { API_BASE_URL } from "@/config/const";
|
||||
|
||||
export type RefreshTokenRequestModel = {
|
||||
token: string;
|
||||
@@ -6,7 +7,7 @@ export type RefreshTokenRequestModel = {
|
||||
|
||||
export const refreshToken = async (model: RefreshTokenRequestModel) => {
|
||||
const res = await axios.post(
|
||||
`${process.env.NEXT_PUBLIC_API_BASE_URL}/public/auth/refresh`,
|
||||
`${API_BASE_URL}/public/auth/refresh`,
|
||||
{ refreshToken: model.token },
|
||||
{
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
removeRefreshToken,
|
||||
} from "./func";
|
||||
import { refreshToken } from "./auth/refresh-token";
|
||||
import { API_BASE_URL } from "@/config/const";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
@@ -16,7 +17,7 @@ declare global {
|
||||
}
|
||||
|
||||
const axiosInstance = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
|
||||
baseURL: API_BASE_URL,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
|
||||
|
||||
+8
-19
@@ -1,42 +1,31 @@
|
||||
import { REFRESH_TOKEN_NAME, TOKEN_NAME } from "@/config/const";
|
||||
|
||||
export const getToken = async (): Promise<string | null> => {
|
||||
if (typeof window === "undefined") return null;
|
||||
return localStorage.getItem(
|
||||
process.env.NEXT_PUBLIC_TOKEN_NAME as string
|
||||
);
|
||||
return localStorage.getItem(TOKEN_NAME);
|
||||
};
|
||||
|
||||
export const getRefreshToken = async (): Promise<string | null> => {
|
||||
if (typeof window === "undefined") return null;
|
||||
return localStorage.getItem(
|
||||
process.env.NEXT_PUBLIC_REFRESH_TOKEN_NAME as string
|
||||
);
|
||||
return localStorage.getItem(REFRESH_TOKEN_NAME);
|
||||
};
|
||||
|
||||
export const setToken = async (token: string): Promise<void> => {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.setItem(
|
||||
process.env.NEXT_PUBLIC_TOKEN_NAME as string,
|
||||
token
|
||||
);
|
||||
localStorage.setItem(TOKEN_NAME, token);
|
||||
};
|
||||
|
||||
export const setRefreshToken = async (token: string): Promise<void> => {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.setItem(
|
||||
process.env.NEXT_PUBLIC_REFRESH_TOKEN_NAME as string,
|
||||
token
|
||||
);
|
||||
localStorage.setItem(REFRESH_TOKEN_NAME, token);
|
||||
};
|
||||
|
||||
export const removeToken = async (): Promise<void> => {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.removeItem(process.env.NEXT_PUBLIC_TOKEN_NAME as string);
|
||||
localStorage.removeItem(TOKEN_NAME);
|
||||
};
|
||||
|
||||
export const removeRefreshToken = async (): Promise<void> => {
|
||||
if (typeof window === "undefined") return;
|
||||
localStorage.removeItem(
|
||||
process.env.NEXT_PUBLIC_REFRESH_TOKEN_NAME as string
|
||||
);
|
||||
localStorage.removeItem(REFRESH_TOKEN_NAME);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user