Add frontend/modules/loyalty with types, API client, design system, feature pages and thin App Router routes under app/loyalty/. BFF proxy at app/api/loyalty/. Include loyalty frontend docs. Co-authored-by: Cursor <cursoragent@cursor.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { Card, CardContent, EmptyState } from "@/components/ds";
|
|
import { AlertTriangle } from "lucide-react";
|
|
|
|
export function LoyaltyScopeNotice({
|
|
title,
|
|
description,
|
|
alternatives,
|
|
}: {
|
|
title: string;
|
|
description: string;
|
|
alternatives?: { label: string; href: string }[];
|
|
}) {
|
|
return (
|
|
<Card className="border-amber-200 bg-amber-50/50 dark:border-amber-900 dark:bg-amber-950/20">
|
|
<CardContent className="flex gap-4 pt-6">
|
|
<AlertTriangle className="h-6 w-6 shrink-0 text-amber-600" />
|
|
<div>
|
|
<h2 className="font-semibold text-secondary">{title}</h2>
|
|
<p className="mt-2 text-sm text-[var(--muted)]">{description}</p>
|
|
{alternatives?.length ? (
|
|
<ul className="mt-4 space-y-2 text-sm">
|
|
{alternatives.map((a) => (
|
|
<li key={a.href}>
|
|
<a href={a.href} className="text-[var(--loyalty-accent)] hover:underline">
|
|
{a.label}
|
|
</a>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
) : null}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
export function LoyaltyPermissionDenied({ message }: { message?: string }) {
|
|
return (
|
|
<EmptyState
|
|
title="دسترسی محدود"
|
|
description={message ?? "شما مجوز مشاهده این بخش را ندارید. با مدیر tenant تماس بگیرید."}
|
|
/>
|
|
);
|
|
}
|