mirror of
https://github.com/pockethost/pockethost.git
synced 2026-03-11 11:14:56 +00:00
feat: hard paywall in dashboard
This commit is contained in:
@@ -7,10 +7,6 @@
|
||||
359,
|
||||
'once, use forever',
|
||||
]
|
||||
export let priceAnnually: [number, string?, number?] = [
|
||||
159,
|
||||
'year (save 55%)',
|
||||
]
|
||||
export let startDate: Date | null = null
|
||||
export let endDate: Date | null = null
|
||||
|
||||
@@ -26,12 +22,10 @@
|
||||
qtyMax={1000}
|
||||
description="Epic elite! The Flounder's Edition is almost as good as the Founder's edition, and you'll help PocketHost go global."
|
||||
{priceMonthly}
|
||||
{priceAnnually}
|
||||
requireAuthenticatedUser
|
||||
checkoutMonthURL="https://store.pockethost.io/buy/9ff8775b-6b9e-4aa8-a0ab-dc5e58e25408?checkout[custom][user_id]={$userStore?.id}&checkout[email]={$userStore?.email}"
|
||||
checkoutYearURL="https://store.pockethost.io/buy/82d79f7c-64f6-4c2b-9f58-dcc8951f1cdd?checkout[custom][user_id]={$userStore?.id}&checkout[email]={$userStore?.email}"
|
||||
checkoutMonthURL="https://store.pockethost.io/buy/d4b2d062-429c-49b4-9cdc-853aaeb17e20?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}"
|
||||
features={[
|
||||
`Everything in the ${PLAN_NAMES[SubscriptionType.Premium]} tier`,
|
||||
`Unlimited instances`,
|
||||
`Commemorative Flounder's badge`,
|
||||
`PocketHost t-shirt`,
|
||||
`#onlyflounders private discord channel`,
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
checkoutMonthURL="https://store.pockethost.io/checkout/buy/e71cbfb5-cec3-4745-97a7-d877f6776503?checkout[custom][user_id]={$userStore?.id}"
|
||||
checkoutYearURL="https://store.pockethost.io/checkout/buy/e5660329-5b99-4ed6-8f36-0d387803e1d6?checkout[custom][user_id]={$userStore?.id}"
|
||||
features={[
|
||||
`Everything in the ${PLAN_NAMES[SubscriptionType.Premium]} tier`,
|
||||
'Unlimited instances',
|
||||
'Unlimited bandwidth',
|
||||
'Unlimited storage & files',
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
<script>
|
||||
import UserLoggedIn from '$components/guards/UserLoggedIn.svelte'
|
||||
import UserLoggedOut from '$components/guards/UserLoggedOut.svelte'
|
||||
import { userStore } from '$util/stores'
|
||||
|
||||
$: maxInstances = $userStore?.subscription_quantity
|
||||
</script>
|
||||
|
||||
<div class="m-4">
|
||||
<UserLoggedIn>
|
||||
{#if maxInstances === 0}
|
||||
<div class="flex flex-col space-x-4 items-center justify-center">
|
||||
<div class="prose">
|
||||
<p class="text-2xl text-center text-warning">
|
||||
Instances will not run until you <a
|
||||
href="/access"
|
||||
class="link text-primary">upgrade</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<slot />
|
||||
</UserLoggedIn>
|
||||
<UserLoggedOut>
|
||||
|
||||
@@ -28,27 +28,38 @@
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row space-x-4 items-center justify-center">
|
||||
<div>Instances</div>
|
||||
<progress
|
||||
class="progress progress-primary w-48 md:w-80"
|
||||
value={instanceCount}
|
||||
max={maxInstances}
|
||||
></progress>
|
||||
<div>
|
||||
{#if $userSubscriptionType === SubscriptionType.Founder}
|
||||
{instanceCount}/<a
|
||||
href="https://discord.com/channels/1128192380500193370/1128192380500193373/1296340516044017718"
|
||||
class="link"
|
||||
target="_blank">{maxInstances}</a
|
||||
>
|
||||
{:else}
|
||||
{instanceCount}/{maxInstances}
|
||||
<div class="flex flex-col space-x-4 items-center justify-center">
|
||||
{#if maxInstances > 0}
|
||||
{#if instanceCount > maxInstances}
|
||||
<p class="text-center text-error">
|
||||
You have exceeded your instance limit.
|
||||
</p>
|
||||
{/if}
|
||||
{#if $userSubscriptionType === SubscriptionType.Free}
|
||||
<a href="/pricing" class="link text-xs text-success">Upgrade</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-row space-x-4 items-center justify-center">
|
||||
<div>Instances</div>
|
||||
<progress
|
||||
class="progress {instanceCount > maxInstances
|
||||
? 'progress-error'
|
||||
: 'progress-primary'} w-48 md:w-80"
|
||||
value={instanceCount}
|
||||
max={maxInstances}
|
||||
></progress>
|
||||
<div>
|
||||
{#if $userSubscriptionType === SubscriptionType.Founder}
|
||||
{instanceCount}/<a
|
||||
href="https://discord.com/channels/1128192380500193370/1128192380500193373/1296340516044017718"
|
||||
class="link"
|
||||
target="_blank">{maxInstances}</a
|
||||
>
|
||||
{:else}
|
||||
{instanceCount}/{maxInstances}
|
||||
{/if}
|
||||
{#if instanceCount >= maxInstances}
|
||||
<a href="/support" class="link text-xs text-success">Upgrade</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2 items-center justify-center">
|
||||
|
||||
@@ -8,18 +8,10 @@
|
||||
<div class="card max-w-sm bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Paywall!</h2>
|
||||
<p>Oof. You hit a paywall.</p>
|
||||
<p class="text-error">
|
||||
You're only allowed {maxInstances} projects on the {PLAN_NAMES[
|
||||
$userSubscriptionType
|
||||
]} plan.
|
||||
</p>
|
||||
<p>
|
||||
But that's okay, we know you want to support PocketHost if you love it
|
||||
this much!
|
||||
</p>
|
||||
<p>Oof. You hit a paywall because you are out of instances.</p>
|
||||
|
||||
<div class="card-actions justify-end">
|
||||
<a href="/pricing" class="btn btn-primary">Unlock More Projects</a>
|
||||
<a href="/access" class="btn btn-primary">Unlock</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<script lang="ts">
|
||||
import Paywall from './Paywall.svelte'
|
||||
</script>
|
||||
|
||||
<Paywall />
|
||||
14
packages/dashboard/src/routes/(static)/access/Card.svelte
Normal file
14
packages/dashboard/src/routes/(static)/access/Card.svelte
Normal file
@@ -0,0 +1,14 @@
|
||||
<script lang="ts">
|
||||
export let feature: any
|
||||
</script>
|
||||
|
||||
<div class="card bg-accent text-accent-content shadow-xl mr-auto ml-auto">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{feature.title}</h2>
|
||||
{#if feature.img}
|
||||
<enhanced:img src={feature.img} />
|
||||
{/if}
|
||||
<p>{@html feature.description}</p>
|
||||
<div class="card-actions justify-end"></div>
|
||||
</div>
|
||||
</div>
|
||||
103
packages/dashboard/src/routes/(static)/access/Paywall.svelte
Normal file
103
packages/dashboard/src/routes/(static)/access/Paywall.svelte
Normal file
@@ -0,0 +1,103 @@
|
||||
<script lang="ts">
|
||||
import Card from './Card.svelte'
|
||||
import regions from './regions.png?enhanced'
|
||||
import Testimonials from '$src/components/Testimonials.svelte'
|
||||
import { userStore } from '$src/util/stores'
|
||||
|
||||
let idx = 0
|
||||
const features = [
|
||||
{
|
||||
title: 'PocketBase at Global Scale',
|
||||
img: regions,
|
||||
description:
|
||||
'PocketHost has edges in 40+ regions. Your users connect through our global network of edge servers, then our internal VPN handles world-class routing to your data, wherever it resides.',
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Developer-Friendly Pricing',
|
||||
description: `Join the pirate ship for just $5 per instance. After 5 instances? It's on us, because we like how you think.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Risk-free Trial',
|
||||
description: `Test-drive PocketHost for 7 days. Credit card required.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Pay Once, Use Forever',
|
||||
description: `Join the Flounder's crew LTD. One payment, lifetime access to the Pro tier (up to 250 instances). Once these spots are gone, they're gone forever.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'No Usage Police',
|
||||
description: `Forget usage meters and quotas. Our Fair Use policy means you can build without limits. Gone viral? We've got your back. No questions asked.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Ludicrous Speed',
|
||||
description: `Our global network moves at the speed of thought. 10-30ms average time-to-edge means your apps feel like magic. Your users won't know what hit them.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Early Access to New Tech',
|
||||
description: `Get your hands on our experimental <a href="/blog/announcing-pocker" class="link">Pocker</a> tech before anyone else. Help us push the boundaries of what's possible.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Unshakeable',
|
||||
description:
|
||||
'With 99.95% uptime, your apps stay up while others go down. Sleep easy knowing your creation is always ready to serve.',
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Death to DevOps',
|
||||
description: `Focus on the cool stuff. Let us handle the boring bits - scaling, backups, maintenance. It's time to build something legendary.`,
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Hack More, Pay Less',
|
||||
description:
|
||||
'Why waste time managing servers? Put your resources into building the next big thing. Your wallet (and your future app) will thank you.',
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
{
|
||||
title: 'Power to the Builders',
|
||||
description:
|
||||
'Join us in building the future. Every subscription supports the creators and contributors of the 100% open-source PocketBase and PocketHost projects.',
|
||||
button: 'Unlock Access Now',
|
||||
},
|
||||
]
|
||||
|
||||
$: feature = features[idx]!
|
||||
</script>
|
||||
|
||||
<div class="prose ml-auto mr-auto">
|
||||
<p class="text-3xl text-center">PocketHost Access</p>
|
||||
<p class="text-2xl text-center">
|
||||
<span class="text-primary">$5/instance</span> or
|
||||
<span class="text-primary">$25/unlimited</span>
|
||||
</p>
|
||||
<p class="text-xl text-accent text-center">7 Day Free Trial</p>
|
||||
<div class="flex justify-center mt-10 mb-10">
|
||||
<a
|
||||
class="btn btn-warning btn-lg"
|
||||
style="z-index: 1000"
|
||||
href={`https://store.pockethost.io/buy/d4b2d062-429c-49b4-9cdc-853aaeb17e20?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}`}
|
||||
>{feature.button}</a
|
||||
>
|
||||
</div>
|
||||
|
||||
{#each features as feature}
|
||||
<div class="not-prose mb-10">
|
||||
<Card {feature} />
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<Testimonials />
|
||||
</div>
|
||||
<a
|
||||
class="btn btn-warning btn-block btn-lg rounded-none fixed bottom-0"
|
||||
style="z-index: 1000"
|
||||
href={`https://store.pockethost.io/buy/d4b2d062-429c-49b4-9cdc-853aaeb17e20?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}`}
|
||||
>{feature.button}</a
|
||||
>
|
||||
BIN
packages/dashboard/src/routes/(static)/access/regions.png
Normal file
BIN
packages/dashboard/src/routes/(static)/access/regions.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
@@ -0,0 +1,11 @@
|
||||
## Hard paywall is live
|
||||
|
||||
_[@cap'n](https://discord.gg/nVTxCMEcGT) Jan 10, 2025_
|
||||
|
||||
As [announced previously](/blog/hard-paywall), I've moved to a hard paywall. This means that every new user will have to pay for their PocketHost account before they can use it. There will be a 7 day free trial, but after that, you'll have to pay, and you will know that going in.
|
||||
|
||||
Freemium is broken, especially for small businesses. It's a great way to get people to try your product, but it's not a great way to grow independently.
|
||||
|
||||
I encourage everyone to consider subscribing to PocketHost. It's a great way to support the PocketBase community and ensure the project's long term viability.
|
||||
|
||||
Existing users will be grandfathered in.
|
||||
@@ -1,4 +1,8 @@
|
||||
export const toc = [
|
||||
{
|
||||
title: 'Hard paywall is live',
|
||||
path: '/blog/hard-paywall-is-live',
|
||||
},
|
||||
{
|
||||
title: 'YouTube Dev Channel is Live',
|
||||
path: '/blog/announcing-dev-channel',
|
||||
|
||||
@@ -1,42 +1,16 @@
|
||||
# Pricing Ethos
|
||||
|
||||
At PocketHost, we believe in keeping things simple and transparent. Our pricing is designed to support indie hackers, makers, and small businesses. We offer flexible plans to suit your needs, including a Free Tier, a Pro Tier, and occasionally, limited Lifetime Offers during our bootstrapping phase.
|
||||
At PocketHost, we believe in keeping things simple and transparent. Our pricing is designed to support indie hackers, makers, and small businesses. We offer flexible plans to suit your needs, based on the number of instances you want to run. We also offer limited Lifetime Offers during our bootstrapping phase.
|
||||
|
||||
## Free Tier
|
||||
## Instances
|
||||
|
||||
**Free Forever**
|
||||
You can get started easily on PocketHost by purchasing an instance.
|
||||
|
||||
Our Free Tier is perfect for getting started with PocketHost without any upfront costs. It includes:
|
||||
|
||||
- **Multiple Projects**: Create up to 25 projects as you need.
|
||||
- **Generous Resources**: Fair use of storage, bandwidth, and CPU.
|
||||
- **Essential Features**: Access to the core functionalities of PocketHost.
|
||||
|
||||
The Free Tier is ideal for prototypes, personal projects, or exploring what PocketHost has to offer.
|
||||
|
||||
## Pro Tier
|
||||
|
||||
**Enhanced Capacity and Access**
|
||||
|
||||
For those who need more, our Pro Tier offers expanded capabilities:
|
||||
|
||||
- **All Free Tier Benefits**: Plus additional resources.
|
||||
- **Priority Support**: Get help when you need it.
|
||||
- **Advanced Features**: Unlock premium functionalities.
|
||||
|
||||
**Subscription Options**:
|
||||
|
||||
- **Monthly Plan**: Flexibility to pay as you go.
|
||||
- **Annual Plan**: Save more with yearly billing.
|
||||
|
||||
Our Pro Tier remains a great deal for users who require extra power and support for their growing projects.
|
||||
|
||||
## Lifetime Offers
|
||||
|
||||
**Limited Supply During Bootstrapping**
|
||||
|
||||
Occasionally, we offer Lifetime Plans as part of our bootstrapping efforts:
|
||||
|
||||
- **One-Time Payment**: Enjoy Pro Tier benefits without recurring fees.
|
||||
- **Limited Availability**: Offered in limited quantities and sold on a first-come, first-served basis.
|
||||
- **Non-Transferable**: Cannot be pro-rated, transferred, used retroactively, reserved, or purchased in advance.
|
||||
@@ -46,8 +20,6 @@ Occasionally, we offer Lifetime Plans as part of our bootstrapping efforts:
|
||||
- Once sold out, Lifetime Offers are gone forever.
|
||||
- Timing is everything—if you can wait and catch one of these deals, it's an incredible opportunity.
|
||||
|
||||
Many users opt for our standard Pro Tier, which continues to provide excellent value even when Lifetime Offers are unavailable.
|
||||
|
||||
## Fair Use Policy
|
||||
|
||||
**Unlimited Doesn't Mean Infinite**
|
||||
|
||||
@@ -14,18 +14,10 @@
|
||||
const plans = [
|
||||
{
|
||||
name: PLAN_NAMES[SubscriptionType.Free],
|
||||
price: null,
|
||||
},
|
||||
{
|
||||
name: PLAN_NAMES[SubscriptionType.Premium],
|
||||
price: [
|
||||
{
|
||||
text: '$20/mo',
|
||||
link: `https://store.pockethost.io/checkout/buy/8e7cfb35-846a-4fd6-adcb-c2db5589275d?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}`,
|
||||
},
|
||||
{
|
||||
text: '$199/yr (save 20%)',
|
||||
link: `https://store.pockethost.io/checkout/buy/96e4ab4b-f646-4fb2-b830-5584db983e73?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}`,
|
||||
text: '$5-25 monthly',
|
||||
link: `https://store.pockethost.io/buy/d4b2d062-429c-49b4-9cdc-853aaeb17e20?checkout[custom][user_id]=${$userStore?.id}&checkout[email]=${$userStore?.email}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -34,60 +26,45 @@
|
||||
const items: Item[] = [
|
||||
{
|
||||
name: 'Number of Instances',
|
||||
items: ['25', '250'],
|
||||
items: ['$5/instance (up to 4) or $25 for unlimited'],
|
||||
info: `Each instance can have its own domain, database, and files.`,
|
||||
},
|
||||
{
|
||||
name: 'Premium Bandwidth',
|
||||
items: ['10GB', '100GB'],
|
||||
info: `Premium Bandwidth is pooled per account and refreshes monthly. Any data data transferred in or out of any PocketHost instance you own counts against this pool. This includes all HTTP traffic, file downloads, and admin panel usage.`,
|
||||
},
|
||||
{
|
||||
name: 'Standard Bandwidth',
|
||||
items: ['Unlimited', 'Unlimited'],
|
||||
info: `Standard Bandwidth may be slower than Premium. It is provided so your app doesn't just stop working when you exceed your Premium quota.`,
|
||||
items: ['Unlimited fair use'],
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Storage',
|
||||
items: [
|
||||
'10GB',
|
||||
'<div class="flex flex-col"><div>100GB</div><div class="text-xs text-neutral-content">$5 per 100GB thereafter</div></div>',
|
||||
],
|
||||
info: `Storage is pooled per account. The first 100GB is included. After that, you are billed $5 for each subsequent 100GB block or partial block of 100GB used.`,
|
||||
},
|
||||
{
|
||||
name: 'Max inodes',
|
||||
items: ['1k', '100k'],
|
||||
info: `inodes are pooled per account. An inode is typically a file or directory. The inode limit counts toward any file you or your users upload.`,
|
||||
items: ['Unlimited fair use'],
|
||||
},
|
||||
{
|
||||
name: 'CPU',
|
||||
items: ['Unlimited', 'Unlimited'],
|
||||
info: `Your PocketBase instance runs in a Docker container. While there are practical limits, we do not meter or throttle CPU usage.`,
|
||||
items: ['Unlimited fair use'],
|
||||
},
|
||||
{
|
||||
name: 'FTP access',
|
||||
items: ['YesBlock', 'YesBlock'],
|
||||
items: ['YesBlock'],
|
||||
},
|
||||
{
|
||||
name: 'Run every version of PocketBase',
|
||||
items: ['YesBlock', 'YesBlock'],
|
||||
items: ['YesBlock'],
|
||||
info: `We support the latest patch of every minor release of PocketBase.`,
|
||||
},
|
||||
{
|
||||
name: 'Secure infrastructure',
|
||||
items: ['YesBlock', 'YesBlock'],
|
||||
items: ['YesBlock'],
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Community Discord',
|
||||
items: ['YesBlock', 'YesBlock'],
|
||||
items: ['YesBlock'],
|
||||
},
|
||||
{
|
||||
name: 'Custom Domains',
|
||||
items: ['NoBlock', 'YesBlock'],
|
||||
items: ['YesBlock'],
|
||||
},
|
||||
{ name: 'Pro Discord', items: ['NoBlock', 'YesBlock'] },
|
||||
{ name: 'Pro Discord', items: ['YesBlock'] },
|
||||
]
|
||||
</script>
|
||||
|
||||
@@ -101,39 +78,25 @@
|
||||
<div
|
||||
class="flex justify-center items-center flex-col space-y-10 p-10 bg-emerald-950"
|
||||
>
|
||||
<div class="text-2xl text-center">Feature comparison</div>
|
||||
<div class="text-2xl text-center">Features</div>
|
||||
|
||||
<table class="hidden md:table border-spacing-x-8 max-w-[354px] md:max-w-md">
|
||||
<thead class="table-header-group">
|
||||
<tr class=" text-left">
|
||||
<th class=" md:min-w-48"> </th>
|
||||
{#each plans as plan}
|
||||
<th class="text-center text-lg min-w-48">
|
||||
{plan.name}
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
<tr class="">
|
||||
<th class=""></th>
|
||||
{#each plans as plan}
|
||||
{#if !plan.price}
|
||||
<th class="text-center">Free Forever</th>
|
||||
{:else}
|
||||
<th>
|
||||
<div class="flex flex-col justify-center py-4">
|
||||
{#each plan.price as pPrice}
|
||||
<a
|
||||
href={$userStore && $isUserVerified
|
||||
? pPrice.link
|
||||
: `/login`}
|
||||
class="btn btn-sm btn-secondary text-base mb-2"
|
||||
>
|
||||
{pPrice.text}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</th>
|
||||
{/if}
|
||||
<th>
|
||||
<div class="flex flex-col justify-center py-4">
|
||||
{#each plan.price as pPrice}
|
||||
<a
|
||||
href={$userStore && $isUserVerified ? pPrice.link : `/login`}
|
||||
class="btn btn-sm btn-secondary text-base mb-2"
|
||||
>
|
||||
{pPrice.text}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -157,24 +120,18 @@
|
||||
<th class=" text-lg min-w-48">
|
||||
{plan.name}
|
||||
</th>
|
||||
{#if !plan.price}
|
||||
<th>Free Forever</th>
|
||||
{:else}
|
||||
<th>
|
||||
<div class="flex flex-col justify-center py-4">
|
||||
{#each plan.price as pPrice}
|
||||
<a
|
||||
href={$userStore && $isUserVerified
|
||||
? pPrice.link
|
||||
: `/login`}
|
||||
class="btn btn-xs w-40 btn-primary mb-2"
|
||||
>
|
||||
{pPrice.text}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</th>
|
||||
{/if}
|
||||
<th>
|
||||
<div class="flex flex-col justify-center py-4">
|
||||
{#each plan.price as pPrice}
|
||||
<a
|
||||
href={$userStore && $isUserVerified ? pPrice.link : `/login`}
|
||||
class="btn btn-xs w-40 btn-primary mb-2"
|
||||
>
|
||||
{pPrice.text}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
{/each}
|
||||
</thead>
|
||||
|
||||
Reference in New Issue
Block a user