|
2 | 2 | import { BillingPlan } from '$lib/constants'; |
3 | 3 | import { formatCurrency } from '$lib/helpers/numbers'; |
4 | 4 | import { currentPlan, organization } from '$lib/stores/organization'; |
5 | | - import { Badge, Layout, Typography } from '@appwrite.io/pink-svelte'; |
| 5 | + import { Badge, Layout, Tooltip, Typography } from '@appwrite.io/pink-svelte'; |
6 | 6 | import { LabelCard } from '..'; |
7 | 7 | import type { Plan } from '$lib/sdk/billing'; |
8 | 8 | import { page } from '$app/state'; |
9 | 9 | import { ProfileMode, resolvedProfile } from '$lib/profiles/index.svelte'; |
10 | 10 | import { InputSelect } from '$lib/elements/forms'; |
| 11 | + import { isFreePlan, isPaidPlan } from '$lib/helpers/billing'; |
11 | 12 |
|
12 | 13 | export let disabled = false; |
13 | 14 | export let isNewOrg = false; |
|
113 | 114 | function handleTierChange(group: PlanGroup) { |
114 | 115 | billingPlan = selectedTiers[group.key] as BillingPlan; |
115 | 116 | } |
| 117 | +
|
| 118 | + function shouldShowTooltip(plan: Plan) { |
| 119 | + if (isPaidPlan(plan.$id)) return true; |
| 120 | + else return !anyOrgFree; |
| 121 | + } |
116 | 122 | </script> |
117 | 123 |
|
118 | 124 | <Layout.Stack> |
119 | 125 | {#each groupedPlans as group (group.key)} |
120 | 126 | {@const basePlan = group.plans[0]} |
121 | | - <LabelCard |
122 | | - name="plan" |
123 | | - bind:group={billingPlan} |
124 | | - disabled={!selfService || (basePlan.$id === BillingPlan.FREE && anyOrgFree) || disabled} |
125 | | - tooltipShow={basePlan.$id === BillingPlan.FREE && anyOrgFree} |
126 | | - value={group.isGrouped ? selectedTiers[group.key] || basePlan.$id : basePlan.$id} |
127 | | - title={basePlan.name}> |
128 | | - <svelte:fragment slot="action"> |
129 | | - {#if group.plans.some((plan) => $organization?.billingPlan === plan.$id) && !isNewOrg} |
130 | | - <Badge variant="secondary" size="xs" content="Current plan" /> |
131 | | - {/if} |
132 | | - </svelte:fragment> |
133 | | - |
134 | | - <Layout.Stack direction="column" gap="m"> |
135 | | - <Layout.Stack direction="column" gap="xxs"> |
136 | | - <Typography.Caption variant="400"> |
137 | | - {basePlan.desc} |
138 | | - </Typography.Caption> |
139 | | - |
140 | | - {#if !group.isGrouped} |
141 | | - <Typography.Text> |
142 | | - {@const isZeroPrice = (basePlan.price ?? 0) <= 0} |
143 | | - {@const price = formatCurrency(basePlan.price ?? 0)} |
144 | | - {#if resolvedProfile.id === ProfileMode.STUDIO} |
145 | | - {getPlanLabel(basePlan)} |
146 | | - {:else} |
147 | | - {isZeroPrice ? price : getPlanLabel(basePlan)} |
148 | | - {/if} |
149 | | - </Typography.Text> |
| 127 | + <Tooltip disabled={shouldShowTooltip(basePlan)} maxWidth="fit-content"> |
| 128 | + <LabelCard |
| 129 | + name="plan" |
| 130 | + bind:group={billingPlan} |
| 131 | + disabled={!selfService || (isFreePlan(basePlan.$id) && anyOrgFree) || disabled} |
| 132 | + tooltipShow={isFreePlan(basePlan.$id) && anyOrgFree} |
| 133 | + value={group.isGrouped ? selectedTiers[group.key] || basePlan.$id : basePlan.$id} |
| 134 | + title={basePlan.name}> |
| 135 | + <svelte:fragment slot="action"> |
| 136 | + {#if group.plans.some((plan) => $organization?.billingPlan === plan.$id) && !isNewOrg} |
| 137 | + <Badge variant="secondary" size="xs" content="Current plan" /> |
| 138 | + {/if} |
| 139 | + </svelte:fragment> |
| 140 | + |
| 141 | + <Layout.Stack direction="column" gap="m"> |
| 142 | + <Layout.Stack direction="column" gap="xxs"> |
| 143 | + <Typography.Caption variant="400"> |
| 144 | + {basePlan.desc} |
| 145 | + </Typography.Caption> |
| 146 | + |
| 147 | + {#if !group.isGrouped} |
| 148 | + <Typography.Text> |
| 149 | + {@const isZeroPrice = (basePlan.price ?? 0) <= 0} |
| 150 | + {@const price = formatCurrency(basePlan.price ?? 0)} |
| 151 | + {#if resolvedProfile.id === ProfileMode.STUDIO} |
| 152 | + {getPlanLabel(basePlan)} |
| 153 | + {:else} |
| 154 | + {isZeroPrice ? price : getPlanLabel(basePlan)} |
| 155 | + {/if} |
| 156 | + </Typography.Text> |
| 157 | + {/if} |
| 158 | + </Layout.Stack> |
| 159 | + |
| 160 | + {#if group.isGrouped} |
| 161 | + <InputSelect |
| 162 | + id="tier-{group.key}" |
| 163 | + bind:value={selectedTiers[group.key]} |
| 164 | + on:change={() => handleTierChange(group)} |
| 165 | + options={group.tierOptions} /> |
150 | 166 | {/if} |
151 | 167 | </Layout.Stack> |
| 168 | + </LabelCard> |
152 | 169 |
|
153 | | - {#if group.isGrouped} |
154 | | - <InputSelect |
155 | | - id="tier-{group.key}" |
156 | | - bind:value={selectedTiers[group.key]} |
157 | | - on:change={() => handleTierChange(group)} |
158 | | - options={group.tierOptions} /> |
159 | | - {/if} |
160 | | - </Layout.Stack> |
161 | | - </LabelCard> |
| 170 | + <svelte:fragment slot="tooltip"> |
| 171 | + Only 1 free organization is allowed per account. |
| 172 | + </svelte:fragment> |
| 173 | + </Tooltip> |
162 | 174 | {/each} |
163 | 175 |
|
164 | 176 | {#if $currentPlan && !currentPlanInList} |
|
0 commit comments