From fcc2f4704e39b0e69b377cc138f75027721dac22 Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Tue, 22 Jul 2025 15:08:37 +0300 Subject: Initial template --- src/components/widgets/Announcement.astro | 16 ++++ src/components/widgets/BlogHighlightedPosts.astro | 64 +++++++++++++++ src/components/widgets/BlogLatestPosts.astro | 63 +++++++++++++++ src/components/widgets/Brands.astro | 38 +++++++++ src/components/widgets/CallToAction.astro | 58 +++++++++++++ src/components/widgets/CallToActionImage.astro | 73 +++++++++++++++++ src/components/widgets/Contact.astro | 40 +++++++++ src/components/widgets/Content.astro | 94 +++++++++++++++++++++ src/components/widgets/FAQs.astro | 33 ++++++++ src/components/widgets/Features.astro | 36 +++++++++ src/components/widgets/Features2.astro | 38 +++++++++ src/components/widgets/Features3.astro | 70 ++++++++++++++++ src/components/widgets/Footer.astro | 61 ++++++++++++++ src/components/widgets/Header.astro | 14 ++++ src/components/widgets/Hero.astro | 99 +++++++++++++++++++++++ src/components/widgets/Hero2.astro | 99 +++++++++++++++++++++++ src/components/widgets/HeroText.astro | 86 ++++++++++++++++++++ src/components/widgets/Note.astro | 23 ++++++ src/components/widgets/Pricing.astro | 83 +++++++++++++++++++ src/components/widgets/Stats.astro | 46 +++++++++++ src/components/widgets/Steps.astro | 59 ++++++++++++++ src/components/widgets/Steps2.astro | 79 ++++++++++++++++++ src/components/widgets/Testimonials.astro | 75 +++++++++++++++++ 23 files changed, 1347 insertions(+) create mode 100644 src/components/widgets/Announcement.astro create mode 100644 src/components/widgets/BlogHighlightedPosts.astro create mode 100644 src/components/widgets/BlogLatestPosts.astro create mode 100644 src/components/widgets/Brands.astro create mode 100644 src/components/widgets/CallToAction.astro create mode 100644 src/components/widgets/CallToActionImage.astro create mode 100644 src/components/widgets/Contact.astro create mode 100644 src/components/widgets/Content.astro create mode 100644 src/components/widgets/FAQs.astro create mode 100644 src/components/widgets/Features.astro create mode 100644 src/components/widgets/Features2.astro create mode 100644 src/components/widgets/Features3.astro create mode 100644 src/components/widgets/Footer.astro create mode 100644 src/components/widgets/Header.astro create mode 100644 src/components/widgets/Hero.astro create mode 100644 src/components/widgets/Hero2.astro create mode 100644 src/components/widgets/HeroText.astro create mode 100644 src/components/widgets/Note.astro create mode 100644 src/components/widgets/Pricing.astro create mode 100644 src/components/widgets/Stats.astro create mode 100644 src/components/widgets/Steps.astro create mode 100644 src/components/widgets/Steps2.astro create mode 100644 src/components/widgets/Testimonials.astro (limited to 'src/components/widgets') diff --git a/src/components/widgets/Announcement.astro b/src/components/widgets/Announcement.astro new file mode 100644 index 0000000..8e4bf78 --- /dev/null +++ b/src/components/widgets/Announcement.astro @@ -0,0 +1,16 @@ +--- + +--- + + diff --git a/src/components/widgets/BlogHighlightedPosts.astro b/src/components/widgets/BlogHighlightedPosts.astro new file mode 100644 index 0000000..75f35a9 --- /dev/null +++ b/src/components/widgets/BlogHighlightedPosts.astro @@ -0,0 +1,64 @@ +--- +import { APP_BLOG } from 'astrowind:config'; + +import Grid from '~/components/blog/Grid.astro'; + +import { getBlogPermalink } from '~/utils/permalinks'; +import { findPostsByIds } from '~/utils/blog'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Widget } from '~/types'; + +export interface Props extends Widget { + title?: string; + linkText?: string; + linkUrl?: string | URL; + information?: string; + postIds: string[]; +} + +const { + title = await Astro.slots.render('title'), + linkText = 'View all posts', + linkUrl = getBlogPermalink(), + information = await Astro.slots.render('information'), + postIds = [], + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; + +const posts = APP_BLOG.isEnabled ? await findPostsByIds(postIds) : []; +--- + +{ + APP_BLOG.isEnabled ? ( + +
+ {title && ( +
+

+ {APP_BLOG.list.isEnabled && linkText && linkUrl && ( + + {linkText} » + + )} +

+ )} + + {information &&

} +

+ + +
+ ) : ( + + ) +} diff --git a/src/components/widgets/BlogLatestPosts.astro b/src/components/widgets/BlogLatestPosts.astro new file mode 100644 index 0000000..28f66d4 --- /dev/null +++ b/src/components/widgets/BlogLatestPosts.astro @@ -0,0 +1,63 @@ +--- +import { APP_BLOG } from 'astrowind:config'; + +import Grid from '~/components/blog/Grid.astro'; + +import { getBlogPermalink } from '~/utils/permalinks'; +import { findLatestPosts } from '~/utils/blog'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Widget } from '~/types'; +import Button from '~/components/ui/Button.astro'; + +export interface Props extends Widget { + title?: string; + linkText?: string; + linkUrl?: string | URL; + information?: string; + count?: number; +} + +const { + title = await Astro.slots.render('title'), + linkText = 'View all posts', + linkUrl = getBlogPermalink(), + information = await Astro.slots.render('information'), + count = 4, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; + +const posts = APP_BLOG.isEnabled ? await findLatestPosts({ count }) : []; +--- + +{ + APP_BLOG.isEnabled ? ( + +
+ {title && ( +
+

+ {APP_BLOG.list.isEnabled && linkText && linkUrl && ( + + )} +

+ )} + + {information &&

} +

+ + +
+ ) : ( + + ) +} diff --git a/src/components/widgets/Brands.astro b/src/components/widgets/Brands.astro new file mode 100644 index 0000000..7e42ae1 --- /dev/null +++ b/src/components/widgets/Brands.astro @@ -0,0 +1,38 @@ +--- +import { Icon } from 'astro-icon/components'; +import type { Brands as Props } from '~/types'; + +import Image from '~/components/common/Image.astro'; +import Headline from '~/components/ui/Headline.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +const { + title = '', + subtitle = '', + tagline = '', + icons = [], + images = [], + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + + +
+ {icons && icons.map((icon) => )} + { + images && + images.map( + (image) => + image.src && ( +
+ {image.alt +
+ ) + ) + } +
+
diff --git a/src/components/widgets/CallToAction.astro b/src/components/widgets/CallToAction.astro new file mode 100644 index 0000000..f51aa91 --- /dev/null +++ b/src/components/widgets/CallToAction.astro @@ -0,0 +1,58 @@ +--- +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { CallToAction, Widget } from '~/types'; +import Headline from '~/components/ui/Headline.astro'; +import Button from '~/components/ui/Button.astro'; + +interface Props extends Widget { + title?: string; + subtitle?: string; + tagline?: string; + callToAction?: CallToAction; + actions?: string | CallToAction[]; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + actions = await Astro.slots.render('actions'), + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + +
+ + { + actions && ( +
+ {Array.isArray(actions) ? ( + actions.map((action) => ( +
+
+ )) + ) : ( + + )} +
+ ) + } +
+
diff --git a/src/components/widgets/CallToActionImage.astro b/src/components/widgets/CallToActionImage.astro new file mode 100644 index 0000000..df13145 --- /dev/null +++ b/src/components/widgets/CallToActionImage.astro @@ -0,0 +1,73 @@ +--- +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Widget } from '~/types'; +import Headline from '~/components/ui/Headline.astro'; +import Image from '~/components/common/Image.astro'; + +interface Props extends Widget { + title?: string; + subtitle?: string; + tagline?: string; + image?: { + src: string; + alt: string; + href?: string; + target?: string; + }; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + image, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + +
+ + { + image && ( +
+ {image.href ? ( + + {image.alt} + + ) : ( + {image.alt} + )} +
+ ) + } +
+
\ No newline at end of file diff --git a/src/components/widgets/Contact.astro b/src/components/widgets/Contact.astro new file mode 100644 index 0000000..122f4b0 --- /dev/null +++ b/src/components/widgets/Contact.astro @@ -0,0 +1,40 @@ +--- +import FormContainer from '~/components/ui/Form.astro'; +import Headline from '~/components/ui/Headline.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Contact as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + inputs, + textarea, + disclaimer, + button, + description, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + + + { + inputs && ( +
+ +
+ ) + } +
diff --git a/src/components/widgets/Content.astro b/src/components/widgets/Content.astro new file mode 100644 index 0000000..694a198 --- /dev/null +++ b/src/components/widgets/Content.astro @@ -0,0 +1,94 @@ +--- +import type { Content as Props } from '~/types'; +import Headline from '~/components/ui/Headline.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Image from '~/components/common/Image.astro'; +import Button from '~/components/ui/Button.astro'; +import ItemGrid from '~/components/ui/ItemGrid.astro'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + content = await Astro.slots.render('content'), + callToAction, + items = [], + columns, + image = await Astro.slots.render('image'), + isReversed = false, + isAfterContent = false, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + +
+
+
+ {content &&
} + + { + callToAction && ( +
+
+ ) + } + + +
+ +
+
+ diff --git a/src/components/widgets/FAQs.astro b/src/components/widgets/FAQs.astro new file mode 100644 index 0000000..cba9762 --- /dev/null +++ b/src/components/widgets/FAQs.astro @@ -0,0 +1,33 @@ +--- +import Headline from '~/components/ui/Headline.astro'; +import ItemGrid from '~/components/ui/ItemGrid.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Faqs as Props } from '~/types'; + +const { + title = '', + subtitle = '', + tagline = '', + items = [], + columns = 2, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + + + diff --git a/src/components/widgets/Features.astro b/src/components/widgets/Features.astro new file mode 100644 index 0000000..8f42b62 --- /dev/null +++ b/src/components/widgets/Features.astro @@ -0,0 +1,36 @@ +--- +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import ItemGrid from '~/components/ui/ItemGrid.astro'; +import Headline from '~/components/ui/Headline.astro'; +import type { Features as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + items = [], + columns = 2, + + defaultIcon, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + } /> + ) ?? {}), + }} + /> + diff --git a/src/components/widgets/Features2.astro b/src/components/widgets/Features2.astro new file mode 100644 index 0000000..282337e --- /dev/null +++ b/src/components/widgets/Features2.astro @@ -0,0 +1,38 @@ +--- +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Headline from '~/components/ui/Headline.astro'; +import ItemGrid2 from '~/components/ui/ItemGrid2.astro'; +import type { Features as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + items = [], + columns = 3, + defaultIcon, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + } /> + ) ?? {}), + }} + /> + diff --git a/src/components/widgets/Features3.astro b/src/components/widgets/Features3.astro new file mode 100644 index 0000000..62ab475 --- /dev/null +++ b/src/components/widgets/Features3.astro @@ -0,0 +1,70 @@ +--- +import Headline from '~/components/ui/Headline.astro'; +import ItemGrid from '~/components/ui/ItemGrid.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Image from '~/components/common/Image.astro'; +import type { Features as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + image, + items = [], + columns, + defaultIcon, + isBeforeContent, + isAfterContent, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + } /> + + + + + diff --git a/src/components/widgets/Footer.astro b/src/components/widgets/Footer.astro new file mode 100644 index 0000000..70cac54 --- /dev/null +++ b/src/components/widgets/Footer.astro @@ -0,0 +1,61 @@ +--- +import { Icon } from 'astro-icon/components'; +import { SITE } from 'astrowind:config'; +import { getHomePermalink } from '~/utils/permalinks'; + +interface Link { + text?: string; + href?: string; + ariaLabel?: string; + icon?: string; +} + +interface Links { + title?: string; + links: Array; +} + +export interface Props { + links: Array; + secondaryLinks: Array; + socialLinks: Array; + footNote?: string; + theme?: string; +} + +const { socialLinks = [], secondaryLinks = [], links = [], footNote = '', theme = 'light' } = Astro.props; +--- + +
+ +
+
+ { + socialLinks?.length ? ( +
    + {socialLinks.map(({ ariaLabel, href, text, icon }) => ( +
  • + + {icon && } + + +
  • + ))} +
+ ) : ( + '' + ) + } + +
+ +
+
+
+
diff --git a/src/components/widgets/Header.astro b/src/components/widgets/Header.astro new file mode 100644 index 0000000..0064a30 --- /dev/null +++ b/src/components/widgets/Header.astro @@ -0,0 +1,14 @@ +--- +import { Icon } from 'astro-icon/components'; +--- + +
+ +
diff --git a/src/components/widgets/Hero.astro b/src/components/widgets/Hero.astro new file mode 100644 index 0000000..cbd1154 --- /dev/null +++ b/src/components/widgets/Hero.astro @@ -0,0 +1,99 @@ +--- +import Image from '~/components/common/Image.astro'; +import Button from '~/components/ui/Button.astro'; + +import type { Hero as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + + content = await Astro.slots.render('content'), + actions = await Astro.slots.render('actions'), + image = await Astro.slots.render('image'), + + id, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + +
+ +
+
+
+
+ { + tagline && ( +

+ ) + } + { + title && ( +

+ ) + } +
+ { + subtitle && ( +

+ ) + } + { + actions && ( +

+ {Array.isArray(actions) ? ( + actions.map((action) => ( +
+
+ )) + ) : ( + + )} +
+ ) + } +
+ {content && } +

+
+ { + image && ( +
+ {typeof image === 'string' ? ( + + ) : ( + + )} +
+ ) + } +
+
+
+
diff --git a/src/components/widgets/Hero2.astro b/src/components/widgets/Hero2.astro new file mode 100644 index 0000000..e92870d --- /dev/null +++ b/src/components/widgets/Hero2.astro @@ -0,0 +1,99 @@ +--- +import Image from '~/components/common/Image.astro'; +import Button from '~/components/ui/Button.astro'; + +import type { Hero as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + + content = await Astro.slots.render('content'), + actions = await Astro.slots.render('actions'), + image = await Astro.slots.render('image'), + + id, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + +
+ +
+
+
+
+ { + tagline && ( +

+ ) + } + { + title && ( +

+ ) + } +
+ { + subtitle && ( +

+ ) + } + + { + actions && ( +

+ {Array.isArray(actions) ? ( + actions.map((action) => ( +
+
+ )) + ) : ( + + )} +
+ ) + } +
+ {content && } +

+
+ { + image && ( +
+ {typeof image === 'string' ? ( + + ) : ( + + )} +
+ ) + } +
+
+
+
diff --git a/src/components/widgets/HeroText.astro b/src/components/widgets/HeroText.astro new file mode 100644 index 0000000..be2a1b6 --- /dev/null +++ b/src/components/widgets/HeroText.astro @@ -0,0 +1,86 @@ +--- +import type { CallToAction } from '~/types'; +import Button from '~/components/ui/Button.astro'; + +export interface Props { + title?: string; + subtitle?: string; + tagline?: string; + content?: string; + callToAction?: string | CallToAction; + callToAction2?: string | CallToAction; +} + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + content = await Astro.slots.render('content'), + callToAction = await Astro.slots.render('callToAction'), + callToAction2 = await Astro.slots.render('callToAction2'), +} = Astro.props; +--- + +
+ +
+
+
+
+ { + tagline && ( +

+ ) + } + { + title && ( +

+ ) + } +
+ { + subtitle && ( +

+ ) + } +

+ { + callToAction && ( +
+ {typeof callToAction === 'string' ? ( + + ) : ( +
+ ) + } + { + callToAction2 && ( +
+ {typeof callToAction2 === 'string' ? ( + + ) : ( +
+ ) + } +
+
+ {content && } +

+
+
+
diff --git a/src/components/widgets/Note.astro b/src/components/widgets/Note.astro new file mode 100644 index 0000000..3f43881 --- /dev/null +++ b/src/components/widgets/Note.astro @@ -0,0 +1,23 @@ +--- +import { Icon } from 'astro-icon/components'; + +export interface Props { + icon?: string; + title?: string; + description?: string; +} + +const { + icon = 'tabler:info-square', + title = await Astro.slots.render('title'), + description = await Astro.slots.render('description'), +} = Astro.props; +--- + +
+
+ + + +
+
diff --git a/src/components/widgets/Pricing.astro b/src/components/widgets/Pricing.astro new file mode 100644 index 0000000..3f20b74 --- /dev/null +++ b/src/components/widgets/Pricing.astro @@ -0,0 +1,83 @@ +--- +import { Icon } from 'astro-icon/components'; +import Button from '~/components/ui/Button.astro'; +import Headline from '~/components/ui/Headline.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import type { Pricing as Props } from '~/types'; + +const { + title = '', + subtitle = '', + tagline = '', + prices = [], + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + +
+
+ { + prices && + prices.map(({ title, subtitle, price, period, items, callToAction, hasRibbon = false, ribbonTitle }) => ( +
+ {price && period && ( +
+ {hasRibbon && ribbonTitle && ( +
+ + {ribbonTitle} + +
+ )} +
+ {title && ( +

{title}

+ )} + {subtitle &&

{subtitle}

} +
+
+ $ + {price} +
+ {period} +
+ {items && ( +
    + {items.map( + ({ description, icon }) => + description && ( +
  • +
    + +
    + {description} +
  • + ) + )} +
+ )} +
+ {callToAction && ( +
+ {typeof callToAction === 'string' ? ( + + ) : ( + callToAction && + callToAction.href &&
+ )} +
+ )} +
+ )) + } +
+
+
diff --git a/src/components/widgets/Stats.astro b/src/components/widgets/Stats.astro new file mode 100644 index 0000000..bf76ea0 --- /dev/null +++ b/src/components/widgets/Stats.astro @@ -0,0 +1,46 @@ +--- +import type { Stats as Props } from '~/types'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Headline from '~/components/ui/Headline.astro'; +import { Icon } from 'astro-icon/components'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + stats = [], + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + +
+ { + stats && + stats.map(({ amount, title, icon }) => ( +
+ {icon && ( +
+ +
+ )} + {amount && ( +
+ {amount} +
+ )} + {title && ( +
+ {title} +
+ )} +
+ )) + } +
+
diff --git a/src/components/widgets/Steps.astro b/src/components/widgets/Steps.astro new file mode 100644 index 0000000..3c65bf6 --- /dev/null +++ b/src/components/widgets/Steps.astro @@ -0,0 +1,59 @@ +--- +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Timeline from '~/components/ui/Timeline.astro'; +import Headline from '~/components/ui/Headline.astro'; +import Image from '~/components/common/Image.astro'; +import type { Steps as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline = await Astro.slots.render('tagline'), + items = [], + image = await Astro.slots.render('image'), + isReversed = false, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + +
+
+ + } /> +
+ { + image && ( +
+ {typeof image === 'string' ? ( + + ) : ( + {image?.alt + )} +
+ ) + } +
+
diff --git a/src/components/widgets/Steps2.astro b/src/components/widgets/Steps2.astro new file mode 100644 index 0000000..0891663 --- /dev/null +++ b/src/components/widgets/Steps2.astro @@ -0,0 +1,79 @@ +--- +import { Icon } from 'astro-icon/components'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Headline from '~/components/ui/Headline.astro'; +import Button from '~/components/ui/Button.astro'; +import type { Steps as Props } from '~/types'; + +const { + title = await Astro.slots.render('title'), + subtitle = await Astro.slots.render('subtitle'), + tagline, + callToAction = await Astro.slots.render('callToAction'), + items = [], + isReversed = false, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; + +// Function to make email addresses clickable +function makeEmailsClickable(text: string | undefined): string { + if (!text) return ''; + const emailRegex = /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g; + return text.replace(emailRegex, '$1'); +} +--- + + +
+
+ + +
+ { + typeof callToAction === 'string' ? ( + + ) : ( + callToAction && + callToAction.text && + callToAction.href &&
+
+
+
    + { + items && items.length + ? items.map(({ title: title2, description, icon }, index) => ( +
  • +
    + + {icon ? : index + 1} + +
    +
    +

    +

    +

    +
  • + )) + : '' + } +
+
+
+
diff --git a/src/components/widgets/Testimonials.astro b/src/components/widgets/Testimonials.astro new file mode 100644 index 0000000..11db7b5 --- /dev/null +++ b/src/components/widgets/Testimonials.astro @@ -0,0 +1,75 @@ +--- +import Headline from '~/components/ui/Headline.astro'; +import WidgetWrapper from '~/components/ui/WidgetWrapper.astro'; +import Button from '~/components/ui/Button.astro'; +import Image from '~/components/common/Image.astro'; +import type { Testimonials as Props } from '~/types'; + +const { + title = '', + subtitle = '', + tagline = '', + testimonials = [], + callToAction, + + id, + isDark = false, + classes = {}, + bg = await Astro.slots.render('bg'), +} = Astro.props; +--- + + + + +
+ { + testimonials && + testimonials.map(({ title, testimonial, name, job, image }) => ( +
+
+ {title &&

{title}

} + {testimonial && ( +
+

" {testimonial} "

+
+ )} + +
+ +
+ {image && ( +
+ {typeof image === 'string' ? ( + + ) : ( + + )} +
+ )} + +
+ {name &&

{name}

} + {job &&

{job}

} +
+
+
+
+ )) + } +
+ { + callToAction && ( +
+
+ ) + } +
-- cgit v1.2.3