summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2025-07-22 16:33:05 +0300
committerDawid Rycerz <dawid@rycerz.xyz>2025-07-22 16:33:05 +0300
commit6924fc24c8d7c4d9281492ff12de583ef26f8927 (patch)
tree50fedb1340827f4626e66cb92e1efc8f6e281aad /src/components
parent85a31139e7d11996da5de5d09ad3f821c60e232d (diff)
Add initial pricing
Diffstat (limited to 'src/components')
-rw-r--r--src/components/widgets/Pricing.astro126
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>