933cb17107
Plan & limit enforcement: - src/lib/plans.ts: PLAN_LIMITS (free: 15 props, 25 customers, 5 presentations, 1 member, 5 imgs/prop) - checkLimit() + limitErrorMessage() — role-aware error messages (owner: upgrade CTA, others: contact admin) - Create actions (property, customer, presentation, team invite): hard limit check before create - PropertyImageUploader: maxImages prop + isOwner-aware toast - UsageBadge component: usage counter shown only to owner (green→amber→red) Role-based access: - TenantContext + ActiveContext: add memberCount + role fields - Dashboard layout: non-owner on free plan with >1 member → /plan-limit - /plan-limit: blocked-access page with owner contact info + sign-out - AppSidebar: minRole filtering — Plan & Faturalama (owner only), Çalışma Alanı/Yatırımcılar (admin+) - settings/billing: owner-only hard redirect - settings/workspace + settings/members: member redirect, admin read-only - settings/investors: member redirect - workspace-actions + logo-actions: restricted to owner only - Workspace form: canEdit = owner only (admin sees read-only view)
31 lines
1.1 KiB
TypeScript
31 lines
1.1 KiB
TypeScript
export const dynamic = "force-dynamic";
|
|
|
|
import { requireTenant } from "@/lib/appwrite/tenant-guard";
|
|
import { listProperties } from "@/lib/appwrite/property-queries";
|
|
import { PropertiesClient } from "@/components/properties/properties-client";
|
|
import { checkLimit, PLAN_LIMITS } from "@/lib/plans";
|
|
|
|
export default async function PropertiesPage() {
|
|
const ctx = await requireTenant();
|
|
const [properties, limitResult] = await Promise.all([
|
|
listProperties(ctx.tenantId),
|
|
checkLimit(ctx.tenantId, ctx.settings?.plan, "properties"),
|
|
]);
|
|
|
|
const plan = ctx.settings?.plan ?? "free";
|
|
const limit = PLAN_LIMITS[plan].properties;
|
|
|
|
const imgLimit = PLAN_LIMITS[plan].propertyImages;
|
|
|
|
return (
|
|
<div className="flex flex-1 flex-col gap-4 p-4 md:p-6 overflow-hidden">
|
|
<PropertiesClient
|
|
initialProperties={properties}
|
|
isOwner={ctx.role === "owner"}
|
|
usageLimit={limit !== Infinity ? { current: limitResult.current, limit } : undefined}
|
|
maxImagesPerProperty={imgLimit !== Infinity ? imgLimit : undefined}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|