UI overhaul, import fixes, fix user store
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { get_endpoint } from "lib/NovaAPI";
|
||||
import { user } from "lib/UserStore";
|
||||
import { onMount } from "svelte";
|
||||
import Expandable from "util/Expandable.svelte";
|
||||
import { formatDate } from "util/Formatting";
|
||||
@@ -7,9 +9,9 @@ let result = $state(null);
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const resp = await fetch(window.api_endpoint+"/misc/ip_address_reputation");
|
||||
const resp = await fetch(get_endpoint()+"/misc/ip_address_reputation");
|
||||
if(resp.status >= 400) {
|
||||
throw new Error(resp.text());
|
||||
throw new Error(await resp.text());
|
||||
}
|
||||
result = await resp.json()
|
||||
} catch (err) {
|
||||
@@ -66,7 +68,7 @@ onMount(async () => {
|
||||
support@nova.storage. Please do not mail unless you have a
|
||||
good reason. If you do not provide a valid reason why the ban
|
||||
should be reversed your e-mail will be ignored. And do not
|
||||
forget to put your username ({window.user.username}) in the
|
||||
forget to put your username ({$user === null ? "" : $user.username}) in the
|
||||
e-mail.
|
||||
</p>
|
||||
</Expandable>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<script>
|
||||
import Tooltip from "layout/Tooltip.svelte";
|
||||
import Euro from "util/Euro.svelte";
|
||||
import OtherPlans from "./OtherPlans.svelte";
|
||||
import OtherPlans from "./SubscriptionPlans.svelte";
|
||||
import { user } from "lib/UserStore";
|
||||
</script>
|
||||
|
||||
<section>
|
||||
@@ -222,7 +223,7 @@ import OtherPlans from "./OtherPlans.svelte";
|
||||
Free
|
||||
</div>
|
||||
<div class="bottom_row pro_feat">
|
||||
{#if window.user.subscription.id === "patreon_1"}
|
||||
{#if $user !== null && $user.subscription.id === "patreon_1"}
|
||||
You have this plan<br/>
|
||||
Thank you for supporting Nova!
|
||||
{:else}
|
||||
@@ -240,7 +241,7 @@ import OtherPlans from "./OtherPlans.svelte";
|
||||
{/if}
|
||||
</div>
|
||||
<div class="bottom_row prepaid_feat">
|
||||
{#if window.user.username === ""}
|
||||
{#if $user === null}
|
||||
<!-- User is not logged in -->
|
||||
Account required<br/>
|
||||
<a href="/login?redirect=/user/prepaid/deposit" class="button button_highlight round">
|
||||
@@ -257,16 +258,16 @@ import OtherPlans from "./OtherPlans.svelte";
|
||||
No recurring payments
|
||||
{:else}
|
||||
<!-- User is logged in -->
|
||||
{#if window.user.subscription.type === ""}
|
||||
{#if $user.subscription.type === ""}
|
||||
<a href="/user/prepaid/deposit#deposit" class="button button_highlight round">
|
||||
Deposit credit
|
||||
</a>
|
||||
to activate Prepaid
|
||||
{:else if window.user.subscription.type === "patreon"}
|
||||
{:else if $user.subscription.type === "patreon"}
|
||||
Patreon subscription active. Prepaid cannot be activated
|
||||
{:else if window.user.subscription.type === "prepaid"}
|
||||
{:else if $user.subscription.type === "prepaid"}
|
||||
Prepaid subscription is active<br/>
|
||||
Current balance <Euro amount={window.user.balance_micro_eur}/>
|
||||
Current balance <Euro amount={$user.balance_micro_eur}/>
|
||||
<br/>
|
||||
<a href="/user/prepaid/deposit#deposit" class="button button_highlight round">
|
||||
Top up my credit
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import Checkout from "layout/checkout/Checkout.svelte";
|
||||
import { user } from "lib/UserStore";
|
||||
import LoginRegister from "login/LoginRegister.svelte";
|
||||
import Euro from "util/Euro.svelte";
|
||||
</script>
|
||||
|
||||
{#if window.user.username !== ""}
|
||||
{#if $user !== null}
|
||||
<div class="page_content">
|
||||
<section>
|
||||
{#if window.user.subscription.type === "patreon"}
|
||||
{#if $user.subscription.type === "patreon"}
|
||||
<p>
|
||||
You already have a Patreon subscription active. You cannot use
|
||||
Prepaid while that subscription is active.
|
||||
</p>
|
||||
|
||||
{:else if window.user.subscription.type === "prepaid"}
|
||||
{:else if $user.subscription.type === "prepaid"}
|
||||
<p>
|
||||
You already have a Prepaid subscription active. Your account
|
||||
balance is <Euro amount={window.user.balance_micro_eur}/>. Use
|
||||
balance is <Euro amount={$user.balance_micro_eur}/>. Use
|
||||
the form below to top up your balance.
|
||||
</p>
|
||||
<Checkout/>
|
||||
{:else}
|
||||
<p>
|
||||
You are currently logged in as '{window.user.username}'. Use the
|
||||
You are currently logged in as '{$user.username}'. Use the
|
||||
form below to activate prepaid on this account.
|
||||
</p>
|
||||
<Checkout/>
|
||||
|
||||
@@ -3,9 +3,9 @@ import Menu from "filesystem/Menu.svelte";
|
||||
import Footer from "layout/Footer.svelte";
|
||||
import { drop_target } from "lib/DropTarget";
|
||||
import AddressReputation from "./AddressReputation.svelte";
|
||||
import FeatureTable from "./FeatureTable.svelte";
|
||||
import GetStarted from "./GetStarted.svelte";
|
||||
import Pricing from "./Pricing.svelte";
|
||||
import SubscriptionPlans from "./SubscriptionPlans.svelte";
|
||||
|
||||
let upload_widget
|
||||
</script>
|
||||
@@ -28,26 +28,6 @@ let upload_widget
|
||||
content delivery. We will store and serve your files at an extremely
|
||||
competitive rate.
|
||||
</p>
|
||||
<div class="prices">
|
||||
<div>
|
||||
<div>Storage pricing</div>
|
||||
<div>€ 4 / TB / month</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>Egress pricing</div>
|
||||
<div>€ 1 / TB</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>What Nova is good at</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Serving large files to millions of people worldwide
|
||||
</li>
|
||||
<li>
|
||||
Storing files for less money than all the competition
|
||||
</li>
|
||||
</ul>
|
||||
<Pricing/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -107,6 +87,11 @@ let upload_widget
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<header>
|
||||
<h1>Subscription plans</h1>
|
||||
</header>
|
||||
<SubscriptionPlans/>
|
||||
|
||||
<header>
|
||||
<h1>Get started</h1>
|
||||
</header>
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
<div class="feat_table">
|
||||
<div>
|
||||
<div class="cell_background" style="background-image: url('/res/img/benefit_2.webp');">
|
||||
Persistence<br/>
|
||||
{#if window.user.subscription.id === "patreon_2"}
|
||||
You have this plan<br/>
|
||||
Thank you for supporting Nova!
|
||||
{:else}
|
||||
<a href="https://www.patreon.com/join/nova/checkout?rid=5291482" class="button button_highlight round">
|
||||
€ 8
|
||||
</a>
|
||||
/ month
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell round_tr">
|
||||
<div><span class="text_highlight">100 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">8 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">4 TB</span> storage space</div>
|
||||
<div>
|
||||
<span class="text_highlight">File viewer
|
||||
branding</span>: Set a custom theme and header,
|
||||
footer and background images on the download pages
|
||||
for your files
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="cell_background" style="background-image: url('/res/img/benefit_3.webp');">
|
||||
Tenacity<br/>
|
||||
{#if window.user.subscription.id === "patreon_3"}
|
||||
You have this plan<br/>
|
||||
Thank you for supporting Nova!
|
||||
{:else}
|
||||
<a href="https://www.patreon.com/join/nova/checkout?rid=5291516" class="button button_highlight round">
|
||||
€ 16
|
||||
</a>
|
||||
/ month
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell">
|
||||
<div><span class="text_highlight">100 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">16 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">8 TB</span> storage space</div>
|
||||
<div><span class="text_highlight">File viewer branding</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="cell_background" style="background-image: url('/res/img/benefit_4.webp');">
|
||||
Eternity<br/>
|
||||
{#if window.user.subscription.id === "patreon_4"}
|
||||
You have this plan<br/>
|
||||
Thank you for supporting Nova!
|
||||
{:else}
|
||||
<a href="https://www.patreon.com/join/nova/checkout?rid=5291528" class="button button_highlight round">
|
||||
€ 32
|
||||
</a>
|
||||
/ month
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell">
|
||||
<div><span class="text_highlight">100 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">32 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">16 TB</span> storage space</div>
|
||||
<div><span class="text_highlight">File viewer branding</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="cell_background" style="background-image: url('/res/img/benefit_6.webp');">
|
||||
Infinity<br/>
|
||||
{#if window.user.subscription.id === "patreon_6"}
|
||||
You have this plan<br/>
|
||||
Thank you for supporting Nova!
|
||||
{:else}
|
||||
<a href="https://www.patreon.com/join/nova/checkout?rid=6573749" class="button button_highlight round">
|
||||
€ 64
|
||||
</a>
|
||||
/ month
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell round_br">
|
||||
<div><span class="text_highlight">100 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">64 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">32 TB</span> storage space</div>
|
||||
<div><span class="text_highlight">File viewer branding</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.feat_table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.feat_table > div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-height: 8em;
|
||||
}
|
||||
.feat_table > div > div:first-child {
|
||||
flex: 0 0 20%;
|
||||
max-width: 20%;
|
||||
}
|
||||
.feat_table > div > div {
|
||||
flex: 1 1 0;
|
||||
margin: 0.2em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
word-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
.feat_table > div > .feat_pro {
|
||||
background-color: var(--card_color);
|
||||
border: 1px solid var(--highlight_color);
|
||||
}
|
||||
.text_highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
.feat_table > div > .cell_background {
|
||||
flex: 0 0 33%;
|
||||
min-width: 33%;
|
||||
border-top-left-radius: 0.5em;
|
||||
border-bottom-left-radius: 0.5em;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
text-align: left;
|
||||
font-size: 1.2em;
|
||||
color: #ffffff;
|
||||
text-shadow: 1px 1px 2px #000000;
|
||||
}
|
||||
|
||||
.feat_table > div > div.round_tr { border-top-right-radius: 0.5em; }
|
||||
.feat_table > div > div.round_br { border-bottom-right-radius: 0.5em; }
|
||||
|
||||
.features_cell {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.features_cell > div {
|
||||
flex: 1 1 50%;
|
||||
min-width: 220px;
|
||||
}
|
||||
</style>
|
||||
226
svelte/src/home_page/SubscriptionPlans.svelte
Normal file
226
svelte/src/home_page/SubscriptionPlans.svelte
Normal file
@@ -0,0 +1,226 @@
|
||||
<script lang="ts">
|
||||
import Euro from "util/Euro.svelte";
|
||||
import { formatDataVolume } from "util/Formatting";
|
||||
|
||||
type Plan = {
|
||||
title: string
|
||||
monthly: number
|
||||
egress: number
|
||||
storage: number
|
||||
checkout_cadence_1?: string
|
||||
checkout_cadence_6?: string
|
||||
checkout_cadence_12?: string
|
||||
}
|
||||
|
||||
const gb = 1e9
|
||||
const tb = gb*1000
|
||||
const euro = 1e6
|
||||
|
||||
const plans: Plan[] = [
|
||||
{
|
||||
title: "Luna",
|
||||
monthly: 2*euro,
|
||||
egress: 2*tb,
|
||||
storage: 500*gb,
|
||||
// checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://www.creem.io/test/payment/prod_4WIbZB54NgOTVSGEe8kwpA",
|
||||
checkout_cadence_12: "https://www.creem.io/test/payment/prod_4A8depiWgKgJ5h5tJD2Sv7",
|
||||
}, {
|
||||
title: "Io",
|
||||
monthly: 4*euro,
|
||||
egress: 4*tb,
|
||||
storage: 1*tb,
|
||||
// checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Callisto",
|
||||
monthly: 8*euro,
|
||||
egress: 8*tb,
|
||||
storage: 2*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Mercury",
|
||||
monthly: 16*euro,
|
||||
egress: 16*tb,
|
||||
storage: 4*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Titan",
|
||||
monthly: 32*euro,
|
||||
egress: 32*tb,
|
||||
storage: 8*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Ganymede",
|
||||
monthly: 64*euro,
|
||||
egress: 64*tb,
|
||||
storage: 16*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Mars",
|
||||
monthly: 128*euro,
|
||||
egress: 128*tb,
|
||||
storage: 32*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Venus",
|
||||
monthly: 256*euro,
|
||||
egress: 256*tb,
|
||||
storage: 64*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Terra",
|
||||
monthly: 512*euro,
|
||||
egress: 512*tb,
|
||||
storage: 128*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Neptunus",
|
||||
monthly: 1024*euro,
|
||||
egress: 1024*tb,
|
||||
storage: 256*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Uranus",
|
||||
monthly: 2048*euro,
|
||||
egress: 2048*tb,
|
||||
storage: 512*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Saturnus",
|
||||
monthly: 4096*euro,
|
||||
egress: 4096*tb,
|
||||
storage: 1024*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Jupiter",
|
||||
monthly: 8192*euro,
|
||||
egress: 8192*tb,
|
||||
storage: 2048*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}, {
|
||||
title: "Sol",
|
||||
monthly: 16384*euro,
|
||||
egress: 16384*tb,
|
||||
storage: 4096*tb,
|
||||
checkout_cadence_1: "https://example.com",
|
||||
checkout_cadence_6: "https://example.com",
|
||||
checkout_cadence_12: "https://example.com",
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<div class="horizontal_scroll">
|
||||
<div class="feat_table">
|
||||
{#each plans as plan (plan.title)}
|
||||
<div class="plan">
|
||||
<div class="title">
|
||||
<span class="bold">{plan.title}</span>
|
||||
<br/>
|
||||
<Euro amount={plan.monthly}/> / month
|
||||
</div>
|
||||
<div class="features">
|
||||
<div>
|
||||
<span class="bold">{formatDataVolume(plan.storage, 0)}</span>
|
||||
storage space
|
||||
</div>
|
||||
<div>
|
||||
<span class="bold">{formatDataVolume(plan.egress, 0)}</span>
|
||||
egress traffic per month
|
||||
</div>
|
||||
</div>
|
||||
<div class="order">
|
||||
{#if plan.checkout_cadence_1 !== undefined}
|
||||
<a href="{plan.checkout_cadence_1}" class="button">
|
||||
<div class="bold">Monthly</div>
|
||||
<div><Euro amount={plan.monthly}/> / month</div>
|
||||
</a>
|
||||
{:else}
|
||||
<span>Monthly plan not available</span>
|
||||
{/if}
|
||||
{#if plan.checkout_cadence_6 !== undefined}
|
||||
<a href="{plan.checkout_cadence_6}" class="button">
|
||||
<div class="bold">Bi-yearly (save 10%)</div>
|
||||
<div><Euro amount={plan.monthly*6*.9}/> / 6 months</div>
|
||||
</a>
|
||||
{:else}
|
||||
<span>Bi-yearly plan not available</span>
|
||||
{/if}
|
||||
{#if plan.checkout_cadence_12 !== undefined}
|
||||
<a href="{plan.checkout_cadence_12}" class="button">
|
||||
<div class="bold">Yearly (save 20%)</div>
|
||||
<div><Euro amount={plan.monthly*12*.8}/> / year</div>
|
||||
</a>
|
||||
{:else}
|
||||
<span>Yearly plan not available</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.horizontal_scroll {
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
.feat_table {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
}
|
||||
.plan {
|
||||
flex: 0 0 18em;
|
||||
display: flex;
|
||||
width: 18em;
|
||||
flex-direction: column;
|
||||
border: 1px solid var(--highlight_color);
|
||||
border-radius: 8px;
|
||||
background-color: var(--body_color);
|
||||
}
|
||||
.plan > div {
|
||||
flex: 1 1 0;
|
||||
margin: 0.2em;
|
||||
padding: 0.5em;
|
||||
text-align: center;
|
||||
word-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
.plan > .order {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.plan > .order > .button {
|
||||
flex-direction: column;
|
||||
}
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user