feat: landing page + smart components

This commit is contained in:
Liyas Thomas
2021-07-02 05:01:29 +00:00
committed by GitHub
parent fb93db6ad4
commit a130cfcadb
23 changed files with 1124 additions and 55 deletions

View File

@@ -0,0 +1,118 @@
<template>
<div class="flex flex-col p-4">
<div class="flex flex-col items-center">
<p class="my-4 font-semibold tracking-widest text-center text-accent">
FEATURES
</p>
<h3
class="
max-w-xl
mt-4
mb-8
text-4xl
font-bold
leading-tight
tracking-tight
text-center
transition
text-secondaryDark
"
>
A technology-first approach to payments and finance
</h3>
</div>
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
<div
v-for="(feature, index) in features"
:key="`feature-${index}`"
class="
inline-flex
flex-col
p-8
transition
border
rounded-lg
border-divider
"
>
<i class="text-3xl material-icons text-accent">{{ feature.icon }}</i>
<div class="flex-grow">
<h2
class="
mt-4
mb-2
text-lg
font-semibold
transition
text-secondaryDark
"
>
{{ feature.title }}
</h2>
<p>
{{ feature.description }}
</p>
<p class="mt-2">
<NuxtLink :to="feature.link.target" class="link">
{{ feature.link.title }}
<i class="material-icons">chevron_right</i>
</NuxtLink>
</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
features: [
{
icon: "offline_bolt",
title: "SaaS Executives",
description:
"Unblock your barriers to new markets to sell software globally, to companies of all sizes, at all different price points, and increase your revenue growth with Koolis SaaS Commerce Platform.",
link: { title: "Learn more", target: "/settings" },
},
{
icon: "stars",
title: "Product Managers",
description:
"Dont let your billing stack hold you back. Everything you need to grow your SaaS business. Subscription billing, payments, taxes and more, in one unified platform.",
link: { title: "Learn more", target: "/settings" },
},
{
icon: "supervised_user_circle",
title: "Creators",
description:
"Kooli is for artists and creators: writers, designers, software developers, musicians, educators, filmmakers, and anyone in-between. If you make stuff, you can sell that stuff.",
link: { title: "Learn more", target: "/settings" },
},
{
icon: "build_circle",
title: "Developers",
description:
"Focus on building, not billing. Save the blood, sweat and tears for your software development, not your billing stack, with Paddles subscription and commerce platform.",
link: { title: "Learn more", target: "/settings" },
},
{
icon: "monetization_on",
title: "Finance",
description:
"All your payments, subscriptions, taxes, invoices, SaaS metrics, and more in one place. Integrate your product, CRM, and accounting with only one tool, not dozens.",
link: { title: "Learn more", target: "/settings" },
},
{
icon: "group_work",
title: "Enterprise",
description:
"Accept payments in 135+ currencies to better serve your international customers with a single integration. No international business entity required. Fees exclude GST.",
link: { title: "Learn more", target: "/settings" },
},
],
}
},
}
</script>

View File

@@ -0,0 +1,168 @@
<template>
<footer class="flex flex-col px-8 py-16">
<nav class="grid grid-cols-2 gap-4 md:grid-cols-4">
<div class="flex flex-col space-y-2">
<SmartLink
:to="
!$store.state.authUser
? localePath('/')
: localePath(`/${$store.state.login}`)
"
class="my-2"
>
<AppLogo class="h-8" />
</SmartLink>
<span> Kooli </span>
<SmartChangeLanguage />
<ul class="space-y-2">
<li>
<SmartAnchor label="Terms" to="/about/terms" class="footer-nav" />
</li>
<li>
<SmartAnchor
label="Privacy"
to="/about/privacy"
class="footer-nav"
/>
</li>
</ul>
<SmartColorModePicker />
</div>
<div class="flex flex-col space-y-2">
<h4 class="my-2 font-semibold">Solutions</h4>
<ul class="space-y-2">
<li
v-for="(item, index) in navigation.solutions"
:key="`item-${index}`"
>
<SmartAnchor
:label="item.name"
:to="item.link"
class="footer-nav"
/>
</li>
</ul>
</div>
<div class="flex flex-col space-y-2">
<h4 class="my-2 font-semibold">Platform</h4>
<ul class="space-y-2">
<li
v-for="(item, index) in navigation.platform"
:key="`item-${index}`"
>
<SmartAnchor
:label="item.name"
:to="item.link"
class="footer-nav"
/>
</li>
</ul>
</div>
<div class="flex flex-col space-y-2">
<h4 class="my-2 font-semibold">Company</h4>
<ul class="space-y-2">
<li
v-for="(item, index) in navigation.company"
:key="`item-${index}`"
>
<SmartAnchor
:label="item.name"
:to="item.link"
class="footer-nav"
/>
</li>
</ul>
</div>
</nav>
</footer>
</template>
<script>
export default {
data() {
return {
navigation: {
solutions: [
{
name: "SaaS",
link: "/settings",
},
{
name: "Products",
link: "/settings",
},
{
name: "Creators",
link: "/settings",
},
{
name: "Developers",
link: "/settings",
},
{
name: "Finance",
link: "/settings",
},
{
name: "Enterprise",
link: "/settings",
},
],
platform: [
{
name: "Payments",
link: "/settings",
},
{
name: "Subscriptions",
link: "/settings",
},
{
name: "API",
link: "https://docs.kooli.tech/api",
},
{
name: "Guides",
link: "https://docs.kooli.tech/guides",
},
],
company: [
{
name: "About",
link: "/about",
},
{
name: "Jobs",
link: "/about/jobs",
},
{
name: "Integrations",
link: "/about/integrations",
},
{
name: "Support",
link: "",
},
{
name: "Contact",
link: "/about/contact",
},
{
name: "Blog",
link: "https://blog.kooli.tech",
},
],
},
}
},
}
</script>
<style lang="scss" scoped>
.footer-nav {
&:hover,
&:focus {
@apply text-secondaryDark;
}
}
</style>

View File

@@ -0,0 +1,97 @@
<template>
<div ref="globe"></div>
</template>
<script>
import ThreeGlobe from "three-globe"
import * as THREE from "three"
import geojson from "~/assets/geojson/ne_110m_admin_0_countries.geojson"
import texture from "~/assets/images/texture.png"
export default {
data() {
return {
globe: null,
cube: null,
renderer: null,
scene: null,
camera: null,
tbControls: null,
arcsData: [...Array(40).keys()].map(() => ({
startLat: (Math.random() - 0.5) * 180,
startLng: (Math.random() - 0.5) * 360,
endLat: (Math.random() - 0.5) * 180,
endLng: (Math.random() - 0.5) * 360,
color: ["#00acee", "#aceeff", "#00ffac", "#aaef3e"][
Math.round(Math.random() * 3)
],
})),
}
},
mounted() {
this.init()
this.animate()
window.addEventListener(
"resize",
() => {
this.camera.aspect =
this.$refs.globe.clientWidth / this.$refs.globe.clientHeight
this.camera.updateProjectionMatrix()
this.renderer.setSize(
this.$refs.globe.clientWidth,
this.$refs.globe.clientHeight
)
},
false
)
},
methods: {
init() {
this.globe = new ThreeGlobe()
.globeImageUrl(texture)
.atmosphereColor("#aaaaaa")
.arcsData(this.arcsData)
.arcColor("color")
.arcDashLength(1)
.arcDashGap(5)
.arcStroke(1)
.arcDashInitialGap(() => Math.random() * 5)
.arcDashAnimateTime(2000)
.hexPolygonsData(geojson.features)
.hexPolygonResolution(3)
.hexPolygonMargin(0.5)
.hexPolygonColor(() => `#aaaaaa`)
this.renderer = new THREE.WebGLRenderer({
alpha: true,
})
this.renderer.setSize(
this.$refs.globe.clientWidth,
this.$refs.globe.clientHeight
)
this.$refs.globe.appendChild(this.renderer.domElement)
this.scene = new THREE.Scene()
this.scene.background = null
this.scene.add(this.globe)
this.scene.add(new THREE.AmbientLight(0xffffff))
this.scene.add(new THREE.DirectionalLight(0xffffff, 0.8))
this.camera = new THREE.PerspectiveCamera()
this.camera.aspect =
this.$refs.globe.clientWidth / this.$refs.globe.clientHeight
this.camera.updateProjectionMatrix()
this.camera.position.z = 300
},
animate() {
this.renderer.render(this.scene, this.camera)
requestAnimationFrame(this.animate)
this.globe.rotation.y -= 0.005
},
},
}
</script>

View File

@@ -0,0 +1,42 @@
<template>
<div class="flex p-4 relative overflow-hidden">
<div class="relative my-16 z-10 max-w-3xl">
<h2
class="
leading-none
tracking-tighter
font-semibold
text-accent text-5xl
md:text-6xl
lg:text-8xl
"
>
Open Source
</h2>
<h3
class="
text-3xl
my-8
font-mono
text-secondaryDark
md:text-4xl
lg:text-4xl
font-semibold
"
>
API Development Ecosystem
</h3>
<p class="text-lg my-4 text-secondaryLight max-w-4/5">
Millions of developers and companies build, ship, and maintain their
APIs on Hoppscotch the largest and most advanced development platform
in the world.
</p>
<div class="my-8 flex items-center">
<button class="button rounded text-xl">Get Started</button>
</div>
</div>
<div class="lg:absolute lg:inset-y-0 lg:right-0 lg:w-1/2">
<LandingGlobe class="h-64 w-full sm:h-72 md:h-96 lg:w-full lg:h-full" />
</div>
</div>
</template>

View File

@@ -0,0 +1,142 @@
<template>
<div class="flex flex-col p-4">
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
<div
class="inline-flex flex-col transition border rounded-lg border-divider"
>
<div class="flex flex-col p-8">
<p class="font-semibold tracking-widest text-accent">API</p>
<h3
class="
max-w-xl
my-4
text-4xl
font-semibold
leading-tight
tracking-tight
transition
text-secondaryDark
"
>
Powerful and easy-to-use APIs
</h3>
<p class="my-4 text-lg md:w-4/5">
We agonize over the right abstractions so your teams dont need to
stitch together disparate systems or spend months integrating
payments functionality.
</p>
<div class="flex mt-4">
<ButtonPrimary
to="https://docs.kooli.tech/guides"
label="Read the docs"
icon="chevron_right"
reverse
/>
</div>
</div>
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
<div
v-for="(api, index) in apis"
:key="`api-${index}`"
class="inline-flex flex-col p-8"
>
<i class="text-3xl material-icons text-accent">{{ api.icon }}</i>
<div class="flex-grow">
<h2
class="
mt-4
mb-2
text-lg
font-semibold
transition
text-secondaryDark
"
>
{{ api.title }}
</h2>
<p>
{{ api.description }}
</p>
<p class="mt-2">
<SmartLink :to="api.link.target" class="link">
{{ api.link.title }}
<i class="material-icons">chevron_right</i>
</SmartLink>
</p>
</div>
</div>
</div>
</div>
<div
class="
inline-flex
flex-col
p-4
transition
border
rounded-lg
border-divider
bg-primaryLight
"
>
<div class="flex">
<div class="w-3 h-3 mr-2 bg-red-500 rounded-full"></div>
<div class="w-3 h-3 mr-2 bg-yellow-500 rounded-full"></div>
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div class="flex flex-1 p-4 overflow-auto whitespace-pre">
<pre>
/*
** TailwindCSS Configuration File
**
** Docs: https://tailwindcss.com/docs/configuration
** Default: https://github.com/tailwindcss/tailwindcss/blob/master/stubs/defaultConfig.stub.js
*/
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
purgeLayersByDefault: true,
},
experimental: "all",
dark: "class",
corePlugins: {
float: false,
clear: false,
transitionDelay: false,
skew: false,
},
}
</pre>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
apis: [
{
icon: "layers",
title: "Tools for every stack",
description:
"We offer client and server libraries in everything from React, PHP to .NET and iOS.",
link: {
title: "See libraries",
target: "https://docs.kooli.tech/api",
},
},
{
icon: "extension",
title: "Prebuilt integrations",
description:
"Use integrations for systems like Shopify, PayPal, and more.",
link: { title: "Explore partners", target: "/about/integrations" },
},
],
}
},
}
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div class="flex p-4 font-mono space-x-16">
<div v-for="(stat, index) in stats" :key="`stat-${index}`">
<span class="text-xl font-bold">
{{ stat.count }}<span class="text-secondaryLight">+</span>
</span>
<br />
<span class="text-sm">
{{ stat.audience }}
</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
stats: [
{ count: "350k", audience: "Developers" },
{ count: "10k", audience: "Organizations" },
{ count: "1m", audience: "Requests" },
],
}
},
}
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div class="flex flex-col p-4">
<div class="flex flex-col items-center">
<p
class="mt-4 mb-8 font-semibold tracking-widest text-center text-accent"
>
EMPOWERING CREATORS
</p>
</div>
<div class="grid grid-cols-3 gap-4 md:grid-cols-4 lg:grid-cols-6">
<div
v-for="(user, index) in 12"
:key="`user-${index}`"
class="inline-flex flex-col items-center justify-center p-4"
>
<img
:src="`https://i.pravatar.cc/${Math.floor(
Math.random() * (600 - 400 + 1) + 400
)}`"
alt="Profile picture"
loading="lazy"
class="inline-flex flex-col object-contain object-center h-24 w-24"
/>
</div>
</div>
</div>
</template>