diff --git a/app/contact/page.tsx b/app/contact/page.tsx new file mode 100644 index 00000000..ac87c5ac --- /dev/null +++ b/app/contact/page.tsx @@ -0,0 +1,14 @@ +import Contact2 from '~/components/widgets/Contact2'; +import Features2 from '~/components/widgets/Features2'; +import { featuresData1 } from '~/shared/data'; + +const Page = () => { + return ( + <> + + + + ); +}; + +export default Page; diff --git a/app/page.tsx b/app/page.tsx index 93f19d7a..a98e1034 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -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 } from '~/shared/data'; +import { content2Data, contentData, featuresData } from '~/shared/data'; import Contact from '~/components/widgets/Contact'; export default function Page() { @@ -16,7 +16,7 @@ export default function Page() { <> - + diff --git a/src/components/common/Form.tsx b/src/components/common/Form.tsx new file mode 100644 index 00000000..7d69a577 --- /dev/null +++ b/src/components/common/Form.tsx @@ -0,0 +1,135 @@ +'use client'; + +import { useState } from 'react'; +import { FormProps } from '../../shared/types'; + +const Form = ({ title, description, inputs, radioBtns, textarea, checkboxes, btn, btnPosition }: FormProps) => { + const [inputValues, setInputValues] = useState([]); + const [radioBtnValue, setRadioBtnValue] = useState(''); + const [textareaValues, setTextareaValues] = useState(''); + const [checkedState, setCheckedState] = useState(new Array(checkboxes && checkboxes.length).fill(false)); + + // Update the value of the entry fields + const changeInputValueHandler = (event: React.ChangeEvent) => { + const { name, value } = event.target; + + setInputValues({ + ...inputValues, + [name]: value, + }); + }; + + // Update checked radio buttons + const changeRadioBtnsHandler = (event: React.ChangeEvent) => { + setRadioBtnValue(event.target.value); + }; + + // Update the textarea value + const changeTextareaHandler = (event: React.ChangeEvent) => { + setTextareaValues(event.target.value); + }; + + // Update checkbox radio buttons + const changeCheckboxHandler = (index: number) => { + setCheckedState((prevValues) => { + const newValues = [...(prevValues as boolean[])]; + newValues.map(() => { + newValues[index] = !checkedState[index]; + }); + return newValues; + }); + }; + + return ( +
+ {title &&

{title}

} + {description &&

{description}

} +
+
+ {/* Inputs */} +
+ {inputs.map(({ type, label, name, placeholder }, index) => ( +
+ + +
+ ))} +
+ {/* Radio buttons */} + {radioBtns && ( +
+ +
+ {radioBtns.radios.map(({ label }, index) => ( +
+ + +
+ ))} +
+
+ )} + {/* Textarea */} + {textarea && ( +
+ + -
-
-
-
- - - +
diff --git a/src/components/widgets/Contact2.tsx b/src/components/widgets/Contact2.tsx new file mode 100644 index 00000000..b30e3701 --- /dev/null +++ b/src/components/widgets/Contact2.tsx @@ -0,0 +1,20 @@ +import { contact2Data } from '~/shared/data'; +import Form from '../common/Form'; +import HeaderWidget from '../common/HeaderWidget'; + +const Contact2 = () => { + const { header, form } = contact2Data; + + return ( +
+
+ {header && } +
+ +
+
+
+ ); +}; + +export default Contact2; diff --git a/src/components/widgets/Content.tsx b/src/components/widgets/Content.tsx index 39872b1f..4791e61b 100644 --- a/src/components/widgets/Content.tsx +++ b/src/components/widgets/Content.tsx @@ -1,11 +1,10 @@ -import { FC } from 'react'; import Image from 'next/image'; import { IconCheck } from '@tabler/icons-react'; import { ContentProps } from '~/shared/types'; import HeaderWidget from '../common/HeaderWidget'; -const Content: FC = ({ header, content, items, image, isReversed, isAfterContent }) => ( +const Content = ({ header, content, items, image, isReversed, isAfterContent }: ContentProps) => (
{ - const { header, items } = featuresData; - - return ( -
-
- {header && } -
- {items.map(({ title, description, icon: Icon }, index) => ( -
-
-
-
- {Icon && } -
-
-
-

{title}

-

{description}

+const Features = ({ header, items }: FeaturesProps) => ( +
+
+ {header && } +
+ {items.map(({ title, description, icon: Icon }, index) => ( +
+
+
+
+ {Icon && }
+
+

{title}

+

{description}

+
- ))} -
+
+ ))}
-
- ); -}; +
+
+); export default Features; diff --git a/src/components/widgets/Features2.tsx b/src/components/widgets/Features2.tsx index 33ea7178..4c34162e 100644 --- a/src/components/widgets/Features2.tsx +++ b/src/components/widgets/Features2.tsx @@ -1,31 +1,44 @@ -import { featuresData } from '~/shared/data'; +import { Fragment } from 'react'; +import { FeaturesProps } from '~/shared/types'; import HeaderWidget from '../common/HeaderWidget'; -const Features2 = () => { - const { header, items } = featuresData; - - return ( -
-
-
- {header && } -
- {items.map(({ title, description, icon: Icon }, index) => ( -
-
- {Icon && } -
{title}
+const Features2 = ({ header, items }: FeaturesProps) => ( +
+
+
+ {header && } +
2 ? 'grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3' : 'flex justify-center' + } items-stretch gap-6`} + > + {items.map(({ title, description, icon: Icon, link }, index) => ( + + {link ? ( + +
+ {Icon && } +
{title}
+
+ {description &&

{description}

} +
+ ) : ( +
+
+ {Icon && } +
{title}
+
+ {description &&

{description}

}
- {description &&

{description}

} -
- ))} -
+ )} + + ))}
-
- ); -}; +
+
+); export default Features2; diff --git a/src/components/widgets/Features3.tsx b/src/components/widgets/Features3.tsx index 26b782f5..2059a875 100644 --- a/src/components/widgets/Features3.tsx +++ b/src/components/widgets/Features3.tsx @@ -1,48 +1,41 @@ -import { featuresData } from '~/shared/data'; +import { FeaturesProps } from '~/shared/types'; import HeaderWidget from '../common/HeaderWidget'; -const Features3 = () => { - const { header, items } = featuresData; - - return ( -
-
- {header && } -
- {items.map(({ title, description, icon: Icon, callToAction }, index) => ( -
-
-
-
- {Icon && } -
-
-
- <> -

{title}

-

{description}

- - {callToAction && ( - - )} +const Features3 = ({ header, items }: FeaturesProps) => ( +
+
+ {header && } +
+ {items.map(({ title, description, icon: Icon, link }, index) => ( +
+
+
+
+ {Icon && }
+
+ <> +

{title}

+

{description}

+ + {link && ( + + )} +
- ))} -
+
+ ))}
-
- ); -}; +
+
+); export default Features3; diff --git a/src/shared/data.tsx b/src/shared/data.tsx index 63f7c399..de7a94f7 100644 --- a/src/shared/data.tsx +++ b/src/shared/data.tsx @@ -13,9 +13,12 @@ import { IconClock, IconComponents, IconDownload, + IconHeadset, + IconHelp, IconListCheck, IconMail, IconMapPin, + IconMessages, IconPhoneCall, IconRocket, IconRss, @@ -74,7 +77,7 @@ export const headerData: HeaderProps = { }, { label: 'Contact', - href: '/', + href: '/contact', }, ], }, @@ -287,8 +290,8 @@ export const featuresData: FeaturesProps = { description: 'A seamless integration between two great frameworks that offer high productivity, performance and versatility.', icon: IconBrandTailwind, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', href: '/', }, }, @@ -297,8 +300,8 @@ export const featuresData: FeaturesProps = { description: 'Widgets made with Tailwind CSS ready to be used in Marketing Websites, SaaS, Blogs, Personal Profiles, Small Business...', icon: IconComponents, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', href: '/', }, }, @@ -307,8 +310,8 @@ export const featuresData: FeaturesProps = { description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', icon: IconListCheck, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', href: '/', }, }, @@ -317,8 +320,8 @@ export const featuresData: FeaturesProps = { description: 'Having a good page speed impacts organic search ranking, improves user experience (UI/UX) and increase conversion rates.', icon: IconRocket, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', href: '/', }, }, @@ -327,8 +330,8 @@ export const featuresData: FeaturesProps = { description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', icon: IconArrowsRightLeft, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', href: '/', }, }, @@ -337,8 +340,41 @@ export const featuresData: FeaturesProps = { description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', icon: IconBulb, - callToAction: { - text: 'Discover now', + link: { + label: 'Discover now', + href: '/', + }, + }, + ], +}; + +export const featuresData1: FeaturesProps = { + header: { + title: 'Support Center', + subtitle: 'Looking for something in particular?', + }, + items: [ + { + title: 'Have a question?', + description: 'See our frequently asked questions', + icon: IconHelp, + link: { + href: '/', + }, + }, + { + title: 'Chat with us', + description: 'Live chat with our support team', + icon: IconMessages, + link: { + href: '/', + }, + }, + { + title: 'Get help', + description: 'Speak to our team today', + icon: IconHeadset, + link: { href: '/', }, }, @@ -816,6 +852,103 @@ export const contactData: ContactProps = { placeholder: 'Your email address', }, ], + textarea: { + cols: 30, + rows: 5, + name: 'textarea', + placeholder: 'Write your message...', + }, + btn: { + title: 'Send Message', + type: 'submit', + }, + }, +}; + +// Contact2 data +export const contact2Data: ContactProps = { + header: { + title: 'Get in Touch', + subtitle: 'In hac habitasse platea dictumst', + highlight: 'Contact', + }, + content: + 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Duis nec ipsum orci. Ut scelerisque sagittis ante, ac tincidunt sem venenatis ut.', + items: [ + { + title: 'Our Address', + description: ['1230 Maecenas Street Donec Road', 'New York, EEUU'], + icon: IconMapPin, + }, + { + title: 'Contact', + description: ['Mobile: +1 (123) 456-7890', 'Mail: tailnext@gmail.com'], + icon: IconPhoneCall, + }, + { + title: 'Working hours', + description: ['Monday - Friday: 08:00 - 17:00', 'Saturday & Sunday: 08:00 - 12:00'], + icon: IconClock, + }, + ], + form: { + title: 'Ready to Get Started?', + description: + 'Mauris consequat, urna vel varius auctor, enim risus ornare felis, at hendrerit erat justo eu justo. Curabitur sagittis efficitur aliquam. Duis eget porttitor lectus, vel pharetra ex. Nam volutpat nibh ut porta egestas.', + inputs: [ + { + type: 'text', + label: 'First name', + name: 'name', + placeholder: 'First name', + }, + { + type: 'text', + label: 'Last name', + name: 'lastName', + placeholder: 'Last name', + }, + { + type: 'email', + label: 'Email address', + name: 'email', + placeholder: 'Email address', + }, + ], + radioBtns: { + label: 'What is the reason for your contact?', + radios: [ + { + label: 'General inquiries', + }, + { + label: 'Technical help', + }, + { + label: 'Claims', + }, + { + label: 'Others', + }, + ], + }, + textarea: { + cols: 30, + rows: 5, + label: 'How can we help you?', + name: 'textarea', + placeholder: 'Write your message...', + }, + checkboxes: [ + { + label: 'Have you read our privacy policy?', + value: '', + }, + { + label: 'Do you want to receive monthly updates by email?', + value: '', + }, + ], btn: { title: 'Send Message', type: 'submit', diff --git a/src/shared/types.d.ts b/src/shared/types.d.ts index 27e246e2..becb5948 100644 --- a/src/shared/types.d.ts +++ b/src/shared/types.d.ts @@ -5,7 +5,7 @@ interface Header { title?: string | ReactElement; subtitle?: string; highlight?: string; - position?: string; + position?: 'center' | 'right' | 'left'; } interface CallToAction { @@ -21,21 +21,49 @@ interface Button { interface Input { type: string; + label?: string; + value?: string; name: string; placeholder?: string; } +interface Textarea { + cols?: number; + rows?: number; + label?: string; + name: string; + placeholder?: string; +} + +interface Checkbox { + label: string; + value: string; +} + +interface Radio { + label: string; +} + +interface RadioBtn { + label?: string; + radios: Array; +} + interface SmallForm { icon?: Function; input: Input; btn: Button; } -interface Form { +interface FormProps { title?: string; description?: string; inputs: Array; + radioBtns?: RadioBtn; + textarea?: Textarea; + checkboxes?: Array; btn: Button; + btnPosition?: 'center' | 'right' | 'left'; } interface Image { @@ -50,6 +78,7 @@ interface Item { form?: SmallForm; icon?: Function; callToAction?: CallToAction; + link?: Link; } interface Team { @@ -187,7 +216,7 @@ interface ContactProps { header?: Header; content?: string; items: Array; - form: Form; + form: FormProps; } interface FooterProps { @@ -205,7 +234,7 @@ interface HeaderProps { isSticky?: boolean; showToggleTheme?: boolean; showRssFeed?: boolean; - position?: string; + position?: 'center' | 'right' | 'left'; } interface ToggleMenuProps {