This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { api } from "@/config/axios";
|
||||
import { RESTAURANT_FETCH_TIMEOUT_MS } from "@/app/[name]/lib/getRestaurant";
|
||||
import {
|
||||
AboutResponse,
|
||||
ReviewsResponse,
|
||||
@@ -6,7 +7,9 @@ import {
|
||||
} from "../types/Types";
|
||||
|
||||
export const getAbout = async (name: string): Promise<AboutResponse> => {
|
||||
const { data } = await api.get<AboutResponse>(`/public/restaurants/${name}`);
|
||||
const { data } = await api.get<AboutResponse>(`/public/restaurants/${name}`, {
|
||||
timeout: RESTAURANT_FETCH_TIMEOUT_MS,
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
|
||||
+18
-27
@@ -17,24 +17,12 @@ export async function generateMetadata({
|
||||
params: Promise<LayoutParams>
|
||||
}): Promise<Metadata> {
|
||||
const { name } = await params
|
||||
const defaultIcon = "/icons/web-app-manifest-192x192.png"
|
||||
const defaultIcon512 = "/icons/web-app-manifest-512x512.png"
|
||||
|
||||
try {
|
||||
const restaurant = await getRestaurant(name)
|
||||
|
||||
const title = restaurant.seoTitle || restaurant.name
|
||||
const logo = restaurant.logo
|
||||
|
||||
const defaultIcon = "/icons/web-app-manifest-192x192.png"
|
||||
|
||||
// استفاده از API route برای تبدیل لوگو به مربع
|
||||
let iconUrl = defaultIcon
|
||||
let icon192Url = defaultIcon
|
||||
let icon512Url = "/icons/web-app-manifest-512x512.png"
|
||||
|
||||
if (logo && logo.trim() !== "") {
|
||||
iconUrl = `/${name}/api/logo?url=${encodeURIComponent(logo)}&size=192`
|
||||
icon192Url = `/${name}/api/logo?url=${encodeURIComponent(logo)}&size=192`
|
||||
icon512Url = `/${name}/api/logo?url=${encodeURIComponent(logo)}&size=512`
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
@@ -42,12 +30,12 @@ export async function generateMetadata({
|
||||
manifest: `/${name}/manifest.webmanifest`,
|
||||
icons: {
|
||||
icon: [
|
||||
{ url: iconUrl },
|
||||
{ url: icon192Url, sizes: "192x192", type: "image/png" },
|
||||
{ url: icon512Url, sizes: "512x512", type: "image/png" },
|
||||
{ url: defaultIcon },
|
||||
{ url: defaultIcon, sizes: "192x192", type: "image/png" },
|
||||
{ url: defaultIcon512, sizes: "512x512", type: "image/png" },
|
||||
],
|
||||
shortcut: iconUrl,
|
||||
apple: iconUrl,
|
||||
shortcut: defaultIcon,
|
||||
apple: defaultIcon,
|
||||
},
|
||||
}
|
||||
} catch {
|
||||
@@ -94,18 +82,21 @@ export default async function Layout({
|
||||
children: React.ReactNode
|
||||
params: Promise<LayoutParams>
|
||||
}): Promise<React.ReactNode> {
|
||||
const { name } = await params
|
||||
|
||||
try {
|
||||
const { name } = await params
|
||||
await getRestaurant(name)
|
||||
return <>
|
||||
<PreferenceWrapper>{children}</PreferenceWrapper>
|
||||
<CartChecker />
|
||||
<ActiveChecker />
|
||||
</>
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message === 'RESTAURANT_NOT_FOUND') {
|
||||
notFound()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<PreferenceWrapper>{children}</PreferenceWrapper>
|
||||
<CartChecker />
|
||||
<ActiveChecker />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,23 +3,22 @@ import { API_BASE_URL } from "@/config/const";
|
||||
import { AboutResponse, Restaurant } from "../(Main)/about/types/Types";
|
||||
import axios from "axios";
|
||||
|
||||
export const RESTAURANT_FETCH_TIMEOUT_MS = 10_000;
|
||||
|
||||
async function fetchRestaurant(slug: string): Promise<Restaurant> {
|
||||
try {
|
||||
const response = await axios(`${API_BASE_URL}/public/restaurants/${slug}`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-SLUG": slug,
|
||||
const response = await axios.get<AboutResponse>(
|
||||
`${API_BASE_URL}/public/restaurants/${slug}`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-SLUG": slug,
|
||||
},
|
||||
timeout: RESTAURANT_FETCH_TIMEOUT_MS,
|
||||
},
|
||||
});
|
||||
);
|
||||
|
||||
if (!response.data) {
|
||||
if (response.status === 404) {
|
||||
throw new Error("RESTAURANT_NOT_FOUND");
|
||||
}
|
||||
throw new Error(`Failed to fetch restaurant: ${response.status}`);
|
||||
}
|
||||
|
||||
const data: AboutResponse = await response.data;
|
||||
const data = response.data;
|
||||
|
||||
if (!data.success || !data.data) {
|
||||
throw new Error("RESTAURANT_NOT_FOUND");
|
||||
@@ -30,6 +29,9 @@ async function fetchRestaurant(slug: string): Promise<Restaurant> {
|
||||
if (error instanceof Error && error.message === "RESTAURANT_NOT_FOUND") {
|
||||
throw error;
|
||||
}
|
||||
if (axios.isAxiosError(error) && error.response?.status === 404) {
|
||||
throw new Error("RESTAURANT_NOT_FOUND");
|
||||
}
|
||||
throw new Error(`Failed to fetch restaurant data: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,44 +13,21 @@ export async function GET(
|
||||
const restaurant = await getRestaurant(name);
|
||||
|
||||
const themeColor = restaurant.menuColor || "#F4F5F9";
|
||||
const logo = restaurant.logo;
|
||||
|
||||
const icons = [];
|
||||
if (logo && logo.trim() !== "") {
|
||||
// استفاده از API route برای تبدیل لوگو به مربع
|
||||
const logo192Url = `/${name}/api/logo?url=${encodeURIComponent(logo)}&size=192`;
|
||||
const logo512Url = `/${name}/api/logo?url=${encodeURIComponent(logo)}&size=512`;
|
||||
|
||||
icons.push(
|
||||
{
|
||||
src: logo192Url,
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
{
|
||||
src: logo512Url,
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
}
|
||||
);
|
||||
} else {
|
||||
icons.push(
|
||||
{
|
||||
src: "/icons/web-app-manifest-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
{
|
||||
src: "/icons/web-app-manifest-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
}
|
||||
);
|
||||
}
|
||||
const icons = [
|
||||
{
|
||||
src: "/icons/web-app-manifest-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
{
|
||||
src: "/icons/web-app-manifest-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
];
|
||||
|
||||
const manifest = {
|
||||
name: restaurant.name,
|
||||
@@ -83,6 +60,45 @@ export async function GET(
|
||||
return new NextResponse("Restaurant not found", { status: 404 });
|
||||
}
|
||||
|
||||
return new NextResponse("Internal Server Error", { status: 500 });
|
||||
const { name } = await params;
|
||||
const manifest = {
|
||||
name,
|
||||
short_name: name,
|
||||
description: `منوی ${name}`,
|
||||
start_url: `/${name}`,
|
||||
scope: `/${name}`,
|
||||
id: `/${name}`,
|
||||
display: "standalone",
|
||||
display_override: ["fullscreen", "minimal-ui", "browser"],
|
||||
background_color: "#F4F5F9",
|
||||
theme_color: "#F4F5F9",
|
||||
orientation: "portrait",
|
||||
dir: "rtl",
|
||||
lang: "fa-IR",
|
||||
icons: [
|
||||
{
|
||||
src: "/icons/web-app-manifest-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
{
|
||||
src: "/icons/web-app-manifest-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
purpose: "any",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return NextResponse.json(manifest, {
|
||||
headers: {
|
||||
"Content-Type": "application/manifest+json",
|
||||
"Cache-Control":
|
||||
"no-store, no-cache, must-revalidate, proxy-revalidate",
|
||||
Pragma: "no-cache",
|
||||
Expires: "0",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user