Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: marketing template #317

Merged
merged 5 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.md
60 changes: 60 additions & 0 deletions docs/content/templates/pricing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
template: marketing
footer: false
---

:::pricing-block{yml}

plans:
monthly:
base: true
title: Month
label: Monthly
annual:
title: Year
label: Yearly
preSelected: true
divider: 12

tiers:
free:
price:
monthly: 0
annual: 0
title: Free
description: Our Free plan description
features:
- Feature One
- Feature Two
starter:
preSelected: true
price:
monthly: 10
annual: 100
title: Starter
description: Our Starter plan pretty long multiline description
features:
- All Free Tier features
- Feature Three
- Feature Four
pro:
price:
monthly: 100
annual: 1000
title: Pro
description: Our Pro plan description
features:
- All Starter Tier features
- Feature Five
- Feature Six

meta:
currency: $
featuresTitle: 'Included features:'
buttonText: Choose plan
preSelectedBadge: Popular
checkoutText: 'Total:'
checkoutButtonText: Checkout

:::

32 changes: 32 additions & 0 deletions src/defaultTheme/components/atoms/InfoLabel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<span
class="
text-xs text-primary-500
px-2.5
py-1.5
leading-none
rounded
font-semibold
uppercase
tracking-wide
bg-primary-100
dark:bg-primary-900
dark:text-primary-400
"
>
{{ label }}
</span>
</template>

<script>
import { defineComponent } from '@nuxtjs/composition-api'
export default defineComponent({
props: {
label: {
type: String,
default: ''
}
}
})
</script>
10 changes: 2 additions & 8 deletions src/defaultTheme/components/atoms/icons/IconCheck.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
<template>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19.5 6L9 18L4.5 13.5"
stroke="currentColor"
stroke-width="1.55625"
stroke-linecap="round"
stroke-linejoin="round"
/>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
</template>
77 changes: 66 additions & 11 deletions src/defaultTheme/components/organisms/PreLaunchHero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,35 @@
<section class="flex flex-col md:flex-row d-container-content py-12 md:py-24">
<div class="w-full md:w-1/2 flex flex-col justify-center mb-8 md:mb-0">
<div class="flex flex-col items-center md:items-start mb-2">
<span
class="mx-2 text-xs mb-4 text-primary-500 px-2.5 py-1.5 leading-none rounded font-semibold uppercase tracking-wide bg-primary-100 dark:bg-primary-900 dark:text-primary-400"
>
🚀 Coming Soon
</span>
<InfoLabel label="🚀 Coming Soon" class="mx-2 mb-4" />
<h2
class="mb-2 text-5xl font-semibold sm:leading-none tracking-tighter text-center text-gray-900 md:text-left dark:text-gray-100 sm:text-6xl lg:text-7xl sm:mb-4"
class="
mb-2
text-5xl
font-semibold
sm:leading-none
tracking-tighter
text-center text-gray-900
md:text-left
dark:text-gray-100
sm:text-6xl
lg:text-7xl
sm:mb-4
"
>
{{ title }}
</h2>
<p
class="mb-2 text-base text-center text-gray-700 md:text-left sm:text-xl xl:text-2xl leading-base sm:mb-4 dark:text-gray-300"
class="
mb-2
text-base text-center text-gray-700
md:text-left
sm:text-xl
xl:text-2xl
leading-base
sm:mb-4
dark:text-gray-300
"
>
{{ description }}
</p>
Expand All @@ -25,15 +42,53 @@
{{ cta.description }}
</p>
<div
class="flex flex-col md:flex-row border border-gray-300 placeholder-gray-900 dark:border-gray-700 rounded-md p-1 w-full mb-2"
class="
flex flex-col
md:flex-row
border border-gray-300
placeholder-gray-900
dark:border-gray-700
rounded-md
p-1
w-full
mb-2
"
>
<input
type="text"
:placeholder="cta.placeholder"
class="flex-1 py-3 px-3 focus:outline-none bg-transparent dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-600"
:placeholder="ctaPlaceholder"
class="
flex-1
py-3
px-3
focus:outline-none
bg-transparent
dark:text-gray-100
placeholder-gray-400
dark:placeholder-gray-600
"
/>
<button
class="inline-block font-semibold text-center items-center flex-none px-6 py-3 text-lg leading-6 rounded-md text-white transition-colors duration-200 border border-transparent border-l-0 bg-primary-500 hover:bg-primary-600 focus:outline-none"
class="
inline-block
font-semibold
text-center
items-center
flex-none
px-6
py-3
text-lg
leading-6
rounded-md
text-white
transition-colors
duration-200
border border-transparent border-l-0
bg-primary-500
hover:bg-primary-600
focus:outline-none
select-none
"
>
{{ cta.label }}
</button>
Expand Down
112 changes: 112 additions & 0 deletions src/defaultTheme/components/organisms/PricingBlock.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<template>
<div class="px-2 my-12 md:my-24">
<div class="flex items-center justify-center my-2 md:my-8">
<div class="bg-gray-100 dark:bg-gray-800 p-1 rounded-lg">
<button
v-for="(plan, planName) in plans"
:key="planName"
class="
inline-block
font-medium
text-center
items-center
flex-none
px-2
py-1
text-sm
rounded-md
border border-transparent border-l-0
focus:outline-none
select-none
"
:class="[
selectedPlan === planName
? 'bg-white dark:bg-gray-600 shadow-sm text-gray-700 dark:text-gray-300'
: 'text-gray-500 dark:text-gray-400'
]"
@click="selectedPlan = planName"
>
{{ plan.label }}
</button>
</div>
</div>

<PricingGrid
:tiers="tiers"
:plans="plans"
:meta="meta"
:selected-plan="selectedPlan"
:selected-tier="selectedTier"
@selectTier="selectedTier = $event"
/>

<div class="flex flex-col items-center">
<div class="flex flex-col items-center mb-4">
<div class="text-gray-500 mb-1">{{ meta.checkoutText }}</div>
<div class="flex items-baseline">
<div class="flex font-bold text-4xl tracking-tighter mr-1">
<span class="">{{ meta.currency }}</span>
<span class="">{{ tiers[selectedTier].price[selectedPlan] }}</span>
</div>
<div class="text-gray-600 dark:text-gray-500">/ {{ plans[selectedPlan].title }}</div>
</div>
</div>
<button
class="
inline-block
font-semibold
text-center
items-center
flex-none
px-6
py-3
text-lg
leading-6
rounded-md
border border-transparent border-l-0
focus:outline-none
select-none
bg-primary-500
hover:bg-primary-600
text-white
"
>
{{ meta.checkoutButtonText }}
</button>
</div>
</div>
</template>

<script>
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
props: {
plans: {
type: Object,
default: () => {}
},
tiers: {
type: Object,
default: () => {}
},
meta: {
type: Object,
default: () => {}
}
},
setup(props) {
let selectedPlan = null
let selectedTier = null

Object.keys(props.plans).forEach(plan => {
if (props.plans[plan] && props.plans[plan].preSelected) selectedPlan = plan
})
Object.keys(props.tiers).forEach(tier => {
if (props.tiers[tier] && props.tiers[tier].preSelected) selectedTier = tier
})

return { selectedPlan, selectedTier }
}
})
</script>
Loading