mirror of
https://github.com/pockethost/pockethost.git
synced 2025-03-30 15:08:30 +00:00
enh: dashboard black friday updates
This commit is contained in:
parent
7f63c48008
commit
dc639647c2
@ -15,6 +15,7 @@
|
||||
"dockerode",
|
||||
"esbuild",
|
||||
"eventsource",
|
||||
"Flouder's",
|
||||
"fullchain",
|
||||
"geoip",
|
||||
"getenv",
|
||||
|
@ -7,20 +7,21 @@
|
||||
import Avatar from '$src/routes/Navbar/Avatar.svelte'
|
||||
</script>
|
||||
|
||||
<div class="text-xl">My Account</div>
|
||||
<div>
|
||||
<Avatar class="w-5 h-5" />
|
||||
Change your avatar on
|
||||
<a href="https://gravatar.com/profile" class="link">Gravatar</a>
|
||||
</div>
|
||||
<div>
|
||||
Your plan: <span class="text-success font-bold"
|
||||
>{PLAN_NAMES[$userSubscriptionType]}</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
Need to change or cancel? <a href="/support" class="link">Contact support</a>
|
||||
</div>
|
||||
<div class="w-[300px] m-4">
|
||||
<FlounderCard />
|
||||
<div class="p-4">
|
||||
<div class="text-2xl m-4">My Account</div>
|
||||
<div class="m-4">
|
||||
Your plan: <span class="text-success font-bold"
|
||||
>{PLAN_NAMES[$userSubscriptionType]}</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<a class="m-4 btn btn-neutral" href="https://gravatar.com/profile">
|
||||
<Avatar class="w-5 h-5" />
|
||||
Update Avatar
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a class="m-4 btn btn-neutral" href="/support"> Manage Membership </a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,10 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { PLAN_NAMES, SubscriptionType } from 'pockethost'
|
||||
import { stats, userStore } from '$util/stores'
|
||||
import { onMount } from 'svelte'
|
||||
import PricingCard from '$src/routes/(static)/pricing/PricingCard.svelte'
|
||||
import { client } from '$src/pocketbase-client'
|
||||
import { writable } from 'svelte/store'
|
||||
|
||||
export let priceMonthly: [number, string?, number?] = [
|
||||
359,
|
||||
@ -16,20 +13,18 @@
|
||||
'year (save 55%)',
|
||||
99,
|
||||
]
|
||||
export let comingSoonText = ''
|
||||
export let comingSoon = false
|
||||
export let startDate: Date | null = null
|
||||
export let endDate: Date | null = null
|
||||
</script>
|
||||
|
||||
<PricingCard
|
||||
name={`${PLAN_NAMES[SubscriptionType.Flounder]}`}
|
||||
qtyRemaining={1000 - $stats.total_flounder_subscribers}
|
||||
qtyMax={1000}
|
||||
{comingSoonText}
|
||||
{comingSoon}
|
||||
{endDate}
|
||||
{startDate}
|
||||
availableText="Super Secret Stealth Mode Pre Black Friday, Pre Cyber Monday Earlybird Presale 20% Off Discount Code Special"
|
||||
description="Epic elite! The Flounder's Edition is almost as good as the Founder's edition, and you'll help PocketHost go global"
|
||||
availableText="Sale ends"
|
||||
description="Epic elite! The Flounder's Edition is almost as good as the Founder's edition, and you'll help PocketHost go global."
|
||||
{priceMonthly}
|
||||
{priceAnnually}
|
||||
checkoutMonthURL="https://store.pockethost.io/buy/9ff8775b-6b9e-4aa8-a0ab-dc5e58e25408?checkout[custom][user_id]={$userStore?.id}&checkout[email]={$userStore?.email}&checkout[discount_code]=G0MTI0OQ"
|
||||
|
@ -40,16 +40,10 @@
|
||||
</div>
|
||||
|
||||
<div class="w-96">
|
||||
<FlounderCard
|
||||
comingSoonText="ON SALE BLACK FRIDAY"
|
||||
comingSoon
|
||||
startDate={new Date(2024, 10, 29)}
|
||||
/>
|
||||
<FlounderCard endDate={new Date(2024, 11, 3)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6">
|
||||
<PricingTable />
|
||||
</div>
|
||||
<PricingTable />
|
||||
</div>
|
||||
|
@ -2,6 +2,7 @@
|
||||
import { faClock, faCheck, faTimes } from '@fortawesome/free-solid-svg-icons'
|
||||
import Fa from 'svelte-fa'
|
||||
import { onMount, onDestroy } from 'svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
export let name = ''
|
||||
export let description = ''
|
||||
export let priceMonthly: [number, string?, number?] = [0, '']
|
||||
@ -10,24 +11,26 @@
|
||||
export let checkoutYearURL = ''
|
||||
export let qtyMax = 0
|
||||
export let qtyRemaining = 0
|
||||
export let comingSoon = false
|
||||
export let soldOutText = 'SOLD OUT'
|
||||
export let comingSoonText = 'COMING SOON'
|
||||
export let availableText = 'AVAILABLE'
|
||||
export let features: string[] = []
|
||||
export let fundingGoals: string[] = []
|
||||
export let startDate: Date | null = null
|
||||
export let endDate: Date | null = null
|
||||
|
||||
const comingSoon = startDate && startDate > new Date()
|
||||
|
||||
$: qtySold = qtyMax - qtyRemaining
|
||||
|
||||
let countdown = ''
|
||||
let countdownInterval: ReturnType<typeof setInterval>
|
||||
|
||||
function updateCountdown() {
|
||||
if (!startDate) return
|
||||
function updateCountdown(date: Date | null) {
|
||||
if (!date) return
|
||||
|
||||
const now = new Date()
|
||||
const difference = startDate.getTime() - now.getTime()
|
||||
const difference = date.getTime() - now.getTime()
|
||||
|
||||
if (difference <= 0) {
|
||||
countdown = ''
|
||||
@ -46,10 +49,17 @@
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (startDate) {
|
||||
updateCountdown()
|
||||
countdownInterval = setInterval(updateCountdown, 1000)
|
||||
if (!startDate && !endDate) return
|
||||
const _update = () => {
|
||||
if (startDate && comingSoon) {
|
||||
updateCountdown(startDate)
|
||||
}
|
||||
if (endDate && !comingSoon) {
|
||||
updateCountdown(endDate)
|
||||
}
|
||||
}
|
||||
countdownInterval = setInterval(_update, 1000)
|
||||
_update()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
@ -78,18 +88,15 @@
|
||||
|
||||
{#if qtyRemaining <= 0}
|
||||
<div class="text-error text-xl font-black text-center">{soldOutText}</div>
|
||||
{:else if comingSoon}
|
||||
<div class="text-secondary text-xl font-black text-center">
|
||||
{comingSoonText}
|
||||
</div>
|
||||
{#if startDate && countdown}
|
||||
<div class="text-center">
|
||||
<div class="flex items-center justify-center">
|
||||
<Fa icon={faClock} class="mr-2 text-accent" />
|
||||
<span class="text-lg font-semibold text-accent">{countdown}</span>
|
||||
</div>
|
||||
{:else if startDate || endDate}
|
||||
<div class="text-center">
|
||||
<div class="flex items-center justify-center">
|
||||
<Fa icon={faClock} class="mr-2 text-accent" />
|
||||
<span class="text-lg font-semibold text-accent"
|
||||
>{comingSoon ? comingSoonText : availableText} {countdown}</span
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-accent text-xl font-black text-center">
|
||||
{availableText}
|
||||
|
@ -91,16 +91,17 @@
|
||||
]
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center items-center flex-col space-y-10">
|
||||
<div class="text-xl text-center">
|
||||
Feature comparison
|
||||
<div class="text-neutral-content text-sm p-2">
|
||||
Learn more about our <a href="/docs/pricing-ethos" class="link"
|
||||
>pricing ethos</a
|
||||
>
|
||||
and <a href="/terms" class="link">Fair Use</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-info text-info-content p-4 text-center text-lg">
|
||||
Learn more about our <a href="/docs/pricing-ethos" class="link"
|
||||
>pricing ethos</a
|
||||
>
|
||||
and <a href="/terms" class="link">Fair Use</a>.
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex justify-center items-center flex-col space-y-10 p-10 bg-emerald-950"
|
||||
>
|
||||
<div class="text-2xl text-center">Feature comparison</div>
|
||||
|
||||
<table class="hidden md:table border-spacing-x-8 max-w-[354px] md:max-w-md">
|
||||
<thead class="table-header-group">
|
||||
@ -125,7 +126,7 @@
|
||||
href={$userStore && $isUserVerified
|
||||
? pPrice.link
|
||||
: `/login`}
|
||||
class="btn btn-sm btn-neutral text-base mb-2"
|
||||
class="btn btn-sm btn-secondary text-base mb-2"
|
||||
>
|
||||
{pPrice.text}
|
||||
</a>
|
||||
|
@ -8,6 +8,7 @@
|
||||
import '@beyonk/gdpr-cookie-consent-banner/banner.css' // optional, you can also define your own styles
|
||||
// @ts-ignore
|
||||
import GdprBanner from '@beyonk/gdpr-cookie-consent-banner'
|
||||
import PromoBanner from './PromoBanner.svelte'
|
||||
|
||||
onMount(() => {
|
||||
init()
|
||||
@ -18,6 +19,7 @@
|
||||
|
||||
<div>
|
||||
<Navbar />
|
||||
<PromoBanner />
|
||||
|
||||
<div class="px-4 sm:px-6 lg:px-8">
|
||||
<VerifyAccountBar />
|
||||
|
16
packages/dashboard/src/routes/PromoBanner.svelte
Normal file
16
packages/dashboard/src/routes/PromoBanner.svelte
Normal file
@ -0,0 +1,16 @@
|
||||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<div class="text-info-content">
|
||||
This promo banner will go away after Dec 2. Please spread the word and help
|
||||
close the Flouder's round.
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://www.producthunt.com/posts/pockethost?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-pockethost"
|
||||
class="btn btn-sm btn-neutral">Vote on Product Hunt</a
|
||||
>
|
||||
<a href="/pricing" class="btn btn-sm btn-neutral">Black Friday ON now!</a>
|
||||
</div>
|
||||
</div>
|
Loading…
x
Reference in New Issue
Block a user