Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 42 additions & 12 deletions docs/api/PLAN_PAYWALL_INTERFACE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Plan Paywall Interface

Component that restricts access to its content until if member does not have access to the required plans.
Component that restricts access to its content unless the member has one of the access plans.

## Architecture

Expand All @@ -15,7 +15,7 @@ The root container that provides plan paywall context to all child components.
**Props**
```tsx
interface PlanPaywallServiceConfig {
requiredPlanIds: string[];
accessPlanIds: string[];
memberOrders?: orders.Order[];
}

Expand All @@ -28,7 +28,7 @@ interface RootProps {
**Example**
```tsx
// Restrict by specific plan ids
<PlanPaywall.Root planPaywallServiceConfig={{ requiredPlanIds: ['planId'] }}>
<PlanPaywall.Root planPaywallServiceConfig={{ accessPlanIds: ['planId'] }}>
<PlanPaywall.Paywall>
<PlanPaywall.RestrictedContent>
<div>Paywalled content</div>
Expand All @@ -45,7 +45,7 @@ interface RootProps {
// Load member orders externally
const { memberOrders } = await loadPlanPaywallServiceConfig(['planId']);

<PlanPaywall.Root planPaywallServiceConfig={{ memberOrders: memberOrders, requiredPlanIds: ['planId'] }}>
<PlanPaywall.Root planPaywallServiceConfig={{ memberOrders: memberOrders, accessPlanIds: ['planId'] }}>
{/* Plan paywall components */}
</PlanPaywall.Root>
```
Expand All @@ -61,6 +61,13 @@ interface PaywallProps {
children: AsChildChildren<PlanPaywallData> | React.ReactNode;
loadingState?: React.ReactNode;
}

interface PlanPaywallData {
isLoading: boolean;
error: string | null;
hasAccess: boolean;
isLoggedIn: boolean;
}
```

**Example**
Expand All @@ -72,7 +79,7 @@ interface PaywallProps {

// With asChild
<PlanPaywall.Paywall asChild>
{React.forwardRef(({isLoading, error, hasAccess}, ref) => {
{React.forwardRef(({isLoading, error, hasAccess, isLoggedIn}, ref) => {
if (isLoading) {
return <div>Loading...</div>;
}
Expand All @@ -81,6 +88,10 @@ interface PaywallProps {
return <div>Error: {error.message}</div>;
}

if (!isLoggedIn) {
return <div>Please log in to access this content</div>;
}

if (hasAccess) {
return <div>Paywalled content</div>;
}
Expand All @@ -89,14 +100,11 @@ interface PaywallProps {
})}
</PlanPaywall.Paywall>
```

**Data Attributes**
- `data-testid="plan-paywall-paywall"` - Applied to paywall element
---

### PlanPaywall.RestrictedContent

Component that displays the restricted content if the member has access to the required plans.
Component that displays the restricted content if the member has one of the access plans.

**Props**
```tsx
Expand All @@ -115,19 +123,34 @@ interface RestrictedContentProps {

### PlanPaywall.Fallback

Component that displays the fallback content if the member does not have access to the required plans.
Component that displays the fallback content if the member does not have any of the access plans.

**Props**
```tsx
interface FallbackProps {
children: React.ReactNode;
asChild?: boolean;
children:
| AsChildChildren<{ accessPlanIds: string[]; isLoggedIn: boolean }>
| React.ReactNode;
}
```

**Example**
```tsx
// Default usage
<PlanPaywall.Fallback>
<div>You need to buy a plan to access this content</div>
<div>Fallback content</div>
</PlanPaywall.Fallback>

// With asChild with react component
<PlanPaywall.Fallback asChild>
{React.forwardRef(({accessPlanIds, isLoggedIn}, ref) => {
if (!isLoggedIn) {
return <div ref={ref}>Please log in to access this content</div>;
}

return <div ref={ref}>You need to buy one of the following plans to access this content: {accessPlanIds.join(', ')}</div>;
})}
</PlanPaywall.Fallback>
```
---
Expand All @@ -146,6 +169,9 @@ interface ErrorComponentProps {

**Example**
```tsx
// Default usage
<PlanPaywall.ErrorComponent />

// With asChild
<PlanPaywall.ErrorComponent asChild>
<div>There was an error checking member access</div>
Expand All @@ -160,3 +186,7 @@ interface ErrorComponentProps {
))}
</PlanPaywall.ErrorComponent>
```

**Data Attributes**
- `data-testid="plan-paywall-error-component"` - Applied to error component
---
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { useWixClient } from '../hooks/useWixClient';
import { getLevelBadgeClass } from '../utils/course-utils';
import { PlanCardContent } from './PlanCard';
import type { Course } from '../utils/demo-courses';
import { PricingPlans } from '@wix/headless-pricing-plans/react';
import {
PricingPlans,
type PlanPaywallFallbackData,
} from '@wix/headless-pricing-plans/react';

interface CoursePageComponentProps {
course: Course;
Expand All @@ -17,15 +20,24 @@ export const CoursePageComponent = (props: CoursePageComponentProps) => {
return (
<PricingPlans.PlanPaywall.Root
planPaywallServiceConfig={{
requiredPlanIds: props.course.accessedByPlanIds,
accessPlanIds: props.course.accessedByPlanIds,
}}
>
<PricingPlans.PlanPaywall.Paywall>
<PricingPlans.PlanPaywall.RestrictedContent>
<CourseData {...props} />
</PricingPlans.PlanPaywall.RestrictedContent>
<PricingPlans.PlanPaywall.Fallback>
<RestrictedCourseFallback course={props.course} />
{React.forwardRef<HTMLDivElement, PlanPaywallFallbackData>(
({ accessPlanIds, isLoggedIn }, ref) => (
<RestrictedCourseFallback
course={props.course}
ref={ref}
accessPlanIds={accessPlanIds}
isLoggedIn={isLoggedIn}
/>
),
)}
</PricingPlans.PlanPaywall.Fallback>
</PricingPlans.PlanPaywall.Paywall>
</PricingPlans.PlanPaywall.Root>
Expand All @@ -35,11 +47,11 @@ export const CoursePageComponent = (props: CoursePageComponentProps) => {
return <CourseData {...props} />;
};

const RestrictedCourseFallback: React.FC<CoursePageComponentProps> = ({
course,
}) => {
const { getIsLoggedIn, login, logout } = useWixClient();
const [isLoggedIn] = useState<boolean>(getIsLoggedIn());
const RestrictedCourseFallback = React.forwardRef<
HTMLDivElement,
PlanPaywallFallbackData & { course: Course }
>(({ course, isLoggedIn, accessPlanIds }, ref) => {
const { login, logout } = useWixClient();

const authLinkText = isLoggedIn ? 'Logout' : 'Login';

Expand All @@ -52,7 +64,10 @@ const RestrictedCourseFallback: React.FC<CoursePageComponentProps> = ({
};

return (
<div className="min-h-screen bg-gradient-to-br from-amber-50 via-orange-50 to-yellow-50">
<div
ref={ref}
className="min-h-screen bg-gradient-to-br from-amber-50 via-orange-50 to-yellow-50"
>
{/* Navigation */}
<nav className="bg-white/80 backdrop-blur-md border-b border-primary-100 sticky top-0 z-50 shadow-subtle">
<div className="container mx-auto px-6 py-4">
Expand Down Expand Up @@ -184,8 +199,7 @@ const RestrictedCourseFallback: React.FC<CoursePageComponentProps> = ({
<div className="max-w-6xl mx-auto text-center">
<PricingPlans.PlanList.Root
planListServiceConfig={{
// TODO: Don't render plans if user has access to the course
planIds: course.accessedByPlanIds || [],
planIds: accessPlanIds,
}}
>
<PricingPlans.PlanList.Plans
Expand Down Expand Up @@ -216,7 +230,7 @@ const RestrictedCourseFallback: React.FC<CoursePageComponentProps> = ({
</main>
</div>
);
};
});

const CourseData: React.FC<CoursePageComponentProps> = ({ course }) => {
const { getIsLoggedIn, login, logout } = useWixClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ const CoursesPageComponent: React.FC = () => {
<PricingPlans.PlanPaywall.Root
key={course.id}
planPaywallServiceConfig={{
requiredPlanIds: course.accessedByPlanIds,
accessPlanIds: course.accessedByPlanIds,
}}
>
<PricingPlans.PlanPaywall.Paywall>
Expand Down
2 changes: 1 addition & 1 deletion packages/headless-components/pricing-plans/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@wix/headless-pricing-plans",
"version": "0.0.10",
"version": "0.0.11",
"type": "module",
"scripts": {
"prebuild": "cd ../utils && yarn build && cd ../components && yarn build && cd ../media && yarn build",
Expand Down
Loading