Skip to content

Commit

Permalink
Merge pull request mantinedev#10 from widgeter/new-components
Browse files Browse the repository at this point in the history
Include a pricing page
  • Loading branch information
prototypa authored Feb 24, 2023
2 parents 323f7dc + 7792ded commit a66e3d9
Show file tree
Hide file tree
Showing 11 changed files with 397 additions and 79 deletions.
17 changes: 17 additions & 0 deletions app/pricing/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Pricing from '~/components/widgets/Pricing';
import Comparison from '~/components/widgets/Comparison';
import FAQs3 from '~/components/widgets/FAQs3';
import CallToAction from '~/components/widgets/CallToAction';

const Page = () => {
return (
<>
<Pricing />
<Comparison />
<FAQs3 />
<CallToAction />
</>
);
};

export default Page;
56 changes: 56 additions & 0 deletions src/components/common/Collapse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client';

import { useState } from 'react';
import { CollapseProps } from '~/shared/types';

const Collapse = ({ items, classCollapseItem, iconUp, iconDown }: CollapseProps) => {
const [toggle, setToggle] = useState<boolean>(true);
const [activeIndex, setActiveIndex] = useState<undefined | number>(undefined);

const handleSetIndex = (index: number) => {
if (activeIndex !== index) {
setActiveIndex(index);
setToggle(!toggle);
} else {
setActiveIndex(undefined);
setToggle(!toggle);
}
};

return (
<>
{items.map(({ title, description }, index) => (
<div
key={`accordion-${index}`}
onClick={() => handleSetIndex(index)}
className="mx-auto max-w-3xl select-none bg-transparent text-base text-gray-700"
>
<div className={classCollapseItem}>
<div
className="align-center flex justify-between"
id={`accordion__heading-${index}`}
aria-disabled="false"
aria-expanded="false"
aria-controls={`accordion__panel-${index}`}
role="button"
>
<h2 className="w-full pr-2 text-lg font-medium leading-6 text-gray-900 dark:text-slate-300">{title}</h2>
{activeIndex === index ? iconUp : iconDown}
</div>
{activeIndex === index && (
<div
className="mt-3 select-none"
aria-labelledby={`accordion__heading-${index}`}
id={`accordion__panel-${index}`}
>
<p className="mt-2 text-gray-600 dark:text-slate-400">{description}</p>
</div>
)}
</div>
</div>
))}
</>
);
};

export default Collapse;
10 changes: 7 additions & 3 deletions src/components/common/HeaderWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { Header } from '~/shared/types';

const HeaderWidget = (props: { header: Header; titleClassname: string }) => {
const { header, titleClassname } = props;
const { title, subtitle, highlight } = header;
const { title, subtitle, highlight, position } = header;

return (
<div className="mb-4 text-center">
<div className="mb-4">
{(title || subtitle || highlight) && (
<div className="mb-6 max-w-3xl text-center sm:text-center md:mx-auto md:mb-12">
<div
className={`mb-6 max-w-3xl text-center ${
position === 'left' ? 'sm:text-left' : position === 'right' ? 'sm:text-right' : 'sm:text-center'
} md:mx-auto md:mb-12`}
>
{highlight && (
<p className="text-base font-semibold uppercase tracking-wide text-primary-600 dark:text-primary-200">
{highlight}
Expand Down
6 changes: 3 additions & 3 deletions src/components/widgets/CallToAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ const CallToAction = () => {
const { title, subtitle, callToAction } = callToActionData;

return (
<section className="relative" id="callToActionOne">
<section className="bg-primary-50 dark:bg-slate-800" id="callToActionOne">
<div className="mx-auto max-w-6xl px-4 sm:px-6">
<div className="py-12 md:py-20">
<div className="mx-auto max-w-3xl rounded-md p-6 text-center shadow-xl dark:border dark:border-slate-600 dark:shadow-none">
<div className="pt-4 pb-12 md:pb-20 md:pt-12">
<div className="card mx-auto max-w-3xl p-6 text-center">
{title && (
<h2 className="leading-tighter font-heading mb-4 text-4xl font-bold tracking-tighter md:text-4xl">
{title}
Expand Down
61 changes: 61 additions & 0 deletions src/components/widgets/Comparison.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { IconCheck, IconMinus } from '@tabler/icons-react';
import { comparisonData } from '~/shared/data';
import HeaderWidget from '../common/HeaderWidget';

const Comparison = () => {
const { header, columns } = comparisonData;

return (
<section id="comparison">
<div className="mx-auto max-w-6xl px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
{header && <HeaderWidget header={header} titleClassname="text-2xl sm:text-3xl" />}
<div className="relative ml-[-1em] flex overflow-x-auto md:pb-12">
{columns.map(({ title, items, link }, index) => (
<div
key={`column-content-${index}`}
className="relative mx-auto w-full min-w-fit max-w-3xl select-none border-r border-solid border-gray-300 px-4 py-4 first-of-type:sticky first-of-type:left-0 first-of-type:z-10 first-of-type:w-auto first-of-type:bg-white first-of-type:pl-6 last-of-type:border-none dark:border-slate-500 first-of-type:dark:bg-slate-900 md:px-5 md:first-of-type:w-full md:first-of-type:pl-5"
>
<h3
className={`mb-4 border-b border-solid border-gray-300 pb-4 text-lg font-medium uppercase leading-6 text-gray-900 dark:border-slate-500 dark:text-white ${
index === 0 ? 'text-left' : 'text-center'
}`}
>
{title}
</h3>
{items &&
items.map(({ title: title2 }, index2) => (
<div
key={`column-content-${index2}`}
className={`leading-7 text-gray-600 dark:text-slate-400 ${
index === 0 ? 'text-left' : 'text-center'
}`}
>
{(title2 as boolean) === true ? (
<IconCheck className="mt-2 w-full" />
) : (title2 as boolean) === false ? (
<IconMinus className="mt-2 w-full" />
) : index !== 0 ? (
<p className="mt-2">{title2}</p>
) : (
<h4 className="mt-2 text-lg">{title2}</h4>
)}
</div>
))}
{index !== 0 && (
<div className="mt-8 flex w-full uppercase sm:w-auto">
{link && (
<a href={link.href} className="btn btn-primary w-full sm:mb-0">
{link.label}
</a>
)}
</div>
)}
</div>
))}
</div>
</div>
</section>
);
};

export default Comparison;
61 changes: 8 additions & 53 deletions src/components/widgets/FAQs2.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,21 @@
'use client';

import { useState } from 'react';
import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';
import { faqsData } from '~/shared/data';
import HeaderWidget from '../common/HeaderWidget';
import Collapse from '../common/Collapse';
import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';

const FAQs2 = () => {
const { header, items } = faqsData;

const [toggle, setToggle] = useState<boolean>(true);
const [activeIndex, setActiveIndex] = useState<undefined | number>(undefined);

const handleSetIndex = (index: number) => {
if (activeIndex !== index) {
setActiveIndex(index);
setToggle(!toggle);
} else {
setActiveIndex(undefined);
setToggle(!toggle);
}
};

return (
<section id="faqsTwo">
<div className="mx-auto max-w-6xl px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
{header && <HeaderWidget header={header} titleClassname="text-3xl sm:text-4xl" />}
{items.map(({ title, description }, index) => (
<div
key={`accordion-${index}`}
onClick={() => handleSetIndex(index)}
className="mx-auto mb-2 max-w-3xl select-none rounded-md border border-gray-300 bg-transparent px-5 py-4 text-base text-gray-700 shadow-md"
>
<div className="py-1 px-3">
<div
className="align-center flex justify-between"
id={`accordion__heading-${index}`}
aria-disabled="false"
aria-expanded="false"
aria-controls={`accordion__panel-${index}`}
role="button"
>
<h2 className="text-lg font-medium leading-6 text-gray-900 dark:text-slate-300">{title}</h2>
<>
{activeIndex === index ? (
<IconChevronUp className="h-6 w-6 text-primary-600 dark:text-slate-200" />
) : (
<IconChevronDown className="h-6 w-6 text-primary-600 dark:text-slate-200" />
)}
</>
</div>
{activeIndex === index && (
<div
className="mt-3 select-none"
aria-labelledby={`accordion__heading-${index}`}
id={`accordion__panel-${index}`}
>
<p className="mt-2 text-gray-600 dark:text-slate-400">{description}</p>
</div>
)}
</div>
</div>
))}
<Collapse
items={items}
classCollapseItem="mb-2 rounded-md border border-gray-300 shadow-md md:px-6 py-4 px-5 md:py-5"
iconUp={<IconChevronUp className="h-6 w-6 text-primary-600 dark:text-slate-200" />}
iconDown={<IconChevronDown className="h-6 w-6 text-primary-600 dark:text-slate-200" />}
/>
</div>
</section>
);
Expand Down
39 changes: 39 additions & 0 deletions src/components/widgets/FAQs3.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { faqs3Data } from '~/shared/data';
import HeaderWidget from '../common/HeaderWidget';
import Collapse from '../common/Collapse';
import { IconMinus, IconPlus } from '@tabler/icons-react';

const FAQs3 = () => {
const { header, items, link } = faqs3Data;

return (
<section className="bg-primary-50 dark:bg-slate-800" id="faqsThree">
<div className="mx-auto max-w-6xl px-4 py-16 sm:px-6 lg:px-8 lg:py-20">
<div className="flex items-stretch justify-center">
<div className="grid w-full md:grid-cols-3 md:items-center md:gap-4">
<div className="block h-full sm:flex sm:items-center sm:justify-between md:mt-10 md:block">
{header && <HeaderWidget header={header} titleClassname="text-3xl sm:text-4xl" />}
<div className="flex h-fit w-full justify-center uppercase sm:w-auto sm:justify-start">
{link && (
<a href={link.href} className="btn btn-primary mb-8 sm:mb-0 ">
{link.label}
</a>
)}
</div>
</div>
<div className="mt-4 h-fit md:col-span-2 md:mx-4 md:mt-0 md:px-4">
<Collapse
items={items}
classCollapseItem="border-b border-solid border-slate-300 dark:border-slate-500 py-5"
iconUp={<IconMinus className="h-6 w-6 text-primary-600 dark:text-slate-200" />}
iconDown={<IconPlus className="h-6 w-6 text-primary-600 dark:text-slate-200" />}
/>
</div>
</div>
</div>
</div>
</section>
);
};

export default FAQs3;
8 changes: 4 additions & 4 deletions src/components/widgets/Pricing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const Pricing = () => {
{header && <HeaderWidget header={header} titleClassname="text-2xl sm:text-3xl" />}
<div className="flex items-stretch justify-center">
<div className="grid grid-cols-3 gap-3 dark:text-white sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3">
{prices.map(({ title, value, period, texts, btnText, hasRibbon, ribbonText: ribbonTitle }, index) => (
{prices.map(({ title, value, period, texts, link, hasRibbon, ribbonTitle }, index) => (
<div
className="col-span-3 mx-auto flex w-full sm:col-span-1 md:col-span-1 lg:col-span-1 xl:col-span-1"
key={`item-pricing-${index}`}
Expand Down Expand Up @@ -47,9 +47,9 @@ const Pricing = () => {
))}
</ul>
<div className="mt-8 flex w-full uppercase sm:w-auto">
{btnText && (
<a href="#" className={`btn ${hasRibbon && 'btn-primary sm:mb-0'} w-full`}>
{btnText}
{link && (
<a href={link.href} className={`btn ${hasRibbon && 'btn-primary sm:mb-0'} w-full`}>
{link.label}
</a>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/Team.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const Team = () => {
href={href}
target="_blank"
rel="noopener noreferrer"
aria-label={title}
aria-label={title as string}
className="flex items-center justify-center rounded-sm bg-transparent p-0.5 text-primary-900 hover:bg-primary-900 hover:text-slate-200 hover:dark:bg-slate-800 hover:dark:text-slate-200"
>
<Icon className="h-6 w-6 p-0.5" />
Expand Down
Loading

0 comments on commit a66e3d9

Please sign in to comment.