Wire production domain, CORS for tenant subdomains, celery volume mounts, and nginx reverse proxy configs for apex, API, identity, auth, and wildcard tenants. Co-authored-by: Cursor <cursoragent@cursor.com>
38 lines
1.3 KiB
TypeScript
38 lines
1.3 KiB
TypeScript
import type { PlatformApp } from "@/lib/apps-catalog";
|
||
import { Badge } from "./Badge";
|
||
|
||
export interface AppTileProps {
|
||
app: PlatformApp;
|
||
onClick?: () => void;
|
||
}
|
||
|
||
export function AppTile({ app, onClick }: AppTileProps) {
|
||
const isAvailable = app.status === "available";
|
||
|
||
return (
|
||
<button
|
||
type="button"
|
||
onClick={onClick}
|
||
disabled={!isAvailable && !app.href}
|
||
className="group flex w-full flex-col items-center gap-3 rounded-2xl p-3 text-center transition-all hover:bg-[var(--color-primary-soft)] disabled:cursor-default sm:p-4"
|
||
>
|
||
<div
|
||
className={`relative flex h-[72px] w-[72px] items-center justify-center rounded-[22px] bg-gradient-to-br ${app.gradient} text-3xl shadow-lg shadow-black/10 transition-transform group-hover:scale-105 sm:h-20 sm:w-20 sm:text-4xl`}
|
||
>
|
||
<span role="img" aria-hidden>
|
||
{app.icon}
|
||
</span>
|
||
{!isAvailable ? (
|
||
<span className="absolute -bottom-1 -left-1">
|
||
<Badge variant="muted">بهزودی</Badge>
|
||
</span>
|
||
) : null}
|
||
</div>
|
||
<div className="min-w-0">
|
||
<p className="truncate text-sm font-bold text-secondary sm:text-[15px]">{app.name}</p>
|
||
<p className="mt-0.5 line-clamp-2 text-xs text-gray-500">{app.description}</p>
|
||
</div>
|
||
</button>
|
||
);
|
||
}
|