fix(dashboard): make upgrade plan modal mobile responsive (#736)
* fix(dashboard): make upgrade plan modal mobile responsive - Constrain modal height and enable scrolling on small screens - Anchor modal near top on mobile instead of vertical centering - Stack success-state buttons and use full-width cards in the grid - Reduce pricing card padding and adjust toggle badge on narrow viewports Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> * chore(ui): regenerate output.css for pricing responsive classes Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
877b45b1a3
commit
51f90bf450
@@ -101,22 +101,27 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Dialog.Root bind:open onOpenChange={handleOpenChange}>
|
<Dialog.Root bind:open onOpenChange={handleOpenChange}>
|
||||||
<Dialog.Content class="max-w-5xl! {upgraded || isConfirming ? 'max-w-[600px]!' : ''}">
|
<Dialog.Content
|
||||||
|
class="top-[4dvh]! max-h-[92dvh] w-[96vw] translate-y-0! overflow-y-auto p-4 sm:top-[50%]! sm:max-h-none sm:translate-y-[-50%]! sm:p-6 {upgraded ||
|
||||||
|
isConfirming
|
||||||
|
? 'max-w-[min(600px,96vw)]!'
|
||||||
|
: 'max-w-5xl!'}"
|
||||||
|
>
|
||||||
<Dialog.Header>
|
<Dialog.Header>
|
||||||
<Dialog.Title>{$t('pricing.modal.heading')}</Dialog.Title>
|
<Dialog.Title>{$t('pricing.modal.heading')}</Dialog.Title>
|
||||||
</Dialog.Header>
|
</Dialog.Header>
|
||||||
{#if upgraded}
|
{#if upgraded}
|
||||||
<div class="animate-icon flex w-full flex-col items-center justify-center gap-4">
|
<div class="animate-icon flex w-full flex-col items-center justify-center gap-4 px-1">
|
||||||
<RocketIcon class="rocket-launch my-3 size-6" color="var(--primary)" />
|
<RocketIcon class="rocket-launch my-3 size-6" color="var(--primary)" />
|
||||||
<p class="text-lg">{$t('pricing.modal.thanks')}</p>
|
<p class="text-center text-lg">{$t('pricing.modal.thanks')}</p>
|
||||||
<p class="ui:mb-4 ui:text-center">
|
<p class="ui:mb-4 ui:text-center">
|
||||||
{$t('pricing.modal.plan')}
|
{$t('pricing.modal.plan')}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex w-full flex-col gap-3 sm:w-auto sm:flex-row sm:items-center">
|
||||||
<Button variant="outline" onclick={onClose}>
|
<Button class="w-full sm:w-auto" variant="outline" onclick={onClose}>
|
||||||
{$t('pricing.modal.close')}
|
{$t('pricing.modal.close')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="default" onclick={onLearnMore}>
|
<Button class="w-full sm:w-auto" variant="default" onclick={onLearnMore}>
|
||||||
{$t('pricing.modal.learn')}
|
{$t('pricing.modal.learn')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -128,8 +133,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex h-full flex-col items-center justify-center">
|
<div class="flex flex-col items-center">
|
||||||
<div class="ui:mb-6">
|
<div class="ui:mb-4 ui:w-full ui:max-w-sm ui:px-2 ui:sm:mb-6 ui:sm:max-w-none ui:sm:px-4">
|
||||||
<PricingToggle
|
<PricingToggle
|
||||||
bind:isYearly={isYearlyPlan}
|
bind:isYearly={isYearlyPlan}
|
||||||
monthlyLabel={$t('pricing.modal.monthly')}
|
monthlyLabel={$t('pricing.modal.monthly')}
|
||||||
@@ -137,7 +142,7 @@
|
|||||||
saveLabel={$t('pricing.modal.save')}
|
saveLabel={$t('pricing.modal.save')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-6 grid w-full grid-cols-1 gap-6 overflow-y-auto p-2 md:grid-cols-3 md:overflow-y-visible">
|
<div class="grid w-full grid-cols-1 gap-4 md:grid-cols-3 md:gap-6">
|
||||||
{#each planNames as planName}
|
{#each planNames as planName}
|
||||||
{@const plan = PLANS[planName]}
|
{@const plan = PLANS[planName]}
|
||||||
{@const isPopular = planName === 'EARLY_ADOPTER'}
|
{@const isPopular = planName === 'EARLY_ADOPTER'}
|
||||||
@@ -148,6 +153,7 @@
|
|||||||
{isYearlyPlan}
|
{isYearlyPlan}
|
||||||
{isLoadingPlan}
|
{isLoadingPlan}
|
||||||
{handleClick}
|
{handleClick}
|
||||||
|
className="w-full max-w-none!"
|
||||||
popularLabel={$t('pricing.modal.popular')}
|
popularLabel={$t('pricing.modal.popular')}
|
||||||
perOrgLabel={$t('pricing.modal.per_org')}
|
perOrgLabel={$t('pricing.modal.per_org')}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
class={cn(
|
class={cn(
|
||||||
'ui:relative ui:flex ui:max-w-sm ui:flex-col ui:rounded-lg ui:border ui:border-border ui:bg-card ui:p-8',
|
'ui:relative ui:flex ui:max-w-sm ui:flex-col ui:rounded-lg ui:border ui:border-border ui:bg-card ui:p-4 ui:sm:p-8',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
{#snippet children(isHovered: boolean)}
|
{#snippet children(isHovered: boolean)}
|
||||||
<Button
|
<Button
|
||||||
variant={isPopular ? 'default' : 'outline'}
|
variant={isPopular ? 'default' : 'outline'}
|
||||||
class="ui:w-full ui:py-4 ui:text-base ui:transition-all"
|
class="ui:w-full ui:py-3 ui:text-base ui:transition-all ui:sm:py-4"
|
||||||
disabled={isDisabled || isLoading}
|
disabled={isDisabled || isLoading}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="ui:relative ui:z-10 ui:flex ui:items-center ui:rounded-full ui:border ui:p-1 ui:bg-white ui:dark:bg-slate-950 ui:dark:border-slate-800"
|
class="ui:relative ui:z-10 ui:mx-auto ui:flex ui:w-fit ui:max-w-full ui:items-center ui:rounded-full ui:border ui:p-1 ui:bg-white ui:dark:bg-slate-950 ui:dark:border-slate-800"
|
||||||
>
|
>
|
||||||
{@render period_button(!isYearly, true)}
|
{@render period_button(!isYearly, true)}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
{#snippet children(isHovered)}
|
{#snippet children(isHovered)}
|
||||||
<Badge
|
<Badge
|
||||||
variant="default"
|
variant="default"
|
||||||
class="ui:absolute ui:-top-3 ui:-right-4 ui:rotate-5 ui:shadow-2xl ui:bg-linear-to-r ui:from-pink-500 ui:to-orange-500 ui:px-2 ui:py-0.5"
|
class="ui:absolute ui:-top-3 ui:right-0 ui:rotate-5 ui:shadow-2xl ui:bg-linear-to-r ui:from-pink-500 ui:to-orange-500 ui:px-2 ui:py-0.5 ui:sm:-right-4"
|
||||||
>
|
>
|
||||||
<PremiumIcon size={8} {isHovered} class="ui:text-white! ui:mr-1" />
|
<PremiumIcon size={8} {isHovered} class="ui:text-white! ui:mr-1" />
|
||||||
<span class="ui:text-[10px] ui:font-bold ui:text-white">{saveLabel}</span>
|
<span class="ui:text-[10px] ui:font-bold ui:text-white">{saveLabel}</span>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user