fix(brand): real transparent Meezi icon + guest-menu image placeholder
CI/CD / CI · API (dotnet build + test) (push) Successful in 42s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 29s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m9s
CI/CD / CI · Admin Web (tsc) (push) Successful in 39s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 50s
CI/CD / Deploy · all services (push) Successful in 3m24s
- Icons/favicon were a plain solid-green square (a 547B placeholder). Replaced with the actual Meezi mark (green rounded square + menu lines) on transparent corners, generated at 32/48/180/192/512 + a full-bleed green maskable-512. Wired 32/48 favicon + 180 apple-touch-icon into the panel and /q metadata. Copied the same icons to Koja for consistent branding. - Guest QR menu showed blank muted boxes for items without a photo. Added a minimal themed café-cup placeholder (MenuImageFallback) across all four layouts so the menu looks intentional. (Admin/POS already had placeholders.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 28 KiB |
@@ -23,11 +23,13 @@ export const metadata: Metadata = {
|
|||||||
manifest: "/manifest.webmanifest",
|
manifest: "/manifest.webmanifest",
|
||||||
icons: {
|
icons: {
|
||||||
icon: [
|
icon: [
|
||||||
|
{ url: "/icons/icon-32.png", sizes: "32x32", type: "image/png" },
|
||||||
|
{ url: "/icons/icon-48.png", sizes: "48x48", type: "image/png" },
|
||||||
{ url: "/icons/icon-192.png", sizes: "192x192", type: "image/png" },
|
{ url: "/icons/icon-192.png", sizes: "192x192", type: "image/png" },
|
||||||
{ url: "/icons/icon-512.png", sizes: "512x512", type: "image/png" },
|
{ url: "/icons/icon-512.png", sizes: "512x512", type: "image/png" },
|
||||||
],
|
],
|
||||||
shortcut: "/icons/icon-192.png",
|
shortcut: "/icons/icon-32.png",
|
||||||
apple: "/icons/icon-192.png",
|
apple: "/icons/icon-180.png",
|
||||||
},
|
},
|
||||||
appleWebApp: {
|
appleWebApp: {
|
||||||
capable: true,
|
capable: true,
|
||||||
|
|||||||
@@ -9,7 +9,13 @@ export const metadata: Metadata = {
|
|||||||
title: "منوی کافه — میزی",
|
title: "منوی کافه — میزی",
|
||||||
description: "مشاهده منو و ثبت سفارش از میز",
|
description: "مشاهده منو و ثبت سفارش از میز",
|
||||||
manifest: "/manifest.webmanifest",
|
manifest: "/manifest.webmanifest",
|
||||||
icons: { icon: "/icons/icon-192.png", apple: "/icons/icon-192.png" },
|
icons: {
|
||||||
|
icon: [
|
||||||
|
{ url: "/icons/icon-32.png", sizes: "32x32", type: "image/png" },
|
||||||
|
{ url: "/icons/icon-192.png", sizes: "192x192", type: "image/png" },
|
||||||
|
],
|
||||||
|
apple: "/icons/icon-180.png",
|
||||||
|
},
|
||||||
robots: { index: false, follow: false },
|
robots: { index: false, follow: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,34 @@ import type { CafeThemePalette } from "@/lib/cafe-theme";
|
|||||||
import { hasMenu3dView } from "@/lib/menu-3d";
|
import { hasMenu3dView } from "@/lib/menu-3d";
|
||||||
import { Box } from "lucide-react";
|
import { Box } from "lucide-react";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Minimal placeholder shown when a menu item has no image — a faint café-cup
|
||||||
|
* glyph on the themed muted surface, so the guest menu looks intentional
|
||||||
|
* instead of showing blank boxes. `className` controls the box size/shape.
|
||||||
|
*/
|
||||||
|
function MenuImageFallback({ className }: { className?: string }) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn("flex items-center justify-center qr-fill-muted qr-muted", className)}
|
||||||
|
aria-hidden
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.4"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
className="h-2/5 max-h-7 w-2/5 max-w-7 opacity-40"
|
||||||
|
>
|
||||||
|
<path d="M4 8h13v5a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4V8Z" />
|
||||||
|
<path d="M17 9h2.2a2.5 2.5 0 0 1 0 5H17" />
|
||||||
|
<path d="M7 3.5v2M11 3.5v2M14 3.5v2" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export type QrMenuBodyProps = {
|
export type QrMenuBodyProps = {
|
||||||
menuStyle: string;
|
menuStyle: string;
|
||||||
colors: CafeThemePalette;
|
colors: CafeThemePalette;
|
||||||
@@ -377,8 +405,8 @@ function ListItems({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<MenuImageFallback
|
||||||
className={cn("rounded-md qr-fill-muted", compact ? "size-10" : "size-12")}
|
className={cn("rounded-md", compact ? "size-10" : "size-12")}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{hasMenu3dView(item) && onView3d ? (
|
{hasMenu3dView(item) && onView3d ? (
|
||||||
@@ -450,7 +478,7 @@ function MagazineItems({
|
|||||||
{img ? (
|
{img ? (
|
||||||
<img src={img} alt="" className="aspect-[16/9] w-full object-cover" />
|
<img src={img} alt="" className="aspect-[16/9] w-full object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="aspect-[16/9] w-full qr-fill-muted" />
|
<MenuImageFallback className="aspect-[16/9] w-full" />
|
||||||
)}
|
)}
|
||||||
{hasMenu3dView(item) && onView3d ? (
|
{hasMenu3dView(item) && onView3d ? (
|
||||||
<View3dChip
|
<View3dChip
|
||||||
@@ -619,7 +647,7 @@ function ItemRowCard({
|
|||||||
{img ? (
|
{img ? (
|
||||||
<img src={img} alt="" className="size-[4.5rem] rounded-lg object-cover" />
|
<img src={img} alt="" className="size-[4.5rem] rounded-lg object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="size-[4.5rem] rounded-lg qr-fill-muted" />
|
<MenuImageFallback className="size-[4.5rem] rounded-lg" />
|
||||||
)}
|
)}
|
||||||
{hasMenu3dView(item) && onView3d ? (
|
{hasMenu3dView(item) && onView3d ? (
|
||||||
<View3dChip
|
<View3dChip
|
||||||
@@ -694,7 +722,7 @@ function GridCard({
|
|||||||
{img ? (
|
{img ? (
|
||||||
<img src={img} alt="" className="aspect-square w-full object-cover" />
|
<img src={img} alt="" className="aspect-square w-full object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="aspect-square w-full qr-fill-muted" />
|
<MenuImageFallback className="aspect-square w-full" />
|
||||||
)}
|
)}
|
||||||
{hasMenu3dView(item) && onView3d ? (
|
{hasMenu3dView(item) && onView3d ? (
|
||||||
<View3dChip label={view3dLabel} onClick={() => onView3d(item)} className="absolute bottom-2 start-2" />
|
<View3dChip label={view3dLabel} onClick={() => onView3d(item)} className="absolute bottom-2 start-2" />
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 28 KiB |