feat(db): mesh data model — meshes, members, invites, audit log
- pgSchema "mesh" with 4 tables isolating the peer mesh domain - Enums: visibility, transport, tier, role - audit_log is metadata-only (E2E encryption enforced at broker/client) - Cascade on mesh delete, soft-delete via archivedAt/revokedAt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
56
apps/web/src/modules/billing/pricing/plans/plans.tsx
Normal file
56
apps/web/src/modules/billing/pricing/plans/plans.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { memo } from "react";
|
||||
|
||||
import { Skeleton } from "@turbostarter/ui-web/skeleton";
|
||||
|
||||
import { Plan } from "./plan/plan";
|
||||
|
||||
import type { User } from "@turbostarter/auth";
|
||||
import type {
|
||||
BillingModel,
|
||||
Discount,
|
||||
PricingPlan,
|
||||
RecurringInterval,
|
||||
} from "@turbostarter/billing";
|
||||
|
||||
interface PlansProps {
|
||||
readonly plans: PricingPlan[];
|
||||
readonly discounts: Discount[];
|
||||
readonly user: User | null;
|
||||
readonly interval: RecurringInterval;
|
||||
readonly model: BillingModel;
|
||||
readonly currency: string;
|
||||
}
|
||||
|
||||
export const Plans = memo<PlansProps>(
|
||||
({ plans, discounts, interval, user, model, currency }) => {
|
||||
return (
|
||||
<div className="flex w-full flex-wrap items-stretch justify-center gap-8 md:gap-6 lg:gap-4">
|
||||
{plans.map((plan) => (
|
||||
<Plan
|
||||
key={plan.id}
|
||||
plan={plan}
|
||||
interval={interval}
|
||||
model={model}
|
||||
currency={currency}
|
||||
user={user}
|
||||
discounts={discounts}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export const PlansSkeleton = () => {
|
||||
return (
|
||||
<div className="flex w-full flex-wrap items-center justify-center gap-12 md:gap-6 lg:gap-4">
|
||||
{Array.from({ length: 2 }).map((_, i) => (
|
||||
<div key={i} className="grow-0 basis-[25rem] md:shrink-0">
|
||||
<Skeleton className="h-[32rem] w-full" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Plans.displayName = "Plans";
|
||||
Reference in New Issue
Block a user