Skip to content

Commit

Permalink
Merge pull request mantinedev#12 from widgeter/new-components
Browse files Browse the repository at this point in the history
Include FAQs page
  • Loading branch information
prototypa authored Mar 13, 2023
2 parents f1dbac9 + 9adc875 commit bc30738
Show file tree
Hide file tree
Showing 15 changed files with 385 additions and 59 deletions.
4 changes: 2 additions & 2 deletions app/contact/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import Contact2 from '~/components/widgets/Contact2';
import Features2 from '~/components/widgets/Features2';
import { featuresData1 } from '~/shared/data';
import { featuresData2 } from '~/shared/data';

const Page = () => {
return (
<>
<Contact2 />
<Features2 {...featuresData1} />
<Features2 {...featuresData2} />
</>
);
};
Expand Down
14 changes: 14 additions & 0 deletions app/faqs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CallToAction from '~/components/widgets/CallToAction';
import FAQs4 from '~/components/widgets/FAQs4';
import { callToActionData2, faqs4Data } from '~/shared/data';

const Page = () => {
return (
<>
<FAQs4 {...faqs4Data} />
<CallToAction cta={callToActionData2} />
</>
);
};

export default Page;
4 changes: 2 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import FAQs2 from '~/components/widgets/FAQs2';
import Pricing from '~/components/widgets/Pricing';
import Team from '~/components/widgets/Team';
import CallToAction2 from '~/components/widgets/CallToAction2';
import { content2Data, contentData, featuresData } from '~/shared/data';
import { callToActionData, content2Data, contentData, featuresData } from '~/shared/data';
import Contact from '~/components/widgets/Contact';

export default function Page() {
Expand All @@ -25,7 +25,7 @@ export default function Page() {
<Pricing />
<Team />
<Contact />
<CallToAction2 />
<CallToAction2 {...callToActionData} />
</>
);
}
2 changes: 0 additions & 2 deletions app/pricing/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
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 />
</>
);
};
Expand Down
13 changes: 12 additions & 1 deletion src/components/common/Collapse.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';
import { useState } from 'react';
import { CollapseProps } from '~/shared/types';

Expand Down Expand Up @@ -35,7 +36,17 @@ const Collapse = ({ items, classCollapseItem, iconUp, iconDown }: CollapseProps)
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}
{iconDown && iconUp ? (
activeIndex === index ? (
iconUp
) : (
iconDown
)
) : 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
Expand Down
68 changes: 68 additions & 0 deletions src/components/common/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client';

import { IconCheck, IconChevronDown, IconChevronUp } from '@tabler/icons-react';
import { useEffect, useState } from 'react';
import { Dropdown, Tab } from '~/shared/types';

const Dropdown = ({ options, activeTab, onActiveTabSelected, iconUp, iconDown }: Dropdown) => {
const [isDropdownOpen, setIsDropdownOpen] = useState<boolean>(false);
const [selectedOption, setSelectedOption] = useState<string>(options[activeTab].link?.label as string);

const dropdownHandler = (e: React.SyntheticEvent) => {
e.stopPropagation();
setIsDropdownOpen(!isDropdownOpen);
};

const onOptionSelected = (option: Tab, index: number) => {
setSelectedOption(option.link?.label as string);

// Sends the value to the parent component
onActiveTabSelected(index);
};

useEffect(() => {
const handler = () => setIsDropdownOpen(false);

window.addEventListener('click', handler);

return () => {
window.removeEventListener('click', handler);
};
});

return (
<div className="relative mt-4 rounded-md border border-gray-400 text-left">
<div onClick={dropdownHandler} className="flex select-none items-center justify-between rounded-md p-3">
<div className="text-lg">{selectedOption}</div>
{iconDown && iconUp ? (
isDropdownOpen === false ? (
iconDown
) : (
iconUp
)
) : isDropdownOpen === false ? (
<IconChevronDown className="h-6 w-6 text-primary-600 dark:text-slate-200" />
) : (
<IconChevronUp className="h-6 w-6 text-primary-600 dark:text-slate-200" />
)}
</div>
{isDropdownOpen && (
<div className="absolute w-full translate-y-1 overflow-auto rounded-md border border-gray-400">
{options.map((option: Tab, index) => (
<div
key={`option-${index}`}
onClick={() => onOptionSelected(option, index)}
className={`flex cursor-pointer items-center bg-white p-3 text-lg dark:bg-slate-900 ${
activeTab !== index ? 'pl-10' : 'text-primary-600 dark:text-primary-200'
}`}
>
{activeTab === index && <IconCheck className="mr-2 h-5 w-5" />} {option.link?.label}
</div>
))}
</div>
)}
</div>
);
};

export default Dropdown;
18 changes: 7 additions & 11 deletions src/components/widgets/CallToAction.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { callToActionData } from '~/shared/data';
import { CallToActionProps, CallToAction } from '~/shared/types';

const CallToAction = () => {
const { title, subtitle, callToAction } = callToActionData;
const CallToAction = (props: { cta: CallToActionProps }) => {
const { title, subtitle, callToAction } = props.cta;
const { text, href, icon: Icon } = callToAction as CallToAction;

return (
<section className="bg-primary-50 dark:bg-slate-800" id="callToActionOne">
Expand All @@ -14,15 +15,10 @@ const CallToAction = () => {
</h2>
)}
{subtitle && <p className="text-xl text-gray-600 dark:text-slate-400">{subtitle}</p>}
{callToAction && callToAction.text && callToAction.href && (
{text && href && (
<div className="mx-auto mt-6 max-w-xs">
<a
className="btn btn-primary w-full sm:w-auto"
href={callToAction.href}
target="_blank"
rel="noopener noreferrer"
>
{callToAction.icon && <callToAction.icon className="mr-1 -ml-1.5 h-5 w-5" />} {callToAction.text}
<a className="btn btn-primary w-full sm:w-auto" href={href}>
{Icon && <Icon className="mr-1 -ml-1.5 h-5 w-5" />} {text}
</a>
</div>
)}
Expand Down
65 changes: 30 additions & 35 deletions src/components/widgets/CallToAction2.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { IconChevronRight } from '@tabler/icons-react';
import { callToActionData } from '~/shared/data';
import { Item } from '~/shared/types';
import { CallToActionProps, Item } from '~/shared/types';

const Card = ({ title, description, href, form }: Item) => (
<div className="mb-6 rounded-md border-gray-400 bg-primary-50 px-5 py-4 text-base font-medium text-gray-700 shadow-md dark:bg-slate-900">
Expand Down Expand Up @@ -43,41 +42,37 @@ const Card = ({ title, description, href, form }: Item) => (
</div>
);

const CallToAction2 = () => {
const { title, subtitle, items } = callToActionData;

return (
<section className="bg-primary-900 text-gray-200" id="callToActionTwo">
<div className="mx-auto max-w-6xl px-4 py-16 lg:px-8 lg:pt-20">
<div className="row-gap-10 grid gap-6 md:grid-cols-2">
<div className="mx-auto md:my-auto md:ml-0 md:pb-6 md:pr-24">
<h2 className="mb-3 flex justify-center text-6xl font-bold md:justify-start">{title}</h2>
<p className="text-center text-xl text-gray-200 dark:text-slate-300 md:text-left">{subtitle}</p>
</div>
<div className="relative -mb-6">
{items &&
items.map(({ title, description, href, form }, index) => (
<div key={`call-to-action-item-${index}`}>
{href ? (
<a
href={href}
className="w-full sm:mb-0"
target="_blank"
rel="noopener noreferrer"
key={`item-cta-${index}`}
>
<Card title={title} description={description} href={href} form={form} />
</a>
) : (
const CallToAction2 = ({ title, subtitle, items }: CallToActionProps) => (
<section className="bg-primary-900 text-gray-200" id="callToActionTwo">
<div className="mx-auto max-w-6xl px-4 py-16 lg:px-8 lg:pt-20">
<div className="row-gap-10 grid gap-6 md:grid-cols-2">
<div className="mx-auto md:my-auto md:ml-0 md:pb-6 md:pr-24">
<h2 className="mb-3 flex justify-center text-6xl font-bold md:justify-start">{title}</h2>
<p className="text-center text-xl text-gray-200 dark:text-slate-300 md:text-left">{subtitle}</p>
</div>
<div className="relative -mb-6">
{items &&
items.map(({ title, description, href, form }, index) => (
<div key={`call-to-action-item-${index}`}>
{href ? (
<a
href={href}
className="w-full sm:mb-0"
target="_blank"
rel="noopener noreferrer"
key={`item-cta-${index}`}
>
<Card title={title} description={description} href={href} form={form} />
)}
</div>
))}
</div>
</a>
) : (
<Card title={title} description={description} href={href} form={form} />
)}
</div>
))}
</div>
</div>
</section>
);
};
</div>
</section>
);

export default CallToAction2;
3 changes: 2 additions & 1 deletion src/components/widgets/FAQs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IconArrowDownRight } from '@tabler/icons-react';
import { faqsData } from '~/shared/data';
import { Item } from '~/shared/types';
import HeaderWidget from '../common/HeaderWidget';

const FAQs = () => {
Expand All @@ -11,7 +12,7 @@ const FAQs = () => {
{header && <HeaderWidget header={header} titleClassname="text-3xl sm:text-4xl" />}
<div className="max-w-screen-xl sm:mx-auto">
<div className="grid grid-cols-1 gap-x-8 gap-y-8 md:grid-cols-2 lg:gap-x-16">
{items.map(({ title, description }, index) => (
{(items as Item[]).map(({ title, description }, index) => (
<div className="space-y-8" key={`faqs-item-${index}`}>
<div>
<h3 className="mb-4 text-xl font-bold">
Expand Down
3 changes: 2 additions & 1 deletion src/components/widgets/FAQs2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { faqsData } from '~/shared/data';
import HeaderWidget from '../common/HeaderWidget';
import Collapse from '../common/Collapse';
import { IconChevronDown, IconChevronUp } from '@tabler/icons-react';
import { Item } from '~/shared/types';

const FAQs2 = () => {
const { header, items } = faqsData;
Expand All @@ -11,7 +12,7 @@ const FAQs2 = () => {
<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" />}
<Collapse
items={items}
items={items as Item[]}
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" />}
Expand Down
3 changes: 2 additions & 1 deletion src/components/widgets/FAQs3.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { faqs3Data } from '~/shared/data';
import HeaderWidget from '../common/HeaderWidget';
import Collapse from '../common/Collapse';
import { IconMinus, IconPlus } from '@tabler/icons-react';
import { Item } from '~/shared/types';

const FAQs3 = () => {
const { header, items, link } = faqs3Data;
Expand All @@ -23,7 +24,7 @@ const FAQs3 = () => {
</div>
<div className="mt-4 h-fit md:col-span-2 md:mx-4 md:mt-0 md:px-4">
<Collapse
items={items}
items={items as Item[]}
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" />}
Expand Down
74 changes: 74 additions & 0 deletions src/components/widgets/FAQs4.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use client';

import HeaderWidget from '../common/HeaderWidget';
import Collapse from '../common/Collapse';
import { IconMinus, IconPlus } from '@tabler/icons-react';
import { FAQsProps, Item, Tab } from '~/shared/types';
import { useState } from 'react';
import useWindowSize from '~/hooks/useWindowSize';
import Dropdown from '../common/Dropdown';

const FAQs4 = ({ header, tabs }: FAQsProps) => {
const { width } = useWindowSize();
const [activeTab, setActiveTab] = useState(0);

const activeTabSelectedHandler = (index: number) => {
setActiveTab(index);
};

return (
<section className="bg-primary-50 dark:bg-slate-800" id="faqsFour">
<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" />}
<div className="flex items-stretch justify-center">
<div className="grid w-full md:grid-cols-3 md:items-center md:gap-4">
{width > 767 ? (
<div className="block h-full sm:flex sm:items-center sm:justify-between md:mx-4 md:mt-10 md:block md:px-4">
<div className="flex h-fit w-full justify-center sm:w-auto sm:justify-start">
<ul>
{(tabs as Tab[]).map((tab, index) => {
const onSelectTab = () => {
setActiveTab(index);
};

return (
<li
key={`tab-${index}`}
className={`mb-5 flex cursor-pointer items-center ${
activeTab === index ? 'text-primary-600 dark:text-primary-200' : ''
}`}
tabIndex={0}
onClick={onSelectTab}
>
<span className="w-full text-xl hover:underline">{tab.link?.label}</span>
</li>
);
})}
</ul>
</div>
</div>
) : (
<Dropdown options={tabs as Tab[]} activeTab={activeTab} onActiveTabSelected={activeTabSelectedHandler} />
)}
<div className="mt-4 h-fit md:col-span-2 md:mx-4 md:mt-0 md:px-4">
{(tabs as Tab[]).map((tab, index) => (
<div key={`tab-${index}`} className="">
{activeTab === index && (
<Collapse
items={tab.items as Item[]}
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>
</div>
</section>
);
};

export default FAQs4;
Loading

0 comments on commit bc30738

Please sign in to comment.