This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# VITE_API_URL=https://dpage-api.danakcorp.com
|
VITE_API_URL=https://dpage-api.danakcorp.com
|
||||||
VITE_API_URL=http://192.168.99.131:4000
|
# VITE_API_URL=http://192.168.99.131:4000
|
||||||
VITE_TOKEN_NAME=dpage-editor-t
|
VITE_TOKEN_NAME=dpage-editor-t
|
||||||
VITE_REFRESH_TOKEN_NAME=dpage-editor-refresh-t
|
VITE_REFRESH_TOKEN_NAME=dpage-editor-refresh-t
|
||||||
VITE_INVOICE_URL=https://console.danakcorp.com/receipts/
|
VITE_INVOICE_URL=https://console.danakcorp.com/receipts/
|
||||||
|
VITE_DESIGN_TIER_1_MAX=10
|
||||||
|
VITE_DESIGN_PRICE_TIER_1=700000
|
||||||
|
VITE_DESIGN_TIER_2_MAX=30
|
||||||
|
VITE_DESIGN_PRICE_TIER_2=500000
|
||||||
|
VITE_DESIGN_TIER_3_MAX=70
|
||||||
|
VITE_DESIGN_PRICE_TIER_3=400000
|
||||||
|
VITE_DESIGN_PRICE_TIER_4=350000
|
||||||
+16
@@ -19,6 +19,14 @@ WORKDIR /build
|
|||||||
ARG VITE_API_URL
|
ARG VITE_API_URL
|
||||||
ARG VITE_TOKEN_NAME
|
ARG VITE_TOKEN_NAME
|
||||||
ARG VITE_REFRESH_TOKEN_NAME
|
ARG VITE_REFRESH_TOKEN_NAME
|
||||||
|
ARG VITE_INVOICE_URL
|
||||||
|
ARG VITE_DESIGN_TIER_1_MAX
|
||||||
|
ARG VITE_DESIGN_PRICE_TIER_1
|
||||||
|
ARG VITE_DESIGN_TIER_2_MAX
|
||||||
|
ARG VITE_DESIGN_PRICE_TIER_2
|
||||||
|
ARG VITE_DESIGN_TIER_3_MAX
|
||||||
|
ARG VITE_DESIGN_PRICE_TIER_3
|
||||||
|
ARG VITE_DESIGN_PRICE_TIER_4
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm ci --legacy-peer-deps
|
RUN npm ci --legacy-peer-deps
|
||||||
@@ -28,6 +36,14 @@ RUN set -e; \
|
|||||||
[ -n "$VITE_API_URL" ] && env_args="$env_args VITE_API_URL=$VITE_API_URL"; \
|
[ -n "$VITE_API_URL" ] && env_args="$env_args VITE_API_URL=$VITE_API_URL"; \
|
||||||
[ -n "$VITE_TOKEN_NAME" ] && env_args="$env_args VITE_TOKEN_NAME=$VITE_TOKEN_NAME"; \
|
[ -n "$VITE_TOKEN_NAME" ] && env_args="$env_args VITE_TOKEN_NAME=$VITE_TOKEN_NAME"; \
|
||||||
[ -n "$VITE_REFRESH_TOKEN_NAME" ] && env_args="$env_args VITE_REFRESH_TOKEN_NAME=$VITE_REFRESH_TOKEN_NAME"; \
|
[ -n "$VITE_REFRESH_TOKEN_NAME" ] && env_args="$env_args VITE_REFRESH_TOKEN_NAME=$VITE_REFRESH_TOKEN_NAME"; \
|
||||||
|
[ -n "$VITE_INVOICE_URL" ] && env_args="$env_args VITE_INVOICE_URL=$VITE_INVOICE_URL"; \
|
||||||
|
[ -n "$VITE_DESIGN_TIER_1_MAX" ] && env_args="$env_args VITE_DESIGN_TIER_1_MAX=$VITE_DESIGN_TIER_1_MAX"; \
|
||||||
|
[ -n "$VITE_DESIGN_PRICE_TIER_1" ] && env_args="$env_args VITE_DESIGN_PRICE_TIER_1=$VITE_DESIGN_PRICE_TIER_1"; \
|
||||||
|
[ -n "$VITE_DESIGN_TIER_2_MAX" ] && env_args="$env_args VITE_DESIGN_TIER_2_MAX=$VITE_DESIGN_TIER_2_MAX"; \
|
||||||
|
[ -n "$VITE_DESIGN_PRICE_TIER_2" ] && env_args="$env_args VITE_DESIGN_PRICE_TIER_2=$VITE_DESIGN_PRICE_TIER_2"; \
|
||||||
|
[ -n "$VITE_DESIGN_TIER_3_MAX" ] && env_args="$env_args VITE_DESIGN_TIER_3_MAX=$VITE_DESIGN_TIER_3_MAX"; \
|
||||||
|
[ -n "$VITE_DESIGN_PRICE_TIER_3" ] && env_args="$env_args VITE_DESIGN_PRICE_TIER_3=$VITE_DESIGN_PRICE_TIER_3"; \
|
||||||
|
[ -n "$VITE_DESIGN_PRICE_TIER_4" ] && env_args="$env_args VITE_DESIGN_PRICE_TIER_4=$VITE_DESIGN_PRICE_TIER_4"; \
|
||||||
eval "env$env_args npm run build"
|
eval "env$env_args npm run build"
|
||||||
|
|
||||||
FROM nginx:stable-alpine AS production-stage
|
FROM nginx:stable-alpine AS production-stage
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import Textarea from "@/components/Textarea";
|
|||||||
import { toast } from "@/components/Toast";
|
import { toast } from "@/components/Toast";
|
||||||
import UploadBoxDraggble from "@/components/UploadBoxDraggble";
|
import UploadBoxDraggble from "@/components/UploadBoxDraggble";
|
||||||
import { Paths } from "@/config/Paths";
|
import { Paths } from "@/config/Paths";
|
||||||
|
import { formatPrice } from "@/helpers/func";
|
||||||
import { extractErrorMessage } from "@/helpers/utils";
|
import { extractErrorMessage } from "@/helpers/utils";
|
||||||
import { designerRequestInitialValues, designerRequestValidationSchema, getTotalPrice, PRICE_PER_PAGE, toDesignRequestParams } from "@/pages/designer/designerRequestForm";
|
import { designerRequestInitialValues, designerRequestValidationSchema, getPricePerPage, getTotalPrice, toDesignRequestParams } from "@/pages/designer/designerRequestForm";
|
||||||
import { useInitiateDesignRequest } from "@/pages/designer/hooks/useDesignerData";
|
import { useInitiateDesignRequest } from "@/pages/designer/hooks/useDesignerData";
|
||||||
import type { DesignerRequestFormValues } from "@/pages/designer/types/Types";
|
import type { DesignerRequestFormValues } from "@/pages/designer/types/Types";
|
||||||
import { useMultipleUpload } from "@/pages/uploader/hooks/useUploaderData";
|
import { useMultipleUpload } from "@/pages/uploader/hooks/useUploaderData";
|
||||||
@@ -18,6 +19,8 @@ import { useNavigate } from "react-router-dom";
|
|||||||
const DesignerRequestFormFields: FC = () => {
|
const DesignerRequestFormFields: FC = () => {
|
||||||
const { values, errors, touched, isSubmitting, setFieldValue, setFieldTouched, handleChange, handleBlur } = useFormikContext<DesignerRequestFormValues>();
|
const { values, errors, touched, isSubmitting, setFieldValue, setFieldTouched, handleChange, handleBlur } = useFormikContext<DesignerRequestFormValues>();
|
||||||
|
|
||||||
|
const pageCount = values.count === "" ? 0 : values.count;
|
||||||
|
const pricePerPage = pageCount > 0 ? getPricePerPage(pageCount) : 0;
|
||||||
const totalPrice = getTotalPrice(values.count);
|
const totalPrice = getTotalPrice(values.count);
|
||||||
|
|
||||||
const handleAttachmentChange = (files: File[]) => {
|
const handleAttachmentChange = (files: File[]) => {
|
||||||
@@ -67,9 +70,9 @@ const DesignerRequestFormFields: FC = () => {
|
|||||||
<div className="flex-1" />
|
<div className="flex-1" />
|
||||||
<div className="flex flex-1 gap-4">
|
<div className="flex flex-1 gap-4">
|
||||||
<div className="w-[250px]">
|
<div className="w-[250px]">
|
||||||
<Input label="قیمت به ازای هر صفحه" value={`${PRICE_PER_PAGE.toLocaleString("fa-IR")} تومان`} readOnly />
|
<Input label="قیمت به ازای هر صفحه" value={pageCount > 0 ? `${formatPrice(pricePerPage)} تومان` : "—"} readOnly />
|
||||||
</div>
|
</div>
|
||||||
<Input label="مبلغ قابل پرداخت برای شما" value={`${totalPrice.toLocaleString("fa-IR")} تومان`} readOnly />
|
<Input label="مبلغ قابل پرداخت برای شما" value={`${formatPrice(totalPrice)} تومان`} readOnly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,40 @@ import type {
|
|||||||
} from "@/pages/designer/types/Types";
|
} from "@/pages/designer/types/Types";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
|
|
||||||
export const PRICE_PER_PAGE = 1000;
|
const parseEnvNumber = (value: string | undefined, fallback: number): number => {
|
||||||
|
const parsed = Number(value);
|
||||||
|
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DesignPriceTier = {
|
||||||
|
maxPages: number;
|
||||||
|
pricePerPage: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DESIGN_PRICE_TIERS: DesignPriceTier[] = [
|
||||||
|
{
|
||||||
|
maxPages: parseEnvNumber(import.meta.env.VITE_DESIGN_TIER_1_MAX, 10),
|
||||||
|
pricePerPage: parseEnvNumber(import.meta.env.VITE_DESIGN_PRICE_TIER_1, 700_000),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxPages: parseEnvNumber(import.meta.env.VITE_DESIGN_TIER_2_MAX, 30),
|
||||||
|
pricePerPage: parseEnvNumber(import.meta.env.VITE_DESIGN_PRICE_TIER_2, 500_000),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
maxPages: parseEnvNumber(import.meta.env.VITE_DESIGN_TIER_3_MAX, 70),
|
||||||
|
pricePerPage: parseEnvNumber(import.meta.env.VITE_DESIGN_PRICE_TIER_3, 400_000),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const DESIGN_PRICE_TIER_4 = parseEnvNumber(
|
||||||
|
import.meta.env.VITE_DESIGN_PRICE_TIER_4,
|
||||||
|
350_000,
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getPricePerPage = (count: number): number => {
|
||||||
|
const tier = DESIGN_PRICE_TIERS.find((item) => count <= item.maxPages);
|
||||||
|
return tier?.pricePerPage ?? DESIGN_PRICE_TIER_4;
|
||||||
|
};
|
||||||
|
|
||||||
export const designerRequestInitialValues: DesignerRequestFormValues = {
|
export const designerRequestInitialValues: DesignerRequestFormValues = {
|
||||||
title: "",
|
title: "",
|
||||||
@@ -27,8 +60,10 @@ export const designerRequestValidationSchema = Yup.object({
|
|||||||
attachments: Yup.array(),
|
attachments: Yup.array(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getTotalPrice = (count: DesignerRequestFormValues["count"]) =>
|
export const getTotalPrice = (count: DesignerRequestFormValues["count"]) => {
|
||||||
(count === "" ? 0 : count) * PRICE_PER_PAGE;
|
if (count === "" || count < 1) return 0;
|
||||||
|
return count * getPricePerPage(count);
|
||||||
|
};
|
||||||
|
|
||||||
export const toDesignRequestParams = (
|
export const toDesignRequestParams = (
|
||||||
values: DesignerRequestFormValues,
|
values: DesignerRequestFormValues,
|
||||||
|
|||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
interface ImportMetaEnv {
|
||||||
|
readonly VITE_API_URL: string;
|
||||||
|
readonly VITE_TOKEN_NAME: string;
|
||||||
|
readonly VITE_REFRESH_TOKEN_NAME: string;
|
||||||
|
readonly VITE_INVOICE_URL: string;
|
||||||
|
readonly VITE_DESIGN_TIER_1_MAX: string;
|
||||||
|
readonly VITE_DESIGN_PRICE_TIER_1: string;
|
||||||
|
readonly VITE_DESIGN_TIER_2_MAX: string;
|
||||||
|
readonly VITE_DESIGN_PRICE_TIER_2: string;
|
||||||
|
readonly VITE_DESIGN_TIER_3_MAX: string;
|
||||||
|
readonly VITE_DESIGN_PRICE_TIER_3: string;
|
||||||
|
readonly VITE_DESIGN_PRICE_TIER_4: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImportMeta {
|
||||||
|
readonly env: ImportMetaEnv;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user