111 lines
3.7 KiB
TypeScript
111 lines
3.7 KiB
TypeScript
export type DeliveryInvitationAction =
|
|
| "create_delivery_invitation"
|
|
| "send_delivery_offer"
|
|
| "send_delivery_reminder"
|
|
| "request_new_link"
|
|
| "confirm_delivery_choice"
|
|
| "transfer_to_logistics"
|
|
| "mark_paid_storage"
|
|
| "mark_delivered";
|
|
|
|
export type DeliveryInvitationPublicState =
|
|
| "awaiting_choice"
|
|
| "opened"
|
|
| "reminder_sent"
|
|
| "transferred_to_logistics"
|
|
| "paid_storage"
|
|
| "delivered"
|
|
| "agreed"
|
|
| "default";
|
|
|
|
export const DEFAULT_AVAILABLE_SLOTS = ["Первая половина дня", "Вторая половина дня"];
|
|
|
|
export const getOrderUpdateForDeliveryInvitationAction = (action: DeliveryInvitationAction) => {
|
|
switch (action) {
|
|
case "create_delivery_invitation":
|
|
case "send_delivery_offer":
|
|
case "send_delivery_reminder":
|
|
case "request_new_link":
|
|
return {
|
|
status: "Ожидает ответа клиента",
|
|
deliveryAgreementStatus: "Отправлено клиенту",
|
|
};
|
|
case "confirm_delivery_choice":
|
|
return {
|
|
status: "Доставка согласована",
|
|
deliveryAgreementStatus: "Подтверждено клиентом",
|
|
};
|
|
case "transfer_to_logistics":
|
|
return {
|
|
status: "Передан логисту",
|
|
deliveryAgreementStatus: "Нет ответа",
|
|
};
|
|
case "mark_paid_storage":
|
|
return {
|
|
status: "Платное хранение",
|
|
deliveryAgreementStatus: "Нет ответа",
|
|
};
|
|
case "mark_delivered":
|
|
return {
|
|
status: "Доставлен",
|
|
deliveryAgreementStatus: "Подтверждено клиентом",
|
|
};
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
export const getClientInvitationStateFromOrderStatus = (
|
|
status: string,
|
|
): DeliveryInvitationPublicState => {
|
|
switch (status) {
|
|
case "Ожидает ответа клиента":
|
|
return "awaiting_choice";
|
|
case "Ожидает согласования доставки":
|
|
return "opened";
|
|
case "Напоминание отправлено":
|
|
case "Переход отправлен":
|
|
return "reminder_sent";
|
|
case "Передан логисту":
|
|
return "transferred_to_logistics";
|
|
case "Платное хранение":
|
|
return "paid_storage";
|
|
case "Доставлен":
|
|
return "delivered";
|
|
case "Доставка согласована":
|
|
return "agreed";
|
|
default:
|
|
return "default";
|
|
}
|
|
};
|
|
|
|
export const isActiveInvitationState = (state: DeliveryInvitationPublicState) =>
|
|
state === "awaiting_choice" || state === "opened" || state === "reminder_sent";
|
|
|
|
export const generateInvitationToken = () => crypto.randomUUID().replaceAll("-", "");
|
|
|
|
export const hashInvitationToken = async (token: string) => {
|
|
const bytes = new TextEncoder().encode(token);
|
|
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
};
|
|
|
|
export const normalizeAvailableSlots = (availableSlots?: string[] | null) => {
|
|
const slots = availableSlots?.map((slot) => slot.trim()).filter(Boolean) || [];
|
|
return slots.length > 0 ? Array.from(new Set(slots)) : [...DEFAULT_AVAILABLE_SLOTS];
|
|
};
|
|
|
|
export const resolvePublicAppUrl = (
|
|
request: Request,
|
|
fallbackEnv?: string,
|
|
) => {
|
|
const origin = request.headers.get("origin") || request.headers.get("referer") || "";
|
|
const envValue =
|
|
fallbackEnv ||
|
|
(typeof Deno !== "undefined" ? Deno.env.get("PUBLIC_APP_URL") || Deno.env.get("APP_PUBLIC_URL") : "");
|
|
return (envValue || origin || "").replace(/\/$/, "");
|
|
};
|
|
|
|
export const buildInvitationUrl = (baseUrl: string, token: string) =>
|
|
`${baseUrl.replace(/\/$/, "")}/delivery/${token}`;
|