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",
|
||||
icons: {
|
||||
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-512.png", sizes: "512x512", type: "image/png" },
|
||||
],
|
||||
shortcut: "/icons/icon-192.png",
|
||||
apple: "/icons/icon-192.png",
|
||||
shortcut: "/icons/icon-32.png",
|
||||
apple: "/icons/icon-180.png",
|
||||
},
|
||||
appleWebApp: {
|
||||
capable: true,
|
||||
|
||||
@@ -9,7 +9,13 @@ export const metadata: Metadata = {
|
||||
title: "منوی کافه — میزی",
|
||||
description: "مشاهده منو و ثبت سفارش از میز",
|
||||
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 },
|
||||
};
|
||||
|
||||
|
||||
@@ -14,6 +14,34 @@ import type { CafeThemePalette } from "@/lib/cafe-theme";
|
||||
import { hasMenu3dView } from "@/lib/menu-3d";
|
||||
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 = {
|
||||
menuStyle: string;
|
||||
colors: CafeThemePalette;
|
||||
@@ -377,8 +405,8 @@ function ListItems({
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className={cn("rounded-md qr-fill-muted", compact ? "size-10" : "size-12")}
|
||||
<MenuImageFallback
|
||||
className={cn("rounded-md", compact ? "size-10" : "size-12")}
|
||||
/>
|
||||
)}
|
||||
{hasMenu3dView(item) && onView3d ? (
|
||||
@@ -450,7 +478,7 @@ function MagazineItems({
|
||||
{img ? (
|
||||
<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 ? (
|
||||
<View3dChip
|
||||
@@ -619,7 +647,7 @@ function ItemRowCard({
|
||||
{img ? (
|
||||
<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 ? (
|
||||
<View3dChip
|
||||
@@ -694,7 +722,7 @@ function GridCard({
|
||||
{img ? (
|
||||
<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 ? (
|
||||
<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 |