diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-22 16:33:05 +0300 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-07-22 16:33:05 +0300 |
| commit | 6924fc24c8d7c4d9281492ff12de583ef26f8927 (patch) | |
| tree | 50fedb1340827f4626e66cb92e1efc8f6e281aad /src/components/widgets | |
| parent | 85a31139e7d11996da5de5d09ad3f821c60e232d (diff) | |
Add initial pricing
Diffstat (limited to 'src/components/widgets')
| -rw-r--r-- | src/components/widgets/Pricing.astro | 126 |
1 files changed, 63 insertions, 63 deletions
diff --git a/src/components/widgets/Pricing.astro b/src/components/widgets/Pricing.astro index 3f20b74..4ab5279 100644 --- a/src/components/widgets/Pricing.astro +++ b/src/components/widgets/Pricing.astro @@ -1,15 +1,15 @@ --- -import { Icon } from 'astro-icon/components'; -import Button from '~/components/ui/Button.astro'; +import type { Pricing as Props } from '~/types'; import Headline from '~/components/ui/Headline.astro'; import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; -import type { Pricing as Props } from '~/types'; +import Button from '~/components/ui/Button.astro'; const { - title = '', - subtitle = '', - tagline = '', - prices = [], + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + items = [], + actions = [], id, isDark = false, @@ -18,66 +18,66 @@ const { } = Astro.props; --- -<WidgetWrapper id={id} isDark={isDark} containerClass={`max-w-7xl mx-auto ${classes?.container ?? ''}`} bg={bg}> - <Headline title={title} subtitle={subtitle} tagline={tagline} /> - <div class="flex items-stretch justify-center"> - <div class="grid grid-cols-3 gap-4 dark:text-white sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3"> +<WidgetWrapper + id={id} + isDark={isDark} + containerClass={`max-w-7xl mx-auto ${classes?.container ?? ''}`} + bg={bg} +> + <Headline + title={title} + subtitle={subtitle} + tagline={tagline} + classes={{ + container: 'max-w-xl sm:mx-auto lg:max-w-2xl', + title: 'text-4xl md:text-5xl font-bold tracking-tighter mb-4 font-heading', + subtitle: 'max-w-3xl mx-auto sm:text-center text-xl text-muted dark:text-slate-400', + }} + /> + <div class="mt-12"> + <div class="row-gap-8 md:grid md:grid-cols-2 md:gap-8"> { - prices && - prices.map(({ title, subtitle, price, period, items, callToAction, hasRibbon = false, ribbonTitle }) => ( - <div class="col-span-3 mx-auto flex w-full sm:col-span-1 md:col-span-1 lg:col-span-1 xl:col-span-1 intersect-once motion-safe:md:intersect:animate-fade motion-safe:md:opacity-0 intersect-quarter"> - {price && period && ( - <div class="rounded-lg backdrop-blur border border-gray-200 dark:border-gray-700 bg-white dark:bg-slate-900 shadow px-6 py-8 flex w-full max-w-sm flex-col justify-between text-center"> - {hasRibbon && ribbonTitle && ( - <div class="absolute right-[-5px] 2xl:right-[-8px] rtl:right-auto rtl:left-[-8px] rtl:2xl:left-[-10px] top-[-5px] 2xl:top-[-10px] z-[1] h-[100px] w-[100px] overflow-hidden text-right"> - <span class="absolute top-[19px] right-[-21px] rtl:right-auto rtl:left-[-21px] block w-full rotate-45 rtl:-rotate-45 bg-green-700 text-center text-[10px] font-bold uppercase leading-5 text-white shadow-[0_3px_10px_-5px_rgba(0,0,0,0.3)] before:absolute before:left-0 before:top-full before:z-[-1] before:border-[3px] before:border-r-transparent before:border-b-transparent before:border-l-green-800 before:border-t-green-800 before:content-[''] after:absolute after:right-0 after:top-full after:z-[-1] after:border-[3px] after:border-l-transparent after:border-b-transparent after:border-r-green-800 after:border-t-green-800 after:content-['']"> - {ribbonTitle} - </span> - </div> - )} - <div class="px-2 py-0"> - {title && ( - <h3 class="text-center text-xl font-semibold uppercase leading-6 tracking-wider mb-2">{title}</h3> - )} - {subtitle && <p class="font-light sm:text-lg text-gray-600 dark:text-slate-400">{subtitle}</p>} - <div class="my-8"> - <div class="flex items-center justify-center text-center mb-1"> - <span class="text-5xl">$</span> - <span class="text-6xl font-extrabold">{price}</span> - </div> - <span class="text-base leading-6 lowercase text-gray-600 dark:text-slate-400">{period}</span> - </div> - {items && ( - <ul class="my-8 md:my-10 space-y-2 text-left"> - {items.map( - ({ description, icon }) => - description && ( - <li class="mb-1.5 flex items-start space-x-3 leading-7"> - <div class="rounded-full bg-primary mt-1"> - <Icon name={icon ? icon : 'tabler:check'} class="w-5 h-5 font-bold p-1 text-white" /> - </div> - <span>{description}</span> - </li> - ) - )} - </ul> - )} - </div> - {callToAction && ( - <div class={`flex justify-center`}> - {typeof callToAction === 'string' ? ( - <Fragment set:html={callToAction} /> - ) : ( - callToAction && - callToAction.href && <Button {...(hasRibbon ? { variant: 'primary' } : {})} {...callToAction} /> - )} - </div> - )} - </div> + items && items.length > 0 && items.map((item, index) => ( + <div class={index % 2 === 0 ? "mb-6 md:mb-0" : ""}> + <div class="mb-6"> + {item.title && ( + <h3 class="text-2xl font-bold tracking-tight dark:text-white sm:text-3xl mb-4">{item.title}</h3> + )} + <hr class="mb-4"> + {item.entries && item.entries.length > 0 && ( + <table class="w-full border-collapse"> + <tbody> + {item.entries.map((entry) => ( + <tr class="h-12"> + <td class="w-1/2 h-12 px-4 text-muted dark:text-slate-400" set:html={entry.description}></td> + <td class="w-1/2 text-right h-12 px-4 text-muted dark:text-slate-400">{entry.price}</td> + </tr> + ))} + </tbody> + </table> )} </div> - )) + </div> + )) } </div> </div> + + <div class="mt-12 text-center"> + {await Astro.slots.render('disclaimer') && ( + <div class="text-xs text-muted dark:text-slate-400 mb-8" set:html={await Astro.slots.render('disclaimer')} /> + )} + + { + actions && actions.length > 0 && ( + <div class="max-w-xs sm:max-w-md m-auto flex flex-nowrap flex-col sm:flex-row sm:justify-center gap-4 mt-6"> + {actions.map((action) => ( + <div class="flex w-full sm:w-auto"> + <Button {...action} class="w-full sm:mb-0" /> + </div> + ))} + </div> + ) + } + </div> </WidgetWrapper> |
