add astro template for front #13

Merged
Clement merged 18 commits from feat/astro-template-for-front into master 2024-05-21 08:07:58 +00:00
9 changed files with 489 additions and 489 deletions
Showing only changes of commit c4f7d60016 - Show all commits

View File

@ -6,6 +6,7 @@ import type { CallToAction as Props } from '~/types';
const { const {
variant = 'secondary', variant = 'secondary',
target, target,
link,
text = Astro.slots.render('default'), text = Astro.slots.render('default'),
icon = '', icon = '',
class: className = '', class: className = '',
@ -31,6 +32,7 @@ const variants = {
<a <a
class={twMerge(variants[variant] || '', className)} class={twMerge(variants[variant] || '', className)}
{...(target ? { target: target, rel: 'noopener noreferrer' } : {})} {...(target ? { target: target, rel: 'noopener noreferrer' } : {})}
{...(link ? { href: link} : {})}
{...rest} {...rest}
> >
<Fragment set:html={text} /> <Fragment set:html={text} />

View File

@ -1,166 +1,173 @@
--- ---
import { Icon } from 'astro-icon/components'; import { Icon } from 'astro-icon/components'
import Logo from '~/components/Logo.astro'; import Logo from 'components/Logo.astro'
import ToggleTheme from '~/components/common/ToggleTheme.astro'; import ToggleTheme from 'components/common/ToggleTheme.astro'
import ToggleMenu from '~/components/common/ToggleMenu.astro'; import ToggleMenu from 'components/common/ToggleMenu.astro'
import Button from '~/components/ui/Button.astro'; import Button from 'components/ui/Button.astro'
import { getHomePermalink } from '~/utils/permalinks'; import { getHomePermalink } from 'utils/permalinks'
import { trimSlash, getAsset } from '~/utils/permalinks'; import { trimSlash, getAsset } from 'utils/permalinks'
import type { CallToAction } from '~/types'; import type { CallToAction } from 'types'
const pb = Astro.locals.pb
const connected = pb.authStore.isValid
interface Link { interface Link {
text?: string; text?: string
href?: string; href?: string
ariaLabel?: string; ariaLabel?: string
icon?: string; icon?: string
} }
interface ActionLink extends CallToAction {} interface ActionLink extends CallToAction {}
interface MenuLink extends Link { interface MenuLink extends Link {
links?: Array<MenuLink>; links?: Array<MenuLink>
} }
export interface Props { export interface Props {
id?: string; id?: string
links?: Array<MenuLink>; links?: Array<MenuLink>
actions?: Array<ActionLink>; actions?: Array<ActionLink>
isSticky?: boolean; isSticky?: boolean
isDark?: boolean; isDark?: boolean
isFullWidth?: boolean; isFullWidth?: boolean
showToggleTheme?: boolean; showToggleTheme?: boolean
showRssFeed?: boolean; showRssFeed?: boolean
position?: string; position?: string
} }
const { const {
id = 'header', id = 'header',
links = [], links = [],
actions = [], actions = [],
isSticky = false, isSticky = false,
isDark = false, isDark = false,
isFullWidth = false, isFullWidth = false,
showToggleTheme = false, showToggleTheme = false,
showRssFeed = false, showRssFeed = false,
position = 'center', position = 'center',
} = Astro.props; } = Astro.props
const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`; const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`
--- ---
<header <header
class:list={[ class:list={[
{ sticky: isSticky, relative: !isSticky, dark: isDark }, { sticky: isSticky, relative: !isSticky, dark: isDark },
'top-0 z-40 flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out', 'top-0 z-40 flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out',
]} ]}
{...isSticky ? { 'data-aw-sticky-header': true } : {}} {...isSticky ? { 'data-aw-sticky-header': true } : {}}
{...id ? { id } : {}} {...id ? { id } : {}}
> >
<div class="absolute inset-0"></div> <div class="absolute inset-0"></div>
<div <div
class:list={[ class:list={[
'relative text-default py-3 px-3 md:px-6 mx-auto w-full', 'relative text-default py-3 px-3 md:px-6 mx-auto w-full',
{ {
'md:flex md:justify-between': position !== 'center', 'md:flex md:justify-between': position !== 'center',
}, },
{ {
'md:grid md:grid-cols-3 md:items-center': position === 'center', 'md:grid md:grid-cols-3 md:items-center': position === 'center',
}, },
{ {
'max-w-7xl': !isFullWidth, 'max-w-7xl': !isFullWidth,
}, },
]} ]}
> >
<div class:list={[{ 'mr-auto rtl:mr-0 rtl:ml-auto': position === 'right' }, 'flex justify-between']}> <div class:list={[{ 'mr-auto rtl:mr-0 rtl:ml-auto': position === 'right' }, 'flex justify-between']}>
<a class="flex items-center" href={getHomePermalink()}> <a class="flex items-center" href={getHomePermalink()}>
<Logo /> <Logo />
</a> </a>
<div class="flex items-center md:hidden"> <div class="flex items-center md:hidden">
<ToggleMenu /> <ToggleMenu />
</div> </div>
</div> </div>
<nav <nav
class="items-center w-full md:w-auto hidden md:flex md:mx-5 text-default overflow-y-auto overflow-x-hidden md:overflow-y-visible md:overflow-x-auto md:justify-self-center" class="items-center w-full md:w-auto hidden md:flex md:mx-5 text-default overflow-y-auto overflow-x-hidden md:overflow-y-visible md:overflow-x-auto md:justify-self-center"
aria-label="Main navigation" aria-label="Main navigation"
> >
<ul <ul
class="flex flex-col md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center" class="flex flex-col md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center"
> >
{ {
links.map(({ text, href, links }) => ( links.map(({ text, href, links }) => (
<li class={links?.length ? 'dropdown' : ''}> <li class={links?.length ? 'dropdown' : ''}>
{links?.length ? ( {links?.length ? (
<> <>
<button type="button" class="hover:text-link dark:hover:text-white px-4 py-3 flex items-center"> <button type="button" class="hover:text-link dark:hover:text-white px-4 py-3 flex items-center">
{text}{' '} {text}{' '}
<Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5 hidden md:inline" /> <Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5 hidden md:inline" />
</button> </button>
<ul class="dropdown-menu md:backdrop-blur-md dark:md:bg-dark rounded md:absolute pl-4 md:pl-0 md:hidden font-medium md:bg-white/90 md:min-w-[200px] drop-shadow-xl"> <ul class="dropdown-menu md:backdrop-blur-md dark:md:bg-dark rounded md:absolute pl-4 md:pl-0 md:hidden font-medium md:bg-white/90 md:min-w-[200px] drop-shadow-xl">
{links.map(({ text: text2, href: href2 }) => ( {links.map(({ text: text2, href: href2 }) => (
<li> <li>
<a <a
class:list={[ class:list={[
'first:rounded-t last:rounded-b md:hover:bg-gray-100 hover:text-link dark:hover:text-white dark:hover:bg-gray-700 py-2 px-5 block whitespace-no-wrap', 'first:rounded-t last:rounded-b md:hover:bg-gray-100 hover:text-link dark:hover:text-white dark:hover:bg-gray-700 py-2 px-5 block whitespace-no-wrap',
{ 'aw-link-active': href2 === currentPath }, { 'aw-link-active': href2 === currentPath },
]} ]}
href={href2} href={href2}
> >
{text2} {text2}
</a> </a>
</li> </li>
))} ))}
</ul> </ul>
</> </>
) : ( ) : (
<a <a
class:list={[ class:list={[
'hover:text-link dark:hover:text-white px-4 py-3 flex items-center', 'hover:text-link dark:hover:text-white px-4 py-3 flex items-center',
{ 'aw-link-active': href === currentPath }, { 'aw-link-active': href === currentPath },
]} ]}
href={href} href={href}
> >
{text} {text}
</a> </a>
)} )}
</li> </li>
)) ))
} }
</ul> </ul>
</nav> </nav>
<div <div
class:list={[ class:list={[
{ 'ml-auto rtl:ml-0 rtl:mr-auto': position === 'left' }, { 'ml-auto rtl:ml-0 rtl:mr-auto': position === 'left' },
'hidden md:self-center md:flex items-center md:mb-0 fixed w-full md:w-auto md:static justify-end left-0 rtl:left-auto rtl:right-0 bottom-0 p-3 md:p-0 md:justify-self-end', 'hidden md:self-center md:flex items-center md:mb-0 fixed w-full md:w-auto md:static justify-end left-0 rtl:left-auto rtl:right-0 bottom-0 p-3 md:p-0 md:justify-self-end',
]} ]}
> >
<div class="items-center flex justify-between w-full md:w-auto"> <div class="items-center flex justify-between w-full md:w-auto">
<div class="flex"> <div class="flex">
{showToggleTheme && <ToggleTheme iconClass="w-6 h-6 md:w-5 md:h-5 md:inline-block" />} {showToggleTheme && <ToggleTheme iconClass="w-6 h-6 md:w-5 md:h-5 md:inline-block" />}
{ {
showRssFeed && ( showRssFeed && (
<a <a
class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center" class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
aria-label="RSS Feed" aria-label="RSS Feed"
href={getAsset('/rss.xml')} href={getAsset('/rss.xml')}
> >
<Icon name="tabler:rss" class="w-5 h-5" /> <Icon name="tabler:rss" class="w-5 h-5" />
</a> </a>
) )
} }
</div> </div>
{ { !connected && (
actions?.length ? ( <span class="ml-4 rtl:ml-0 rtl:mr-4">
<span class="ml-4 rtl:ml-0 rtl:mr-4"> <Button link='/account/login' variant='primary' class="ml-2 py-2.5 px-5.5 md:px-6 font-semibold shadow-none text-sm w-auto">
{actions.map((btnProps) => ( Connexion
<Button {...btnProps} class="ml-2 py-2.5 px-5.5 md:px-6 font-semibold shadow-none text-sm w-auto" /> </Button>
))} <Button link='/account/register' variant='secondary' class="ml-2 py-2.5 px-5.5 md:px-6 font-semibold shadow-none text-sm w-auto">
</span> Inscription
) : ( </Button>
'' </span>
) )}
} { connected && (
</div> <Button link='/account/logout' variant='primary' class="ml-2 py-2.5 px-5.5 md:px-6 font-semibold shadow-none text-sm w-auto">
</div> Déconnexion
</div> </Button>
)}
</div>
</div>
</div>
</header> </header>

View File

@ -21,7 +21,7 @@ const { metadata } = Astro.props;
<Announcement /> <Announcement />
</slot> --> </slot> -->
<slot name="header"> <slot name="header">
<Header {...headerData} isSticky showRssFeed showToggleTheme /> <Header {...headerData} isSticky showToggleTheme />
</slot> </slot>
<main> <main>
<slot /> <slot />

View File

@ -1,183 +1,166 @@
import { getPermalink, getBlogPermalink, getAsset } from './utils/permalinks'; import { getPermalink, getBlogPermalink } from './utils/permalinks'
export const headerData = { export const headerData = {
links: [ links: [
{ {
text: 'Homes', text: 'Homes',
links: [ links: [
{ {
text: 'SaaS', text: 'SaaS',
href: getPermalink('/homes/saas'), href: getPermalink('/homes/saas'),
}, },
{ {
text: 'Startup', text: 'Startup',
href: getPermalink('/homes/startup'), href: getPermalink('/homes/startup'),
}, },
{ {
text: 'Mobile App', text: 'Mobile App',
href: getPermalink('/homes/mobile-app'), href: getPermalink('/homes/mobile-app'),
}, },
{ {
text: 'Personal', text: 'Personal',
href: getPermalink('/homes/personal'), href: getPermalink('/homes/personal'),
}, },
], ],
}, },
{ {
text: 'Pages', text: 'Pages',
links: [ links: [
{ {
text: 'Features (Anchor Link)', text: 'Features (Anchor Link)',
href: getPermalink('/#features'), href: getPermalink('/#features'),
}, },
{ {
text: 'Services', text: 'Services',
href: getPermalink('/services'), href: getPermalink('/services'),
}, },
{ {
text: 'Pricing', text: 'Pricing',
href: getPermalink('/pricing'), href: getPermalink('/pricing'),
}, },
{ {
text: 'About us', text: 'About us',
href: getPermalink('/about'), href: getPermalink('/about'),
}, },
{ {
text: 'Contact', text: 'Contact',
href: getPermalink('/contact'), href: getPermalink('/contact'),
}, },
{ {
text: 'Terms', text: 'Terms',
href: getPermalink('/terms'), href: getPermalink('/terms'),
}, },
{ {
text: 'Privacy policy', text: 'Privacy policy',
href: getPermalink('/privacy'), href: getPermalink('/privacy'),
}, },
], ],
}, },
{ {
text: 'Landing', text: 'Landing',
links: [ links: [
{ {
text: 'Lead Generation', text: 'Lead Generation',
href: getPermalink('/landing/lead-generation'), href: getPermalink('/landing/lead-generation'),
}, },
{ {
text: 'Long-form Sales', text: 'Long-form Sales',
href: getPermalink('/landing/sales'), href: getPermalink('/landing/sales'),
}, },
{ {
text: 'Click-Through', text: 'Click-Through',
href: getPermalink('/landing/click-through'), href: getPermalink('/landing/click-through'),
}, },
{ {
text: 'Product Details (or Services)', text: 'Product Details (or Services)',
href: getPermalink('/landing/product'), href: getPermalink('/landing/product'),
}, },
{ {
text: 'Coming Soon or Pre-Launch', text: 'Coming Soon or Pre-Launch',
href: getPermalink('/landing/pre-launch'), href: getPermalink('/landing/pre-launch'),
}, },
{ {
text: 'Subscription', text: 'Subscription',
href: getPermalink('/landing/subscription'), href: getPermalink('/landing/subscription'),
}, },
], ],
}, },
{ {
text: 'Blog', text: 'Blog',
links: [ links: [
{ {
text: 'Blog List', text: 'Blog List',
href: getBlogPermalink(), href: getBlogPermalink(),
}, },
{ {
text: 'Article', text: 'Article',
href: getPermalink('get-started-website-with-astro-tailwind-css', 'post'), href: getPermalink(
}, 'get-started-website-with-astro-tailwind-css',
{ 'post'
text: 'Article (with MDX)', ),
href: getPermalink('markdown-elements-demo-post', 'post'), },
}, {
{ text: 'Article (with MDX)',
text: 'Category Page', href: getPermalink('markdown-elements-demo-post', 'post'),
href: getPermalink('tutorials', 'category'), },
}, {
{ text: 'Category Page',
text: 'Tag Page', href: getPermalink('tutorials', 'category'),
href: getPermalink('astro', 'tag'), },
}, {
], text: 'Tag Page',
}, href: getPermalink('astro', 'tag'),
{ },
text: 'Widgets', ],
href: '#', },
}, {
], text: 'Widgets',
actions: [{ text: 'Download', href: 'https://github.com/onwidget/astrowind', target: '_blank' }], href: '#',
}; },
],
// actions: [
// {
// text: 'Connexion',
// href: '',
// target: '_blank',
// },
// ],
}
export const footerData = { export const footerData = {
links: [ links: [
{ {
title: 'Product', title: 'Product',
links: [ links: [
{ text: 'Features', href: '#' }, { text: 'Features', href: '#' },
{ text: 'Security', href: '#' }, { text: 'Security', href: '#' },
{ text: 'Team', href: '#' }, ],
{ text: 'Enterprise', href: '#' }, },
{ text: 'Customer stories', href: '#' }, {
{ text: 'Pricing', href: '#' }, title: 'Platform',
{ text: 'Resources', href: '#' }, links: [
], { text: 'Developer API', href: '#' },
}, { text: 'Partners', href: '#' },
{ ],
title: 'Platform', },
links: [ {
{ text: 'Developer API', href: '#' }, title: 'Support',
{ text: 'Partners', href: '#' }, links: [
{ text: 'Atom', href: '#' }, { text: 'Docs', href: '#' },
{ text: 'Electron', href: '#' }, { text: 'Community Forum', href: '#' },
{ text: 'AstroWind Desktop', href: '#' }, ],
], },
}, {
{ title: 'Company',
title: 'Support', links: [
links: [ { text: 'About', href: '#' },
{ text: 'Docs', href: '#' }, { text: 'Blog', href: '#' },
{ text: 'Community Forum', href: '#' }, ],
{ text: 'Professional Services', href: '#' }, },
{ text: 'Skills', href: '#' }, ],
{ text: 'Status', href: '#' }, secondaryLinks: [
], { text: 'Terms', href: getPermalink('/terms') },
}, { text: 'Privacy Policy', href: getPermalink('/privacy') },
{ ],
title: 'Company', socialLinks:[]
links: [ }
{ text: 'About', href: '#' },
{ text: 'Blog', href: '#' },
{ text: 'Careers', href: '#' },
{ text: 'Press', href: '#' },
{ text: 'Inclusion', href: '#' },
{ text: 'Social Impact', href: '#' },
{ text: 'Shop', href: '#' },
],
},
],
secondaryLinks: [
{ text: 'Terms', href: getPermalink('/terms') },
{ text: 'Privacy Policy', href: getPermalink('/privacy') },
],
socialLinks: [
{ ariaLabel: 'X', icon: 'tabler:brand-x', href: '#' },
{ ariaLabel: 'Instagram', icon: 'tabler:brand-instagram', href: '#' },
{ ariaLabel: 'Facebook', icon: 'tabler:brand-facebook', href: '#' },
{ ariaLabel: 'RSS', icon: 'tabler:rss', href: getAsset('/rss.xml') },
{ ariaLabel: 'Github', icon: 'tabler:brand-github', href: 'https://github.com/onwidget/astrowind' },
],
footNote: `
<img class="w-5 h-5 md:w-6 md:h-6 md:-mt-0.5 bg-cover mr-1.5 rtl:mr-0 rtl:ml-1.5 float-left rtl:float-right rounded-sm" src="https://onwidget.com/favicon/favicon-32x32.png" alt="onWidget logo" loading="lazy"></img>
Made by <a class="text-blue-600 underline dark:text-muted" href="https://onwidget.com/"> onWidget</a> · All rights reserved.
`,
};

View File

@ -1,5 +1,6 @@
--- ---
import Layout from 'layouts/Layout.astro' import Layout from 'layouts/PageLayout.astro';
//import Layout from 'layouts/Layout.astro';
import PocketBase from 'pocketbase' import PocketBase from 'pocketbase'
@ -11,11 +12,12 @@ if(!auth.isValid){
return Astro.redirect("/account/login"); return Astro.redirect("/account/login");
} }
const metadata = {
title: 'Account',
ignoreTitleTemplate: true,
};
--- ---
<Layout title="Account setting"> <Layout metadata={metadata}>
<h1>Bonjour {user!.username}</h1> <h1>Bonjour {user!.username}</h1>
<div>
<a href="/account/logout">deconnexion</a>
</div>
</Layout> </Layout>

View File

@ -1,5 +1,6 @@
--- ---
import Layout from "layouts/Layout.astro"; import Layout from 'layouts/PageLayout.astro';
//import Layout from 'layouts/Layout.astro';
import AstroUtils from "libs/AstroUtils"; import AstroUtils from "libs/AstroUtils";
import PocketBase from 'pocketbase' import PocketBase from 'pocketbase'
@ -29,9 +30,14 @@ const res = await AstroUtils.wrap(async () => {
return Astro.redirect("/account/login");// route('/account/login', {message: 'Compte invalide, valider les identifiants'})) //XXX: comprendre comment le system de route fonctionne return Astro.redirect("/account/login");// route('/account/login', {message: 'Compte invalide, valider les identifiants'})) //XXX: comprendre comment le system de route fonctionne
} }
}) })
const metadata = {
title: 'Login',
ignoreTitleTemplate: true,
};
--- ---
<Layout title="login"> <Layout metadata={metadata}>
<form id="account-creation" method="post" enctype="multipart/form-data"> <form id="account-creation" method="post" enctype="multipart/form-data">
<input required name="username" placeholder="Pseudo ou email"/> <input required name="username" placeholder="Pseudo ou email"/>
<input required name="password" type="password" placeholder="Mot de passe" /> <input required name="password" type="password" placeholder="Mot de passe" />

View File

@ -8,6 +8,6 @@ if(pb.authStore.isValid){
pb.authStore.clear() pb.authStore.clear()
} }
return Astro.redirect('/account/login') return Astro.redirect('/')
--- ---

View File

@ -58,7 +58,7 @@ await AstroUtils.wrap(async () => {
}) })
const metadata = { const metadata = {
title: 'register', title: 'Register',
ignoreTitleTemplate: true, ignoreTitleTemplate: true,
}; };
--- ---

306
front/src/types.d.ts vendored
View File

@ -1,288 +1,288 @@
import type { AstroComponentFactory } from 'astro/runtime/server/index.js'; import type { AstroComponentFactory } from 'astro/runtime/server/index.js'
import type { HTMLAttributes, ImageMetadata } from 'astro/types'; import type { HTMLAttributes, ImageMetadata } from 'astro/types'
export interface Post { export interface Post {
/** A unique ID number that identifies a post. */ /** A unique ID number that identifies a post. */
id: string; id: string
/** A posts unique slug part of the posts URL based on its name, i.e. a post called “My Sample Page” has a slug “my-sample-page”. */ /** A posts unique slug part of the posts URL based on its name, i.e. a post called “My Sample Page” has a slug “my-sample-page”. */
slug: string; slug: string
/** */ /** */
permalink: string; permalink: string
/** */ /** */
publishDate: Date; publishDate: Date
/** */ /** */
updateDate?: Date; updateDate?: Date
/** */ /** */
title: string; title: string
/** Optional summary of post content. */ /** Optional summary of post content. */
excerpt?: string; excerpt?: string
/** */ /** */
image?: ImageMetadata | string; image?: ImageMetadata | string
/** */ /** */
category?: Taxonomy; category?: Taxonomy
/** */ /** */
tags?: Taxonomy[]; tags?: Taxonomy[]
/** */ /** */
author?: string; author?: string
/** */ /** */
metadata?: MetaData; metadata?: MetaData
/** */ /** */
draft?: boolean; draft?: boolean
/** */ /** */
Content?: AstroComponentFactory; Content?: AstroComponentFactory
content?: string; content?: string
/** */ /** */
readingTime?: number; readingTime?: number
} }
export interface Taxonomy { export interface Taxonomy {
slug: string; slug: string
title: string; title: string
} }
export interface MetaData { export interface MetaData {
title?: string; title?: string
ignoreTitleTemplate?: boolean; ignoreTitleTemplate?: boolean
canonical?: string; canonical?: string
robots?: MetaDataRobots; robots?: MetaDataRobots
description?: string; description?: string
openGraph?: MetaDataOpenGraph; openGraph?: MetaDataOpenGraph
twitter?: MetaDataTwitter; twitter?: MetaDataTwitter
} }
export interface MetaDataRobots { export interface MetaDataRobots {
index?: boolean; index?: boolean
follow?: boolean; follow?: boolean
} }
export interface MetaDataImage { export interface MetaDataImage {
url: string; url: string
width?: number; width?: number
height?: number; height?: number
} }
export interface MetaDataOpenGraph { export interface MetaDataOpenGraph {
url?: string; url?: string
siteName?: string; siteName?: string
images?: Array<MetaDataImage>; images?: Array<MetaDataImage>
locale?: string; locale?: string
type?: string; type?: string
} }
export interface MetaDataTwitter { export interface MetaDataTwitter {
handle?: string; handle?: string
site?: string; site?: string
cardType?: string; cardType?: string
} }
export interface Image { export interface Image {
src: string; src: string
alt?: string; alt?: string
} }
export interface Video { export interface Video {
src: string; src: string
type?: string; type?: string
} }
export interface Widget { export interface Widget {
id?: string; id?: string
isDark?: boolean; isDark?: boolean
bg?: string; bg?: string
classes?: Record<string, string | Record<string, string>>; classes?: Record<string, string | Record<string, string>>
} }
export interface Headline { export interface Headline {
title?: string; title?: string
subtitle?: string; subtitle?: string
tagline?: string; tagline?: string
classes?: Record<string, string>; classes?: Record<string, string>
} }
interface TeamMember { interface TeamMember {
name?: string; name?: string
job?: string; job?: string
image?: Image; image?: Image
socials?: Array<Social>; socials?: Array<Social>
description?: string; description?: string
classes?: Record<string, string>; classes?: Record<string, string>
} }
interface Social { interface Social {
icon?: string; icon?: string
href?: string; href?: string
} }
export interface Stat { export interface Stat {
amount?: number | string; amount?: number | string
title?: string; title?: string
icon?: string; icon?: string
} }
export interface Item { export interface Item {
title?: string; title?: string
description?: string; description?: string
icon?: string; icon?: string
classes?: Record<string, string>; classes?: Record<string, string>
callToAction?: CallToAction; callToAction?: CallToAction
image?: Image; image?: Image
} }
export interface Price { export interface Price {
title?: string; title?: string
subtitle?: string; subtitle?: string
description?: string; description?: string
price?: number | string; price?: number | string
period?: string; period?: string
items?: Array<Item>; items?: Array<Item>
callToAction?: CallToAction; callToAction?: CallToAction
hasRibbon?: boolean; hasRibbon?: boolean
ribbonTitle?: string; ribbonTitle?: string
} }
export interface Testimonial { export interface Testimonial {
title?: string; title?: string
testimonial?: string; testimonial?: string
name?: string; name?: string
job?: string; job?: string
image?: string | unknown; image?: string | unknown
} }
export interface Input { export interface Input {
type: HTMLInputTypeAttribute; type: HTMLInputTypeAttribute
name: string; name: string
label?: string; label?: string
autocomplete?: string; autocomplete?: string
placeholder?: string; placeholder?: string
} }
export interface Textarea { export interface Textarea {
label?: string; label?: string
name?: string; name?: string
placeholder?: string; placeholder?: string
rows?: number; rows?: number
} }
export interface Disclaimer { export interface Disclaimer {
label?: string; label?: string
} }
// COMPONENTS // COMPONENTS
export interface CallToAction extends Omit<HTMLAttributes<'a'>, 'slot'> { export interface CallToAction extends Omit<HTMLAttributes<'a'>, 'slot'> {
variant?: 'primary' | 'secondary' | 'tertiary' | 'link'; variant?: 'primary' | 'secondary' | 'tertiary' | 'link'
text?: string; text?: string
icon?: string; icon?: string
classes?: Record<string, string>; classes?: Record<string, string>
type?: 'button' | 'submit' | 'reset'; type?: 'button' | 'submit' | 'reset'
} }
export interface ItemGrid { export interface ItemGrid {
items?: Array<Item>; items?: Array<Item>
columns?: number; columns?: number
defaultIcon?: string; defaultIcon?: string
classes?: Record<string, string>; classes?: Record<string, string>
} }
export interface Collapse { export interface Collapse {
iconUp?: string; iconUp?: string
iconDown?: string; iconDown?: string
items?: Array<Item>; items?: Array<Item>
columns?: number; columns?: number
classes?: Record<string, string>; classes?: Record<string, string>
} }
export interface Form { export interface Form {
inputs?: Array<Input>; inputs?: Array<Input>
textarea?: Textarea; textarea?: Textarea
disclaimer?: Disclaimer; disclaimer?: Disclaimer
button?: string; button?: string
description?: string; description?: string
} }
// WIDGETS // WIDGETS
export interface Hero extends Omit<Headline, 'classes'>, Widget { export interface Hero extends Omit<Headline, 'classes'>, Widget {
content?: string; content?: string
image?: string | unknown; image?: string | unknown
callToAction1?: CallToAction; callToAction1?: CallToAction
callToAction2?: CallToAction; callToAction2?: CallToAction
isReversed?: boolean; isReversed?: boolean
} }
export interface Team extends Omit<Headline, 'classes'>, Widget { export interface Team extends Omit<Headline, 'classes'>, Widget {
team?: Array<TeamMember>; team?: Array<TeamMember>
} }
export interface Stats extends Omit<Headline, 'classes'>, Widget { export interface Stats extends Omit<Headline, 'classes'>, Widget {
stats?: Array<Stat>; stats?: Array<Stat>
} }
export interface Pricing extends Omit<Headline, 'classes'>, Widget { export interface Pricing extends Omit<Headline, 'classes'>, Widget {
prices?: Array<Price>; prices?: Array<Price>
} }
export interface Testimonials extends Omit<Headline, 'classes'>, Widget { export interface Testimonials extends Omit<Headline, 'classes'>, Widget {
testimonials?: Array<Testimonial>; testimonials?: Array<Testimonial>
callToAction?: CallToAction; callToAction?: CallToAction
} }
export interface Brands extends Omit<Headline, 'classes'>, Widget { export interface Brands extends Omit<Headline, 'classes'>, Widget {
icons?: Array<string>; icons?: Array<string>
images?: Array<Image>; images?: Array<Image>
} }
export interface Features extends Omit<Headline, 'classes'>, Widget { export interface Features extends Omit<Headline, 'classes'>, Widget {
image?: string | unknown; image?: string | unknown
video?: Video; video?: Video
items?: Array<Item>; items?: Array<Item>
columns?: number; columns?: number
defaultIcon?: string; defaultIcon?: string
callToAction1?: CallToAction; callToAction1?: CallToAction
callToAction2?: CallToAction; callToAction2?: CallToAction
isReversed?: boolean; isReversed?: boolean
isBeforeContent?: boolean; isBeforeContent?: boolean
isAfterContent?: boolean; isAfterContent?: boolean
} }
export interface Faqs extends Omit<Headline, 'classes'>, Widget { export interface Faqs extends Omit<Headline, 'classes'>, Widget {
iconUp?: string; iconUp?: string
iconDown?: string; iconDown?: string
items?: Array<Item>; items?: Array<Item>
columns?: number; columns?: number
} }
export interface Steps extends Omit<Headline, 'classes'>, Widget { export interface Steps extends Omit<Headline, 'classes'>, Widget {
items: Array<{ items: Array<{
title: string; title: string
description?: string; description?: string
icon?: string; icon?: string
classes?: Record<string, string>; classes?: Record<string, string>
}>; }>
callToAction?: string | CallToAction; callToAction?: string | CallToAction
image?: string | Image; image?: string | Image
isReversed?: boolean; isReversed?: boolean
} }
export interface Content extends Omit<Headline, 'classes'>, Widget { export interface Content extends Omit<Headline, 'classes'>, Widget {
content?: string; content?: string
image?: string | unknown; image?: string | unknown
items?: Array<Item>; items?: Array<Item>
columns?: number; columns?: number
isReversed?: boolean; isReversed?: boolean
isAfterContent?: boolean; isAfterContent?: boolean
callToAction?: CallToAction; callToAction?: CallToAction
} }
export interface Contact extends Omit<Headline, 'classes'>, Form, Widget {} export interface Contact extends Omit<Headline, 'classes'>, Form, Widget {}