Make it easier to switch between subscription plans
This commit is contained in:
@@ -140,7 +140,7 @@ onMount(() => {
|
|||||||
// Parse the results saved in the URL, if any
|
// Parse the results saved in the URL, if any
|
||||||
if (window.location.hash[0] === "#") {
|
if (window.location.hash[0] === "#") {
|
||||||
const hash = window.location.hash.replace("#", "");
|
const hash = window.location.hash.replace("#", "");
|
||||||
const result = hash.replace("#", "").split('&').reduce((res, item) => {
|
const result = hash.split('&').reduce((res, item) => {
|
||||||
const parts = item.split('=')
|
const parts = item.split('=')
|
||||||
const n = Number(parts[1])
|
const n = Number(parts[1])
|
||||||
if (n !== NaN) {
|
if (n !== NaN) {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { formatDataVolume, formatThousands } from "../util/Formatting.svelte";
|
import { formatDataVolume, formatThousands } from "../util/Formatting.svelte";
|
||||||
import Chart from "../util/Chart.svelte";
|
import Chart from "../util/Chart.svelte";
|
||||||
import StorageProgressBar from "./StorageProgressBar.svelte";
|
import StorageProgressBar from "./StorageProgressBar.svelte";
|
||||||
@@ -126,14 +126,7 @@ let load_direct_bw = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let patreon_response = ""
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (window.location.hash.startsWith("#patreon_")) {
|
|
||||||
patreon_response = window.location.hash.replace("#patreon_", "")
|
|
||||||
window.location.hash = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.user.monthly_transfer_cap > 0) {
|
if (window.user.monthly_transfer_cap > 0) {
|
||||||
transfer_cap = window.user.monthly_transfer_cap
|
transfer_cap = window.user.monthly_transfer_cap
|
||||||
} else if (window.user.subscription.monthly_transfer_cap > 0) {
|
} else if (window.user.subscription.monthly_transfer_cap > 0) {
|
||||||
@@ -176,58 +169,33 @@ onMount(() => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
update_graphs(43200, 1440, true);
|
update_graphs(43200, 1440, true);
|
||||||
})
|
|
||||||
onDestroy(() => {
|
return () => {
|
||||||
if (graph_timeout !== null) {
|
if (graph_timeout !== null) {
|
||||||
clearTimeout(graph_timeout)
|
clearTimeout(graph_timeout)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
{#if patreon_response !== ""}
|
|
||||||
{#if patreon_response === "error"}
|
|
||||||
<div class="highlight_red">
|
|
||||||
An error occurred while linking Patreon subscription. Please try
|
|
||||||
again later.
|
|
||||||
</div>
|
|
||||||
{:else if patreon_response === "pledge_not_found"}
|
|
||||||
<div class="highlight_yellow">
|
|
||||||
<p>
|
|
||||||
We were not able to find your payment on Patreon. Please
|
|
||||||
wait until the payment is confirmed and try again. Even if
|
|
||||||
the payment says confirmed on Patreon itself it takes a
|
|
||||||
while before it's communicated to pixeldrain. Please wait at
|
|
||||||
least 10 minutes and try again.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If it has been more than 30 minutes, your payment is
|
|
||||||
complete and your account is still not upgraded please
|
|
||||||
contact me at support@pixeldrain.com, or send me a message
|
|
||||||
on Patreon.
|
|
||||||
<p/>
|
|
||||||
</div>
|
|
||||||
{:else if patreon_response === "success"}
|
|
||||||
<div class="highlight_green">
|
|
||||||
Success! Your Patreon pledge has been linked to your pixeldrain
|
|
||||||
account. You are now able to use Pro features.
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
<br/>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<h2>Account information</h2>
|
<h2>Account information</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Username: {window.user.username}</li>
|
<li>Username: {window.user.username}</li>
|
||||||
<li>E-mail address: {window.user.email}</li>
|
<li>
|
||||||
|
{#if window.user.email === ""}
|
||||||
|
No e-mail address configured. You will not be able to recover
|
||||||
|
your account if you lose your password. Set an e-mail address on
|
||||||
|
the <a href="/user/settings">settings page</a>.
|
||||||
|
{:else}
|
||||||
|
E-mail address: {window.user.email}
|
||||||
|
(<a href="/user/settings">configure</a>)
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Supporter level: {window.user.subscription.name}
|
Supporter level: {window.user.subscription.name}
|
||||||
{#if window.user.subscription.type === "patreon"}
|
(<a href="/user/subscription">manage subscriptions</a> /
|
||||||
(<a href="https://www.patreon.com/join/pixeldrain/checkout?edit=1">Manage subscription</a>)
|
<a href="/api/patreon_auth/start">link patreon subscription</a>)
|
||||||
{:else if window.user.subscription.id === ""}
|
|
||||||
(<a href="/api/patreon_auth/start">Link Patreon subscription</a> /
|
|
||||||
<a href="/user/prepaid/deposit">deposit account credit</a>)
|
|
||||||
{/if}
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
|
Max file size: {formatDataVolume(window.user.subscription.file_size_limit, 3)}
|
||||||
@@ -239,17 +207,17 @@ onDestroy(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{#if window.user.balance_micro_eur !== 0}
|
|
||||||
<li>
|
<li>
|
||||||
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
||||||
(<a href="/user/prepaid/deposit">deposit credit</a>)
|
(<a href="/user/prepaid/deposit">deposit credit</a> /
|
||||||
{#if window.user.subscription.id === ""}
|
<a href="/user/prepaid/transactions">transaction log</a>)
|
||||||
|
|
||||||
|
{#if window.user.balance_micro_eur > 0 && window.user.subscription.id === ""}
|
||||||
<br/>
|
<br/>
|
||||||
You have account credit but no active subscription. Activate
|
You have account credit but no active subscription. Activate
|
||||||
a subscription on the <a href="/user/prepaid/subscriptions">subscriptions page</a>
|
a subscription on the <a href="/user/subscription">subscriptions page</a>
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/if}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{#if window.user.subscription.storage_space === -1}
|
{#if window.user.subscription.storage_space === -1}
|
||||||
@@ -259,8 +227,8 @@ onDestroy(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if transfer_cap === -1}
|
{#if transfer_cap === -1}
|
||||||
Premium transfer used in the last 30 days: {formatDataVolume(transfer_used, 3)}.
|
Premium transfer used in the last 30 days: {formatDataVolume(transfer_used, 3)}
|
||||||
<a href="/user/sharing/bandwidth">Configure limit</a>
|
(<a href="/user/sharing/bandwidth">configure limit</a>)
|
||||||
{:else}
|
{:else}
|
||||||
Transfer cap:
|
Transfer cap:
|
||||||
{formatDataVolume(transfer_used, 3)}
|
{formatDataVolume(transfer_used, 3)}
|
||||||
|
80
svelte/src/user_home/PatreonActivationResult.svelte
Normal file
80
svelte/src/user_home/PatreonActivationResult.svelte
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
let patreon_result = ""
|
||||||
|
let patreon_message = ""
|
||||||
|
let patreon_error = ""
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (window.location.hash.startsWith("#")) {
|
||||||
|
const hash = window.location.hash.replace("#", "");
|
||||||
|
const result = hash.split('&').reduce((res, item) => {
|
||||||
|
const parts = item.split('=')
|
||||||
|
res[parts[0]] = decodeURIComponent(parts[1])
|
||||||
|
return res;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
if (result.patreon_result) {
|
||||||
|
patreon_result = result.patreon_result
|
||||||
|
}
|
||||||
|
if (result.patreon_message) {
|
||||||
|
patreon_message = result.patreon_message
|
||||||
|
}
|
||||||
|
if (result.patreon_error) {
|
||||||
|
patreon_error = result.patreon_error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
{#if patreon_result !== ""}
|
||||||
|
{#if patreon_result === "error"}
|
||||||
|
<div class="highlight_red">
|
||||||
|
An error occurred while linking Patreon subscription. Please try
|
||||||
|
again later.
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
If it has been more than 30 minutes, your payment is complete and
|
||||||
|
the upgrade still fails please contact me on Patreon or through
|
||||||
|
e-mail at support@pixeldrain.com.
|
||||||
|
<p/>
|
||||||
|
<p>
|
||||||
|
When contacting support please provide the following information:<br/>
|
||||||
|
Server response: {patreon_message}<br/>
|
||||||
|
Server error code: {patreon_error}
|
||||||
|
</p>
|
||||||
|
{:else if patreon_result === "pledge_not_found"}
|
||||||
|
<div class="highlight_yellow">
|
||||||
|
<p>
|
||||||
|
We were not able to find your payment on Patreon. Please
|
||||||
|
wait until the payment is confirmed and try again. Even if
|
||||||
|
the payment says confirmed on Patreon itself it takes a
|
||||||
|
while before it's communicated to pixeldrain. Please wait at
|
||||||
|
least 10 minutes and try again.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If it has been more than 30 minutes, your payment is complete
|
||||||
|
and the upgrade still fails please contact me on Patreon or
|
||||||
|
through e-mail at support@pixeldrain.com.
|
||||||
|
<p/>
|
||||||
|
<p>
|
||||||
|
When contacting support please provide the following
|
||||||
|
information:<br/>Server response: {patreon_message}<br/>Server
|
||||||
|
error code: {patreon_error}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{:else if patreon_result === "success"}
|
||||||
|
<div class="highlight_green">
|
||||||
|
Success! Your Patreon pledge has been linked to your pixeldrain
|
||||||
|
account. You are now able to use Pro features.
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<br/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.highlight_red, .highlight_yellow {
|
||||||
|
text-align: initial;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -24,20 +24,20 @@ let pages = [
|
|||||||
icon: "settings",
|
icon: "settings",
|
||||||
component: AccountSettings,
|
component: AccountSettings,
|
||||||
}, {
|
}, {
|
||||||
path: "/user/prepaid",
|
path: "/user/subscription",
|
||||||
title: "Prepaid",
|
title: "Subscription",
|
||||||
icon: "receipt_long",
|
icon: "shopping_cart",
|
||||||
subpages: [
|
subpages: [
|
||||||
{
|
{
|
||||||
path: "/user/prepaid/deposit",
|
path: "/user/subscription",
|
||||||
title: "Deposit credit",
|
title: "Manage subscription",
|
||||||
icon: "account_balance_wallet",
|
|
||||||
component: DepositCredit,
|
|
||||||
}, {
|
|
||||||
path: "/user/prepaid/subscriptions",
|
|
||||||
title: "Subscriptions",
|
|
||||||
icon: "shopping_cart",
|
icon: "shopping_cart",
|
||||||
component: Subscription,
|
component: Subscription,
|
||||||
|
}, {
|
||||||
|
path: "/user/prepaid/deposit",
|
||||||
|
title: "Prepaid",
|
||||||
|
icon: "account_balance_wallet",
|
||||||
|
component: DepositCredit,
|
||||||
}, {
|
}, {
|
||||||
path: "/user/prepaid/transactions",
|
path: "/user/prepaid/transactions",
|
||||||
title: "Transactions",
|
title: "Transactions",
|
||||||
|
@@ -3,18 +3,21 @@ import { onMount } from "svelte";
|
|||||||
import Euro from "../util/Euro.svelte"
|
import Euro from "../util/Euro.svelte"
|
||||||
import LoadingIndicator from "../util/LoadingIndicator.svelte";
|
import LoadingIndicator from "../util/LoadingIndicator.svelte";
|
||||||
import SuccessMessage from "../util/SuccessMessage.svelte";
|
import SuccessMessage from "../util/SuccessMessage.svelte";
|
||||||
|
import PatreonActivationResult from "./PatreonActivationResult.svelte";
|
||||||
|
|
||||||
let loading = false
|
let loading = false
|
||||||
let subscription = window.user.subscription.id
|
let subscription = window.user.subscription.id
|
||||||
|
let subscription_type = window.user.subscription.type
|
||||||
let success_message
|
let success_message
|
||||||
|
|
||||||
const update = async () => {
|
const update = async (plan) => {
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
form.append("subscription", subscription)
|
form.append("subscription", plan)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
{
|
||||||
const resp = await fetch(
|
const resp = await fetch(
|
||||||
window.api_endpoint+"/user",
|
window.api_endpoint+"/user",
|
||||||
{ method: "PUT", body: form },
|
{ method: "PUT", body: form },
|
||||||
@@ -25,6 +28,19 @@ const update = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
success_message.set(true, "Subscription updated")
|
success_message.set(true, "Subscription updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const resp = await fetch(window.api_endpoint+"/user")
|
||||||
|
if(resp.status >= 400) {
|
||||||
|
let json = await resp.json()
|
||||||
|
throw json.message
|
||||||
|
}
|
||||||
|
|
||||||
|
window.user = await resp.json()
|
||||||
|
subscription = window.user.subscription.id
|
||||||
|
subscription_type = window.user.subscription.type
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
success_message.set(false, "Failed to update subscription: "+err)
|
success_message.set(false, "Failed to update subscription: "+err)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -64,27 +80,16 @@ onMount(() => {
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if window.user.subscription.type === "patreon"}
|
<PatreonActivationResult/>
|
||||||
<div class="highlight_yellow">
|
|
||||||
<p>
|
|
||||||
Activating a prepaid subscription will not cancel your active
|
|
||||||
Patreon subscription. Go to Patreon's
|
|
||||||
<a
|
|
||||||
href="https://www.patreon.com/settings/memberships">memberships
|
|
||||||
page</a> to end your subscription there.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you enable a prepaid plan here your Patreon subscription will
|
|
||||||
be overridden. If you wish to go back to your Patreon plan use
|
|
||||||
the <a href="/user/home">Link Patreon subscription</a> button on
|
|
||||||
the home page to link your Patreon account back to pixeldrain.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<h2>Manage subscription</h2>
|
<h2>Manage subscription</h2>
|
||||||
<p>
|
<p>
|
||||||
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
|
On pixeldrain you can freely switch between active subscription plans
|
||||||
|
when you want. When switching from Patreon to Prepaid/free you should
|
||||||
|
separately cancel your subscription <a
|
||||||
|
href="https://www.patreon.com/settings/memberships/pixeldrain"
|
||||||
|
target="_blank">on Patreon</a>. That does not happen automatically.
|
||||||
|
Pixeldrain cannot modify your Patreon membership in any way.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Prepaid subscriptions are charged daily based on usage. When you reach
|
Prepaid subscriptions are charged daily based on usage. When you reach
|
||||||
@@ -92,23 +97,65 @@ onMount(() => {
|
|||||||
a positive balance to activate the subscription again.
|
a positive balance to activate the subscription again.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3>Prepaid plans</h3>
|
<h3>Available subscription plans</h3>
|
||||||
<SuccessMessage bind:this={success_message}/>
|
<SuccessMessage bind:this={success_message}/>
|
||||||
|
|
||||||
<div class="feat_table">
|
<div class="feat_table">
|
||||||
|
<div>
|
||||||
|
<div class="feat_label" class:feat_highlight={subscription_type === "patreon"}>
|
||||||
|
Patreon<br/>
|
||||||
|
{#if subscription_type === "patreon"}
|
||||||
|
Currently active<br/>
|
||||||
|
<a class="button" href="https://www.patreon.com/settings/memberships/pixeldrain" target="_blank">
|
||||||
|
<i class="icon">settings</i>
|
||||||
|
Manage
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a class="button" href="/api/patreon_auth/start">
|
||||||
|
<i class="icon">add_link</i>
|
||||||
|
Link Patreon
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="feat_normal round_tr" class:feat_highlight={subscription_type === "patreon"}>
|
||||||
|
<p>
|
||||||
|
This subscription is managed by Patreon. You will need to <a
|
||||||
|
href="https://www.patreon.com/pixeldrain/membership"
|
||||||
|
target="_blank">purchase a plan on Patreon</a> before you
|
||||||
|
can activate this subscription. After your purchase you can
|
||||||
|
click the "Link Patreon" button and your account will be
|
||||||
|
upgraded.
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>€4 per month</li>
|
||||||
|
<li>2 TB storage limit (higher plans available)</li>
|
||||||
|
<li>4 TB transfer limit (higher plans available)</li>
|
||||||
|
<li>Access to the <a href="/filesystem">filesystem</a></li>
|
||||||
|
<li>File expire after 240 days for Pro, and never on the other plans</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="feat_label" class:feat_highlight={subscription === "prepaid"}>
|
<div class="feat_label" class:feat_highlight={subscription === "prepaid"}>
|
||||||
Prepaid<br/>
|
Prepaid (credit <Euro amount={window.user.balance_micro_eur}/>)<br/>
|
||||||
{#if subscription === "prepaid"}
|
{#if subscription === "prepaid"}
|
||||||
Currently active
|
Currently active
|
||||||
{:else}
|
{:else}
|
||||||
<button on:click={() => {subscription = "prepaid"; update("subscription")}}>
|
<button on:click={() => update("prepaid")}>
|
||||||
<i class="icon">attach_money</i>
|
<i class="icon">attach_money</i>
|
||||||
Activate
|
Activate
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="feat_normal round_tr" class:feat_highlight={subscription === "prepaid"}>
|
<div class="feat_normal round_tr" class:feat_highlight={subscription === "prepaid"}>
|
||||||
|
<p>
|
||||||
|
You will need a positive account balance to activate this
|
||||||
|
plan. If you currently have a Patreon subscription active,
|
||||||
|
then enabling prepaid will not cancel that subscription. You
|
||||||
|
can end your subscription <a
|
||||||
|
href="https://www.patreon.com/settings/memberships/pixeldrain"
|
||||||
|
target="_blank">on Patreon.com</a>.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Base price of €1 per month</li>
|
<li>Base price of €1 per month</li>
|
||||||
<li>€4 per TB per month for storage</li>
|
<li>€4 per TB per month for storage</li>
|
||||||
@@ -136,13 +183,17 @@ onMount(() => {
|
|||||||
{#if subscription === "prepaid_temp_storage_120d"}
|
{#if subscription === "prepaid_temp_storage_120d"}
|
||||||
Currently active
|
Currently active
|
||||||
{:else}
|
{:else}
|
||||||
<button on:click={() => {subscription = "prepaid_temp_storage_120d"; update("subscription")}}>
|
<button on:click={() => update("prepaid_temp_storage_120d")}>
|
||||||
<i class="icon">attach_money</i>
|
<i class="icon">attach_money</i>
|
||||||
Activate
|
Activate
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="feat_normal" class:feat_highlight={subscription === "prepaid_temp_storage_120d"}>
|
<div class="feat_normal" class:feat_highlight={subscription === "prepaid_temp_storage_120d"}>
|
||||||
|
<p>
|
||||||
|
You will need a positive account balance to activate this
|
||||||
|
plan.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Base price of €1 per month</li>
|
<li>Base price of €1 per month</li>
|
||||||
<li>€0.50 per TB per month for storage</li>
|
<li>€0.50 per TB per month for storage</li>
|
||||||
@@ -172,13 +223,17 @@ onMount(() => {
|
|||||||
{#if subscription === ""}
|
{#if subscription === ""}
|
||||||
Currently active
|
Currently active
|
||||||
{:else}
|
{:else}
|
||||||
<button on:click={() => {subscription = ""; update("subscription")}}>
|
<button on:click={() => update("")}>
|
||||||
<i class="icon">money_off</i>
|
<i class="icon">money_off</i>
|
||||||
Activate
|
Activate
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="feat_normal round_br" class:feat_highlight={subscription === ""}>
|
<div class="feat_normal round_br" class:feat_highlight={subscription === ""}>
|
||||||
|
<p>
|
||||||
|
Switching to the free plan with another subscription active
|
||||||
|
may cause your files to expire!
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Standard free plan, files expire after 120 days.</li>
|
<li>Standard free plan, files expire after 120 days.</li>
|
||||||
<li>Download limit of 5 GB per day</li>
|
<li>Download limit of 5 GB per day</li>
|
||||||
@@ -199,14 +254,16 @@ onMount(() => {
|
|||||||
}
|
}
|
||||||
.feat_table > div > div:first-child {
|
.feat_table > div > div:first-child {
|
||||||
flex: 0 0 25%;
|
flex: 0 0 25%;
|
||||||
max-width: 25%;
|
border-radius: 8px 0 0 8px;
|
||||||
}
|
}
|
||||||
.feat_table > div > div {
|
.feat_table > div > div {
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
margin: 0.25em;
|
margin: 2px;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
hyphens: auto;
|
hyphens: auto;
|
||||||
|
border-radius: 0 8px 8px 0;
|
||||||
|
border: 2px solid var(--separator)
|
||||||
}
|
}
|
||||||
.feat_table > div > .feat_label {
|
.feat_table > div > .feat_label {
|
||||||
border-top-left-radius: 0.5em;
|
border-top-left-radius: 0.5em;
|
||||||
@@ -221,6 +278,17 @@ onMount(() => {
|
|||||||
border: 2px solid var(--highlight_color)
|
border: 2px solid var(--highlight_color)
|
||||||
}
|
}
|
||||||
|
|
||||||
.feat_table > div > div.round_tr { border-top-right-radius: 0.5em; }
|
/* On small screens we stack the table vertically */
|
||||||
.feat_table > div > div.round_br { border-bottom-right-radius: 0.5em; }
|
@media(max-width: 800px) {
|
||||||
|
.feat_table > div {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.feat_table > div > div:first-child {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
.feat_table > div > div {
|
||||||
|
border-radius: 0 0 8px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Reference in New Issue
Block a user