Merge pull request 'Cleaning up old components etc' (#6) from development into main
Reviewed-on: #6
This commit is contained in:
@@ -1,59 +0,0 @@
|
|||||||
import { type Metadata } from 'next'
|
|
||||||
import Link from 'next/link'
|
|
||||||
|
|
||||||
import { Button } from '@/components/Button'
|
|
||||||
import { TextField } from '@/components/Fields'
|
|
||||||
import { Logo } from '@/components/Logo'
|
|
||||||
import { SlimLayout } from '@/components/SlimLayout'
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: 'Sign In',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Login() {
|
|
||||||
return (
|
|
||||||
<SlimLayout>
|
|
||||||
<div className="flex">
|
|
||||||
<Link href="/" aria-label="Home">
|
|
||||||
<Logo className="h-10 w-auto" />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<h2 className="mt-20 text-lg font-semibold text-gray-900">
|
|
||||||
Sign in to your account
|
|
||||||
</h2>
|
|
||||||
<p className="mt-2 text-sm text-gray-700">
|
|
||||||
Don’t have an account?{' '}
|
|
||||||
<Link
|
|
||||||
href="/register"
|
|
||||||
className="font-medium text-blue-600 hover:underline"
|
|
||||||
>
|
|
||||||
Sign up
|
|
||||||
</Link>{' '}
|
|
||||||
for a free trial.
|
|
||||||
</p>
|
|
||||||
<form action="#" className="mt-10 grid grid-cols-1 gap-y-8">
|
|
||||||
<TextField
|
|
||||||
label="Email address"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
autoComplete="email"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
label="Password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
autoComplete="current-password"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<Button type="submit" variant="solid" color="blue" className="w-full">
|
|
||||||
<span>
|
|
||||||
Sign in <span aria-hidden="true">→</span>
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</SlimLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
import { type Metadata } from 'next'
|
|
||||||
import Link from 'next/link'
|
|
||||||
|
|
||||||
import { Button } from '@/components/Button'
|
|
||||||
import { SelectField, TextField } from '@/components/Fields'
|
|
||||||
import { Logo } from '@/components/Logo'
|
|
||||||
import { SlimLayout } from '@/components/SlimLayout'
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: 'Sign Up',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Register() {
|
|
||||||
return (
|
|
||||||
<SlimLayout>
|
|
||||||
<div className="flex">
|
|
||||||
<Link href="/" aria-label="Home">
|
|
||||||
<Logo className="h-10 w-auto" />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<h2 className="mt-20 text-lg font-semibold text-gray-900">
|
|
||||||
Get started for free
|
|
||||||
</h2>
|
|
||||||
<p className="mt-2 text-sm text-gray-700">
|
|
||||||
Already registered?{' '}
|
|
||||||
<Link
|
|
||||||
href="/login"
|
|
||||||
className="font-medium text-blue-600 hover:underline"
|
|
||||||
>
|
|
||||||
Sign in
|
|
||||||
</Link>{' '}
|
|
||||||
to your account.
|
|
||||||
</p>
|
|
||||||
<form
|
|
||||||
action="#"
|
|
||||||
className="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-2"
|
|
||||||
>
|
|
||||||
<TextField
|
|
||||||
label="First name"
|
|
||||||
name="first_name"
|
|
||||||
type="text"
|
|
||||||
autoComplete="given-name"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
label="Last name"
|
|
||||||
name="last_name"
|
|
||||||
type="text"
|
|
||||||
autoComplete="family-name"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
className="col-span-full"
|
|
||||||
label="Email address"
|
|
||||||
name="email"
|
|
||||||
type="email"
|
|
||||||
autoComplete="email"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<TextField
|
|
||||||
className="col-span-full"
|
|
||||||
label="Password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
autoComplete="new-password"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<SelectField
|
|
||||||
className="col-span-full"
|
|
||||||
label="How did you hear about us?"
|
|
||||||
name="referral_source"
|
|
||||||
>
|
|
||||||
<option>AltaVista search</option>
|
|
||||||
<option>Super Bowl commercial</option>
|
|
||||||
<option>Our route 34 city bus ad</option>
|
|
||||||
<option>The “Never Use This” podcast</option>
|
|
||||||
</SelectField>
|
|
||||||
<div className="col-span-full">
|
|
||||||
<Button type="submit" variant="solid" color="blue" className="w-full">
|
|
||||||
<span>
|
|
||||||
Sign up <span aria-hidden="true">→</span>
|
|
||||||
</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</SlimLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -2,15 +2,6 @@ import { CallToAction } from '@/components/CallToAction'
|
|||||||
import { Faqs } from '@/components/Faqs'
|
import { Faqs } from '@/components/Faqs'
|
||||||
import { Footer } from '@/components/Footer'
|
import { Footer } from '@/components/Footer'
|
||||||
import { Header_darkbg } from '@/components/Header_darkbg'
|
import { Header_darkbg } from '@/components/Header_darkbg'
|
||||||
import { HomeAbout } from '@/components/HomeAbout'
|
|
||||||
import { Hero } from '@/components/Hero'
|
|
||||||
import { Pricing } from '@/components/Pricing'
|
|
||||||
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
|
||||||
import { SecondaryFeatures } from '@/components/SecondaryFeatures'
|
|
||||||
import { Testimonials } from '@/components/Testimonials'
|
|
||||||
import { HomePrinciples } from '@/components/HomePrinciples'
|
|
||||||
import { HomeMilestones } from '@/components/HomeMilestones'
|
|
||||||
import { HomeVentures } from '@/components/HomeVentures'
|
|
||||||
import { Quote } from '@/components/Quote'
|
import { Quote } from '@/components/Quote'
|
||||||
import { AboutHero } from '@/components/AboutHero'
|
import { AboutHero } from '@/components/AboutHero'
|
||||||
import { AboutMission } from '@/components/AboutMission'
|
import { AboutMission } from '@/components/AboutMission'
|
||||||
|
|||||||
@@ -2,19 +2,7 @@ import { CallToAction } from '@/components/CallToAction'
|
|||||||
import { Faqs } from '@/components/Faqs'
|
import { Faqs } from '@/components/Faqs'
|
||||||
import { Footer } from '@/components/Footer'
|
import { Footer } from '@/components/Footer'
|
||||||
import { Header_darkbg } from '@/components/Header_darkbg'
|
import { Header_darkbg } from '@/components/Header_darkbg'
|
||||||
import { HomeAbout } from '@/components/HomeAbout'
|
|
||||||
import { Hero } from '@/components/Hero'
|
|
||||||
import { Pricing } from '@/components/Pricing'
|
|
||||||
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
|
||||||
import { SecondaryFeatures } from '@/components/SecondaryFeatures'
|
|
||||||
import { Testimonials } from '@/components/Testimonials'
|
|
||||||
import { HomePrinciples } from '@/components/HomePrinciples'
|
|
||||||
import { HomeMilestones } from '@/components/HomeMilestones'
|
|
||||||
import { HomeVentures } from '@/components/HomeVentures'
|
|
||||||
import { Quote } from '@/components/Quote'
|
import { Quote } from '@/components/Quote'
|
||||||
import { AboutHero } from '@/components/AboutHero'
|
|
||||||
import { AboutMission } from '@/components/AboutMission'
|
|
||||||
import { AboutExperience } from '@/components/AboutExperience'
|
|
||||||
import { ContactHero } from '@/components/ContactHero'
|
import { ContactHero } from '@/components/ContactHero'
|
||||||
|
|
||||||
export default function Contact() {
|
export default function Contact() {
|
||||||
|
|||||||
@@ -3,15 +3,10 @@ import { Faqs } from '@/components/Faqs'
|
|||||||
import { Footer } from '@/components/Footer'
|
import { Footer } from '@/components/Footer'
|
||||||
import { HomeAbout } from '@/components/HomeAbout'
|
import { HomeAbout } from '@/components/HomeAbout'
|
||||||
import { Hero } from '@/components/Hero'
|
import { Hero } from '@/components/Hero'
|
||||||
import { Pricing } from '@/components/Pricing'
|
|
||||||
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
|
||||||
import { SecondaryFeatures } from '@/components/SecondaryFeatures'
|
|
||||||
import { Testimonials } from '@/components/Testimonials'
|
|
||||||
import { HomePrinciples } from '@/components/HomePrinciples'
|
import { HomePrinciples } from '@/components/HomePrinciples'
|
||||||
import { HomeMilestones } from '@/components/HomeMilestones'
|
import { HomeMilestones } from '@/components/HomeMilestones'
|
||||||
import { HomeVentures } from '@/components/HomeVentures'
|
import { HomeVentures } from '@/components/HomeVentures'
|
||||||
import { Quote } from '@/components/Quote'
|
import { Quote } from '@/components/Quote'
|
||||||
import { Header } from '@/components/Header'
|
|
||||||
import { Header_darkbg } from '@/components/Header_darkbg'
|
import { Header_darkbg } from '@/components/Header_darkbg'
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
|||||||
@@ -2,19 +2,6 @@ import { CallToAction } from '@/components/CallToAction'
|
|||||||
import { Faqs } from '@/components/Faqs'
|
import { Faqs } from '@/components/Faqs'
|
||||||
import { Footer } from '@/components/Footer'
|
import { Footer } from '@/components/Footer'
|
||||||
import { Header_darkbg } from '@/components/Header_darkbg'
|
import { Header_darkbg } from '@/components/Header_darkbg'
|
||||||
import { HomeAbout } from '@/components/HomeAbout'
|
|
||||||
import { Hero } from '@/components/Hero'
|
|
||||||
import { Pricing } from '@/components/Pricing'
|
|
||||||
import { PrimaryFeatures } from '@/components/PrimaryFeatures'
|
|
||||||
import { SecondaryFeatures } from '@/components/SecondaryFeatures'
|
|
||||||
import { Testimonials } from '@/components/Testimonials'
|
|
||||||
import { HomePrinciples } from '@/components/HomePrinciples'
|
|
||||||
import { HomeMilestones } from '@/components/HomeMilestones'
|
|
||||||
import { HomeVentures } from '@/components/HomeVentures'
|
|
||||||
import { Quote } from '@/components/Quote'
|
|
||||||
import { AboutHero } from '@/components/AboutHero'
|
|
||||||
import { AboutMission } from '@/components/AboutMission'
|
|
||||||
import { AboutExperience } from '@/components/AboutExperience'
|
|
||||||
import { PeopleHero } from '@/components/PeopleHero'
|
import { PeopleHero } from '@/components/PeopleHero'
|
||||||
|
|
||||||
export default function People() {
|
export default function People() {
|
||||||
|
|||||||
@@ -1,35 +1,11 @@
|
|||||||
import { Logo_darkbg } from '@/components/Logo_darkbg'
|
|
||||||
import { SVGProps } from 'react'
|
import { SVGProps } from 'react'
|
||||||
import { EnvelopeIcon } from '@heroicons/react/20/solid'
|
import { EnvelopeIcon } from '@heroicons/react/20/solid'
|
||||||
|
|
||||||
const navigation = {
|
const navigation = {
|
||||||
solutions: [
|
|
||||||
{ name: 'Marketing', href: '#' },
|
|
||||||
{ name: 'Analytics', href: '#' },
|
|
||||||
{ name: 'Automation', href: '#' },
|
|
||||||
{ name: 'Commerce', href: '#' },
|
|
||||||
{ name: 'Insights', href: '#' },
|
|
||||||
],
|
|
||||||
support: [
|
|
||||||
{ name: 'Submit ticket', href: '#' },
|
|
||||||
{ name: 'Documentation', href: '#' },
|
|
||||||
{ name: 'Guides', href: '#' },
|
|
||||||
],
|
|
||||||
company: [
|
|
||||||
{ name: 'About', href: '#' },
|
|
||||||
{ name: 'Blog', href: '#' },
|
|
||||||
{ name: 'Jobs', href: '#' },
|
|
||||||
{ name: 'Press', href: '#' },
|
|
||||||
],
|
|
||||||
legal: [
|
|
||||||
{ name: 'Terms of service', href: '#' },
|
|
||||||
{ name: 'Privacy policy', href: '#' },
|
|
||||||
{ name: 'License', href: '#' },
|
|
||||||
],
|
|
||||||
social: [
|
social: [
|
||||||
{
|
{
|
||||||
name: 'LinkedIn',
|
name: 'LinkedIn',
|
||||||
href: '#',
|
href: 'https://www.linkedin.com/company/ourworld-ventures',
|
||||||
icon: (props: SVGProps<SVGSVGElement>) => (
|
icon: (props: SVGProps<SVGSVGElement>) => (
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -47,8 +23,8 @@ const navigation = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Mail',
|
name: 'Email',
|
||||||
href: '#',
|
href: 'mailto:info@ourworld.tf',
|
||||||
icon: (props: SVGProps<SVGSVGElement>) => (
|
icon: (props: SVGProps<SVGSVGElement>) => (
|
||||||
<EnvelopeIcon className={props.className} aria-hidden="true" />
|
<EnvelopeIcon className={props.className} aria-hidden="true" />
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,182 +0,0 @@
|
|||||||
import clsx from 'clsx'
|
|
||||||
|
|
||||||
import { Button } from '@/components/Button'
|
|
||||||
import { Container } from '@/components/Container'
|
|
||||||
|
|
||||||
function SwirlyDoodle(props: React.ComponentPropsWithoutRef<'svg'>) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
viewBox="0 0 281 40"
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fillRule="evenodd"
|
|
||||||
clipRule="evenodd"
|
|
||||||
d="M240.172 22.994c-8.007 1.246-15.477 2.23-31.26 4.114-18.506 2.21-26.323 2.977-34.487 3.386-2.971.149-3.727.324-6.566 1.523-15.124 6.388-43.775 9.404-69.425 7.31-26.207-2.14-50.986-7.103-78-15.624C10.912 20.7.988 16.143.734 14.657c-.066-.381.043-.344 1.324.456 10.423 6.506 49.649 16.322 77.8 19.468 23.708 2.65 38.249 2.95 55.821 1.156 9.407-.962 24.451-3.773 25.101-4.692.074-.104.053-.155-.058-.135-1.062.195-13.863-.271-18.848-.687-16.681-1.389-28.722-4.345-38.142-9.364-15.294-8.15-7.298-19.232 14.802-20.514 16.095-.934 32.793 1.517 47.423 6.96 13.524 5.033 17.942 12.326 11.463 18.922l-.859.874.697-.006c2.681-.026 15.304-1.302 29.208-2.953 25.845-3.07 35.659-4.519 54.027-7.978 9.863-1.858 11.021-2.048 13.055-2.145a61.901 61.901 0 0 0 4.506-.417c1.891-.259 2.151-.267 1.543-.047-.402.145-2.33.913-4.285 1.707-4.635 1.882-5.202 2.07-8.736 2.903-3.414.805-19.773 3.797-26.404 4.829Zm40.321-9.93c.1-.066.231-.085.29-.041.059.043-.024.096-.183.119-.177.024-.219-.007-.107-.079ZM172.299 26.22c9.364-6.058 5.161-12.039-12.304-17.51-11.656-3.653-23.145-5.47-35.243-5.576-22.552-.198-33.577 7.462-21.321 14.814 12.012 7.205 32.994 10.557 61.531 9.831 4.563-.116 5.372-.288 7.337-1.559Z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function CheckIcon({
|
|
||||||
className,
|
|
||||||
...props
|
|
||||||
}: React.ComponentPropsWithoutRef<'svg'>) {
|
|
||||||
return (
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
className={clsx(
|
|
||||||
'h-6 w-6 flex-none fill-current stroke-current',
|
|
||||||
className,
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M9.307 12.248a.75.75 0 1 0-1.114 1.004l1.114-1.004ZM11 15.25l-.557.502a.75.75 0 0 0 1.15-.043L11 15.25Zm4.844-5.041a.75.75 0 0 0-1.188-.918l1.188.918Zm-7.651 3.043 2.25 2.5 1.114-1.004-2.25-2.5-1.114 1.004Zm3.4 2.457 4.25-5.5-1.187-.918-4.25 5.5 1.188.918Z"
|
|
||||||
strokeWidth={0}
|
|
||||||
/>
|
|
||||||
<circle
|
|
||||||
cx={12}
|
|
||||||
cy={12}
|
|
||||||
r={8.25}
|
|
||||||
fill="none"
|
|
||||||
strokeWidth={1.5}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function Plan({
|
|
||||||
name,
|
|
||||||
price,
|
|
||||||
description,
|
|
||||||
href,
|
|
||||||
features,
|
|
||||||
featured = false,
|
|
||||||
}: {
|
|
||||||
name: string
|
|
||||||
price: string
|
|
||||||
description: string
|
|
||||||
href: string
|
|
||||||
features: Array<string>
|
|
||||||
featured?: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
className={clsx(
|
|
||||||
'flex flex-col rounded-3xl px-6 sm:px-8',
|
|
||||||
featured ? 'order-first bg-blue-600 py-8 lg:order-none' : 'lg:py-8',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<h3 className="mt-5 font-display text-lg text-white">{name}</h3>
|
|
||||||
<p
|
|
||||||
className={clsx(
|
|
||||||
'mt-2 text-base',
|
|
||||||
featured ? 'text-white' : 'text-slate-400',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
<p className="order-first font-display text-5xl font-light tracking-tight text-white">
|
|
||||||
{price}
|
|
||||||
</p>
|
|
||||||
<ul
|
|
||||||
role="list"
|
|
||||||
className={clsx(
|
|
||||||
'order-last mt-10 flex flex-col gap-y-3 text-sm',
|
|
||||||
featured ? 'text-white' : 'text-slate-200',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{features.map((feature) => (
|
|
||||||
<li key={feature} className="flex">
|
|
||||||
<CheckIcon className={featured ? 'text-white' : 'text-slate-400'} />
|
|
||||||
<span className="ml-4">{feature}</span>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<Button
|
|
||||||
href={href}
|
|
||||||
variant={featured ? 'solid' : 'outline'}
|
|
||||||
color="white"
|
|
||||||
className="mt-8"
|
|
||||||
aria-label={`Get started with the ${name} plan for ${price}`}
|
|
||||||
>
|
|
||||||
Get started
|
|
||||||
</Button>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Pricing() {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
id="pricing"
|
|
||||||
aria-label="Pricing"
|
|
||||||
className="bg-slate-900 py-20 sm:py-32"
|
|
||||||
>
|
|
||||||
<Container>
|
|
||||||
<div className="md:text-center">
|
|
||||||
<h2 className="font-display text-3xl tracking-tight text-white sm:text-4xl">
|
|
||||||
<span className="relative whitespace-nowrap">
|
|
||||||
<SwirlyDoodle className="absolute top-1/2 left-0 h-[1em] w-full fill-blue-400" />
|
|
||||||
<span className="relative">Simple pricing,</span>
|
|
||||||
</span>{' '}
|
|
||||||
for everyone.
|
|
||||||
</h2>
|
|
||||||
<p className="mt-4 text-lg text-slate-400">
|
|
||||||
It doesn’t matter what size your business is, our software won’t
|
|
||||||
work well for you.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="-mx-4 mt-16 grid max-w-2xl grid-cols-1 gap-y-10 sm:mx-auto lg:-mx-8 lg:max-w-none lg:grid-cols-3 xl:mx-0 xl:gap-x-8">
|
|
||||||
<Plan
|
|
||||||
name="Starter"
|
|
||||||
price="$9"
|
|
||||||
description="Good for anyone who is self-employed and just getting started."
|
|
||||||
href="/register"
|
|
||||||
features={[
|
|
||||||
'Send 10 quotes and invoices',
|
|
||||||
'Connect up to 2 bank accounts',
|
|
||||||
'Track up to 15 expenses per month',
|
|
||||||
'Manual payroll support',
|
|
||||||
'Export up to 3 reports',
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<Plan
|
|
||||||
featured
|
|
||||||
name="Small business"
|
|
||||||
price="$15"
|
|
||||||
description="Perfect for small / medium sized businesses."
|
|
||||||
href="/register"
|
|
||||||
features={[
|
|
||||||
'Send 25 quotes and invoices',
|
|
||||||
'Connect up to 5 bank accounts',
|
|
||||||
'Track up to 50 expenses per month',
|
|
||||||
'Automated payroll support',
|
|
||||||
'Export up to 12 reports',
|
|
||||||
'Bulk reconcile transactions',
|
|
||||||
'Track in multiple currencies',
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<Plan
|
|
||||||
name="Enterprise"
|
|
||||||
price="$39"
|
|
||||||
description="For even the biggest enterprise companies."
|
|
||||||
href="/register"
|
|
||||||
features={[
|
|
||||||
'Send unlimited quotes and invoices',
|
|
||||||
'Connect up to 15 bank accounts',
|
|
||||||
'Track up to 200 expenses per month',
|
|
||||||
'Automated payroll support',
|
|
||||||
'Export up to 25 reports, including TPS',
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Container>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import Image from 'next/image'
|
|
||||||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
|
|
||||||
import clsx from 'clsx'
|
|
||||||
|
|
||||||
import { Container } from '@/components/Container'
|
|
||||||
import backgroundImage from '@/images/background-features.jpg'
|
|
||||||
import screenshotExpenses from '@/images/screenshots/expenses.png'
|
|
||||||
import screenshotPayroll from '@/images/screenshots/payroll.png'
|
|
||||||
import screenshotReporting from '@/images/screenshots/reporting.png'
|
|
||||||
import screenshotVatReturns from '@/images/screenshots/vat-returns.png'
|
|
||||||
|
|
||||||
const features = [
|
|
||||||
{
|
|
||||||
title: 'Payroll',
|
|
||||||
description:
|
|
||||||
"Keep track of everyone's salaries and whether or not they've been paid. Direct deposit not supported.",
|
|
||||||
image: screenshotPayroll,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Claim expenses',
|
|
||||||
description:
|
|
||||||
"All of your receipts organized into one place, as long as you don't mind typing in the data by hand.",
|
|
||||||
image: screenshotExpenses,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'VAT handling',
|
|
||||||
description:
|
|
||||||
"We only sell our software to companies who don't deal with VAT at all, so technically we do all the VAT stuff they need.",
|
|
||||||
image: screenshotVatReturns,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Reporting',
|
|
||||||
description:
|
|
||||||
'Easily export your data into an Excel spreadsheet where you can do whatever the hell you want with it.',
|
|
||||||
image: screenshotReporting,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
export function PrimaryFeatures() {
|
|
||||||
let [tabOrientation, setTabOrientation] = useState<'horizontal' | 'vertical'>(
|
|
||||||
'horizontal',
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let lgMediaQuery = window.matchMedia('(min-width: 1024px)')
|
|
||||||
|
|
||||||
function onMediaQueryChange({ matches }: { matches: boolean }) {
|
|
||||||
setTabOrientation(matches ? 'vertical' : 'horizontal')
|
|
||||||
}
|
|
||||||
|
|
||||||
onMediaQueryChange(lgMediaQuery)
|
|
||||||
lgMediaQuery.addEventListener('change', onMediaQueryChange)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
lgMediaQuery.removeEventListener('change', onMediaQueryChange)
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
id="features"
|
|
||||||
aria-label="Features for running your books"
|
|
||||||
className="relative overflow-hidden bg-blue-600 pt-20 pb-28 sm:py-32"
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
className="absolute top-1/2 left-1/2 max-w-none translate-x-[-44%] translate-y-[-42%]"
|
|
||||||
src={backgroundImage}
|
|
||||||
alt=""
|
|
||||||
width={2245}
|
|
||||||
height={1636}
|
|
||||||
unoptimized
|
|
||||||
/>
|
|
||||||
<Container className="relative">
|
|
||||||
<div className="max-w-2xl md:mx-auto md:text-center xl:max-w-none">
|
|
||||||
<h2 className="font-display text-3xl tracking-tight text-white sm:text-4xl md:text-5xl">
|
|
||||||
Everything you need to run your books.
|
|
||||||
</h2>
|
|
||||||
<p className="mt-6 text-lg tracking-tight text-blue-100">
|
|
||||||
Well everything you need if you aren’t that picky about minor
|
|
||||||
details like tax compliance.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<TabGroup
|
|
||||||
className="mt-16 grid grid-cols-1 items-center gap-y-2 pt-10 sm:gap-y-6 md:mt-20 lg:grid-cols-12 lg:pt-0"
|
|
||||||
vertical={tabOrientation === 'vertical'}
|
|
||||||
>
|
|
||||||
{({ selectedIndex }) => (
|
|
||||||
<>
|
|
||||||
<div className="-mx-4 flex overflow-x-auto pb-4 sm:mx-0 sm:overflow-visible sm:pb-0 lg:col-span-5">
|
|
||||||
<TabList className="relative z-10 flex gap-x-4 px-4 whitespace-nowrap sm:mx-auto sm:px-0 lg:mx-0 lg:block lg:gap-x-0 lg:gap-y-1 lg:whitespace-normal">
|
|
||||||
{features.map((feature, featureIndex) => (
|
|
||||||
<div
|
|
||||||
key={feature.title}
|
|
||||||
className={clsx(
|
|
||||||
'group relative rounded-full px-4 py-1 lg:rounded-l-xl lg:rounded-r-none lg:p-6',
|
|
||||||
selectedIndex === featureIndex
|
|
||||||
? 'bg-white lg:bg-white/10 lg:ring-1 lg:ring-white/10 lg:ring-inset'
|
|
||||||
: 'hover:bg-white/10 lg:hover:bg-white/5',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<h3>
|
|
||||||
<Tab
|
|
||||||
className={clsx(
|
|
||||||
'font-display text-lg data-selected:not-data-focus:outline-hidden',
|
|
||||||
selectedIndex === featureIndex
|
|
||||||
? 'text-blue-600 lg:text-white'
|
|
||||||
: 'text-blue-100 hover:text-white lg:text-white',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<span className="absolute inset-0 rounded-full lg:rounded-l-xl lg:rounded-r-none" />
|
|
||||||
{feature.title}
|
|
||||||
</Tab>
|
|
||||||
</h3>
|
|
||||||
<p
|
|
||||||
className={clsx(
|
|
||||||
'mt-2 hidden text-sm lg:block',
|
|
||||||
selectedIndex === featureIndex
|
|
||||||
? 'text-white'
|
|
||||||
: 'text-blue-100 group-hover:text-white',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{feature.description}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</TabList>
|
|
||||||
</div>
|
|
||||||
<TabPanels className="lg:col-span-7">
|
|
||||||
{features.map((feature) => (
|
|
||||||
<TabPanel key={feature.title} unmount={false}>
|
|
||||||
<div className="relative sm:px-6 lg:hidden">
|
|
||||||
<div className="absolute -inset-x-4 top-[-6.5rem] bottom-[-4.25rem] bg-white/10 ring-1 ring-white/10 ring-inset sm:inset-x-0 sm:rounded-t-xl" />
|
|
||||||
<p className="relative mx-auto max-w-2xl text-base text-white sm:text-center">
|
|
||||||
{feature.description}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="mt-10 w-180 overflow-hidden rounded-xl bg-slate-50 shadow-xl shadow-blue-900/20 sm:w-auto lg:mt-0 lg:w-271.25">
|
|
||||||
<Image
|
|
||||||
className="w-full"
|
|
||||||
src={feature.image}
|
|
||||||
alt=""
|
|
||||||
priority
|
|
||||||
sizes="(min-width: 1024px) 67.8125rem, (min-width: 640px) 100vw, 45rem"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</TabPanel>
|
|
||||||
))}
|
|
||||||
</TabPanels>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</TabGroup>
|
|
||||||
</Container>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,249 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import { useId } from 'react'
|
|
||||||
import Image, { type ImageProps } from 'next/image'
|
|
||||||
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
|
|
||||||
import clsx from 'clsx'
|
|
||||||
|
|
||||||
import { Container } from '@/components/Container'
|
|
||||||
import screenshotContacts from '@/images/screenshots/contacts.png'
|
|
||||||
import screenshotInventory from '@/images/screenshots/inventory.png'
|
|
||||||
import screenshotProfitLoss from '@/images/screenshots/profit-loss.png'
|
|
||||||
|
|
||||||
interface Feature {
|
|
||||||
name: React.ReactNode
|
|
||||||
summary: string
|
|
||||||
description: string
|
|
||||||
image: ImageProps['src']
|
|
||||||
icon: React.ComponentType
|
|
||||||
}
|
|
||||||
|
|
||||||
const features: Array<Feature> = [
|
|
||||||
{
|
|
||||||
name: 'Reporting',
|
|
||||||
summary: 'Stay on top of things with always up-to-date reporting features.',
|
|
||||||
description:
|
|
||||||
'We talked about reporting in the section above but we needed three items here, so mentioning it one more time for posterity.',
|
|
||||||
image: screenshotProfitLoss,
|
|
||||||
icon: function ReportingIcon() {
|
|
||||||
let id = useId()
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<defs>
|
|
||||||
<linearGradient
|
|
||||||
id={id}
|
|
||||||
x1="11.5"
|
|
||||||
y1={18}
|
|
||||||
x2={36}
|
|
||||||
y2="15.5"
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
>
|
|
||||||
<stop offset=".194" stopColor="#fff" />
|
|
||||||
<stop offset={1} stopColor="#6692F1" />
|
|
||||||
</linearGradient>
|
|
||||||
</defs>
|
|
||||||
<path
|
|
||||||
d="m30 15-4 5-4-11-4 18-4-11-4 7-4-5"
|
|
||||||
stroke={`url(#${id})`}
|
|
||||||
strokeWidth={2}
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Inventory',
|
|
||||||
summary:
|
|
||||||
'Never lose track of what’s in stock with accurate inventory tracking.',
|
|
||||||
description:
|
|
||||||
'We don’t offer this as part of our software but that statement is inarguably true. Accurate inventory tracking would help you for sure.',
|
|
||||||
image: screenshotInventory,
|
|
||||||
icon: function InventoryIcon() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<path
|
|
||||||
opacity=".5"
|
|
||||||
d="M8 17a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2Z"
|
|
||||||
fill="#fff"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
opacity=".3"
|
|
||||||
d="M8 24a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2Z"
|
|
||||||
fill="#fff"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M8 10a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2Z"
|
|
||||||
fill="#fff"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Contacts',
|
|
||||||
summary:
|
|
||||||
'Organize all of your contacts, service providers, and invoices in one place.',
|
|
||||||
description:
|
|
||||||
'This also isn’t actually a feature, it’s just some friendly advice. We definitely recommend that you do this, you’ll feel really organized and professional.',
|
|
||||||
image: screenshotContacts,
|
|
||||||
icon: function ContactsIcon() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<path
|
|
||||||
opacity=".5"
|
|
||||||
d="M25.778 25.778c.39.39 1.027.393 1.384-.028A11.952 11.952 0 0 0 30 18c0-6.627-5.373-12-12-12S6 11.373 6 18c0 2.954 1.067 5.659 2.838 7.75.357.421.993.419 1.384.028.39-.39.386-1.02.036-1.448A9.959 9.959 0 0 1 8 18c0-5.523 4.477-10 10-10s10 4.477 10 10a9.959 9.959 0 0 1-2.258 6.33c-.35.427-.354 1.058.036 1.448Z"
|
|
||||||
fill="#fff"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12 28.395V28a6 6 0 0 1 12 0v.395A11.945 11.945 0 0 1 18 30c-2.186 0-4.235-.584-6-1.605ZM21 16.5c0-1.933-.5-3.5-3-3.5s-3 1.567-3 3.5 1.343 3.5 3 3.5 3-1.567 3-3.5Z"
|
|
||||||
fill="#fff"
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
function Feature({
|
|
||||||
feature,
|
|
||||||
isActive,
|
|
||||||
className,
|
|
||||||
...props
|
|
||||||
}: React.ComponentPropsWithoutRef<'div'> & {
|
|
||||||
feature: Feature
|
|
||||||
isActive: boolean
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={clsx(className, !isActive && 'opacity-75 hover:opacity-100')}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className={clsx(
|
|
||||||
'w-9 rounded-lg',
|
|
||||||
isActive ? 'bg-blue-600' : 'bg-slate-500',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<svg aria-hidden="true" className="h-9 w-9" fill="none">
|
|
||||||
<feature.icon />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h3
|
|
||||||
className={clsx(
|
|
||||||
'mt-6 text-sm font-medium',
|
|
||||||
isActive ? 'text-blue-600' : 'text-slate-600',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{feature.name}
|
|
||||||
</h3>
|
|
||||||
<p className="mt-2 font-display text-xl text-slate-900">
|
|
||||||
{feature.summary}
|
|
||||||
</p>
|
|
||||||
<p className="mt-4 text-sm text-slate-600">{feature.description}</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function FeaturesMobile() {
|
|
||||||
return (
|
|
||||||
<div className="-mx-4 mt-20 flex flex-col gap-y-10 overflow-hidden px-4 sm:-mx-6 sm:px-6 lg:hidden">
|
|
||||||
{features.map((feature) => (
|
|
||||||
<div key={feature.summary}>
|
|
||||||
<Feature feature={feature} className="mx-auto max-w-2xl" isActive />
|
|
||||||
<div className="relative mt-10 pb-10">
|
|
||||||
<div className="absolute -inset-x-4 top-8 bottom-0 bg-slate-200 sm:-inset-x-6" />
|
|
||||||
<div className="relative mx-auto w-211 overflow-hidden rounded-xl bg-white shadow-lg ring-1 shadow-slate-900/5 ring-slate-500/10">
|
|
||||||
<Image
|
|
||||||
className="w-full"
|
|
||||||
src={feature.image}
|
|
||||||
alt=""
|
|
||||||
sizes="52.75rem"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function FeaturesDesktop() {
|
|
||||||
return (
|
|
||||||
<TabGroup className="hidden lg:mt-20 lg:block">
|
|
||||||
{({ selectedIndex }) => (
|
|
||||||
<>
|
|
||||||
<TabList className="grid grid-cols-3 gap-x-8">
|
|
||||||
{features.map((feature, featureIndex) => (
|
|
||||||
<Feature
|
|
||||||
key={feature.summary}
|
|
||||||
feature={{
|
|
||||||
...feature,
|
|
||||||
name: (
|
|
||||||
<Tab className="data-selected:not-data-focus:outline-hidden">
|
|
||||||
<span className="absolute inset-0" />
|
|
||||||
{feature.name}
|
|
||||||
</Tab>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
isActive={featureIndex === selectedIndex}
|
|
||||||
className="relative"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</TabList>
|
|
||||||
<TabPanels className="relative mt-20 overflow-hidden rounded-4xl bg-slate-200 px-14 py-16 xl:px-16">
|
|
||||||
<div className="-mx-5 flex">
|
|
||||||
{features.map((feature, featureIndex) => (
|
|
||||||
<TabPanel
|
|
||||||
static
|
|
||||||
key={feature.summary}
|
|
||||||
className={clsx(
|
|
||||||
'px-5 transition duration-500 ease-in-out data-selected:not-data-focus:outline-hidden',
|
|
||||||
featureIndex !== selectedIndex && 'opacity-60',
|
|
||||||
)}
|
|
||||||
style={{ transform: `translateX(-${selectedIndex * 100}%)` }}
|
|
||||||
aria-hidden={featureIndex !== selectedIndex}
|
|
||||||
>
|
|
||||||
<div className="w-211 overflow-hidden rounded-xl bg-white shadow-lg ring-1 shadow-slate-900/5 ring-slate-500/10">
|
|
||||||
<Image
|
|
||||||
className="w-full"
|
|
||||||
src={feature.image}
|
|
||||||
alt=""
|
|
||||||
sizes="52.75rem"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</TabPanel>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="pointer-events-none absolute inset-0 rounded-4xl ring-1 ring-slate-900/10 ring-inset" />
|
|
||||||
</TabPanels>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</TabGroup>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SecondaryFeatures() {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
id="secondary-features"
|
|
||||||
aria-label="Features for simplifying everyday business tasks"
|
|
||||||
className="pt-20 pb-14 sm:pt-32 sm:pb-20 lg:pb-32"
|
|
||||||
>
|
|
||||||
<Container>
|
|
||||||
<div className="mx-auto max-w-2xl md:text-center">
|
|
||||||
<h2 className="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
|
|
||||||
Simplify everyday business tasks.
|
|
||||||
</h2>
|
|
||||||
<p className="mt-4 text-lg tracking-tight text-slate-700">
|
|
||||||
Because you’d probably be a little confused if we suggested you
|
|
||||||
complicate your everyday business tasks instead.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<FeaturesMobile />
|
|
||||||
<FeaturesDesktop />
|
|
||||||
</Container>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
import Image from 'next/image'
|
|
||||||
|
|
||||||
import { Container } from '@/components/Container'
|
|
||||||
import avatarImage1 from '@/images/avatars/avatar-1.png'
|
|
||||||
import avatarImage2 from '@/images/avatars/avatar-2.png'
|
|
||||||
import avatarImage3 from '@/images/avatars/avatar-3.png'
|
|
||||||
import avatarImage4 from '@/images/avatars/avatar-4.png'
|
|
||||||
import avatarImage5 from '@/images/avatars/avatar-5.png'
|
|
||||||
|
|
||||||
const testimonials = [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'OurWorld is so easy to use I can’t help but wonder if it’s really doing the things the government expects me to do.',
|
|
||||||
author: {
|
|
||||||
name: 'Sheryl Berge',
|
|
||||||
role: 'CEO at Lynch LLC',
|
|
||||||
image: avatarImage1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'I’m trying to get a hold of someone in support, I’m in a lot of trouble right now and they are saying it has something to do with my books. Please get back to me right away.',
|
|
||||||
author: {
|
|
||||||
name: 'Amy Hahn',
|
|
||||||
role: 'Director at Velocity Industries',
|
|
||||||
image: avatarImage4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'The best part about OurWorld is every time I pay my employees, my bank balance doesn’t go down like it used to. Looking forward to spending this extra cash when I figure out why my card is being declined.',
|
|
||||||
author: {
|
|
||||||
name: 'Leland Kiehn',
|
|
||||||
role: 'Founder of Kiehn and Sons',
|
|
||||||
image: avatarImage5,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'There are so many things I had to do with my old software that I just don’t do at all with OurWorld. Suspicious but I can’t say I don’t love it.',
|
|
||||||
author: {
|
|
||||||
name: 'Erin Powlowski',
|
|
||||||
role: 'COO at Armstrong Inc',
|
|
||||||
image: avatarImage2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'I used to have to remit tax to the EU and with OurWorld I somehow don’t have to do that anymore. Nervous to travel there now though.',
|
|
||||||
author: {
|
|
||||||
name: 'Peter Renolds',
|
|
||||||
role: 'Founder of West Inc',
|
|
||||||
image: avatarImage3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
content:
|
|
||||||
'This is the fourth email I’ve sent to your support team. I am literally being held in jail for tax fraud. Please answer your damn emails, this is important.',
|
|
||||||
author: {
|
|
||||||
name: 'Amy Hahn',
|
|
||||||
role: 'Director at Velocity Industries',
|
|
||||||
image: avatarImage4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
]
|
|
||||||
|
|
||||||
function QuoteIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
|
|
||||||
return (
|
|
||||||
<svg aria-hidden="true" width={105} height={78} {...props}>
|
|
||||||
<path d="M25.086 77.292c-4.821 0-9.115-1.205-12.882-3.616-3.767-2.561-6.78-6.102-9.04-10.622C1.054 58.534 0 53.411 0 47.686c0-5.273.904-10.396 2.712-15.368 1.959-4.972 4.746-9.567 8.362-13.786a59.042 59.042 0 0 1 12.43-11.3C28.325 3.917 33.599 1.507 39.324 0l11.074 13.786c-6.479 2.561-11.677 5.951-15.594 10.17-3.767 4.219-5.65 7.835-5.65 10.848 0 1.356.377 2.863 1.13 4.52.904 1.507 2.637 3.089 5.198 4.746 3.767 2.41 6.328 4.972 7.684 7.684 1.507 2.561 2.26 5.5 2.26 8.814 0 5.123-1.959 9.19-5.876 12.204-3.767 3.013-8.588 4.52-14.464 4.52Zm54.24 0c-4.821 0-9.115-1.205-12.882-3.616-3.767-2.561-6.78-6.102-9.04-10.622-2.11-4.52-3.164-9.643-3.164-15.368 0-5.273.904-10.396 2.712-15.368 1.959-4.972 4.746-9.567 8.362-13.786a59.042 59.042 0 0 1 12.43-11.3C82.565 3.917 87.839 1.507 93.564 0l11.074 13.786c-6.479 2.561-11.677 5.951-15.594 10.17-3.767 4.219-5.65 7.835-5.65 10.848 0 1.356.377 2.863 1.13 4.52.904 1.507 2.637 3.089 5.198 4.746 3.767 2.41 6.328 4.972 7.684 7.684 1.507 2.561 2.26 5.5 2.26 8.814 0 5.123-1.959 9.19-5.876 12.204-3.767 3.013-8.588 4.52-14.464 4.52Z" />
|
|
||||||
</svg>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Testimonials() {
|
|
||||||
return (
|
|
||||||
<section
|
|
||||||
id="testimonials"
|
|
||||||
aria-label="What our customers are saying"
|
|
||||||
className="bg-slate-50 py-20 sm:py-32"
|
|
||||||
>
|
|
||||||
<Container>
|
|
||||||
<div className="mx-auto max-w-2xl md:text-center">
|
|
||||||
<h2 className="font-display text-3xl tracking-tight text-slate-900 sm:text-4xl">
|
|
||||||
Loved by businesses worldwide.
|
|
||||||
</h2>
|
|
||||||
<p className="mt-4 text-lg tracking-tight text-slate-700">
|
|
||||||
Our software is so simple that people can’t help but fall in love
|
|
||||||
with it. Simplicity is easy when you just skip tons of
|
|
||||||
mission-critical features.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<ul
|
|
||||||
role="list"
|
|
||||||
className="mx-auto mt-16 grid max-w-2xl grid-cols-1 gap-6 sm:gap-8 lg:mt-20 lg:max-w-none lg:grid-cols-3"
|
|
||||||
>
|
|
||||||
{testimonials.map((column, columnIndex) => (
|
|
||||||
<li key={columnIndex}>
|
|
||||||
<ul role="list" className="flex flex-col gap-y-6 sm:gap-y-8">
|
|
||||||
{column.map((testimonial, testimonialIndex) => (
|
|
||||||
<li key={testimonialIndex}>
|
|
||||||
<figure className="relative rounded-2xl bg-white p-6 shadow-xl shadow-slate-900/10">
|
|
||||||
<QuoteIcon className="absolute top-6 left-6 fill-slate-100" />
|
|
||||||
<blockquote className="relative">
|
|
||||||
<p className="text-lg tracking-tight text-slate-900">
|
|
||||||
{testimonial.content}
|
|
||||||
</p>
|
|
||||||
</blockquote>
|
|
||||||
<figcaption className="relative mt-6 flex items-center justify-between border-t border-slate-100 pt-6">
|
|
||||||
<div>
|
|
||||||
<div className="font-display text-base text-slate-900">
|
|
||||||
{testimonial.author.name}
|
|
||||||
</div>
|
|
||||||
<div className="mt-1 text-sm text-slate-500">
|
|
||||||
{testimonial.author.role}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="overflow-hidden rounded-full bg-slate-50">
|
|
||||||
<Image
|
|
||||||
className="h-14 w-14 object-cover"
|
|
||||||
src={testimonial.author.image}
|
|
||||||
alt=""
|
|
||||||
width={56}
|
|
||||||
height={56}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</figcaption>
|
|
||||||
</figure>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</Container>
|
|
||||||
</section>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -74,7 +74,7 @@ export function VenturesCybercity() {
|
|||||||
Contact
|
Contact
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-50">info@ourworld.tf</a>
|
<a href="mailto:info@ourworld.tf" className="text-indigo-600 hover:text-gray-50">info@ourworld.tf</a>
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function VenturesFreezone() {
|
|||||||
Contact
|
Contact
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
<a href="mailto:info@ourworld.tf" className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function VenturesGeomind() {
|
|||||||
Contact
|
Contact
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
<a href="mailto:info@ourworld.tf" className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export function VenturesHeroApp() {
|
|||||||
Contact
|
Contact
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
<a href="mailto:info@ourworld.tf" className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ export function VenturesSikana() {
|
|||||||
Website
|
Website
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="http://ourworld.tf/" className="text-indigo-600 hover:text-gray-500">sikana.tv</a>
|
<a href="https://sikana.tv" className="text-indigo-600 hover:text-gray-500">sikana.tv</a>
|
||||||
</p>
|
</p>
|
||||||
<p className='mt-6'>
|
<p className='mt-6'>
|
||||||
Contact
|
Contact
|
||||||
</p>
|
</p>
|
||||||
<p className='text-lg/7 font-light text-gray-600'>
|
<p className='text-lg/7 font-light text-gray-600'>
|
||||||
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
<a href="mailto:info@ourworld.tf" className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</figure>
|
</figure>
|
||||||
|
|||||||
Reference in New Issue
Block a user