mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
feat: usage page fixes, implement date range picker, disable scale plan
This commit is contained in:
1 parent
2b77ab5fde
commit
e2882009de
8 files changed
+302
-27
No files matched your search
@@ -28,3 +28,4 @@ export { default as Helper } from './helper.svelte';
|
||||
export { default as Label } from './label.svelte';
|
||||
export { default as InputProjectId } from './inputProjectId.svelte';
|
||||
export { default as InputDate } from './inputDate.svelte';
|
||||
export { default as InputDateRange } from './inputDateRange.svelte';
|
||||
@@ -0,0 +1,179 @@
|
||||
<script lang="ts">
|
||||
import { createDateRangePicker, type DateRange } from '@melt-ui/svelte';
|
||||
import { Label } from '.';
|
||||
const {
|
||||
elements: {
|
||||
calendar,
|
||||
cell,
|
||||
content,
|
||||
grid,
|
||||
heading,
|
||||
nextButton,
|
||||
prevButton,
|
||||
startSegment,
|
||||
endSegment,
|
||||
trigger
|
||||
},
|
||||
states: { months, headingValue, daysOfWeek, segmentContents, value },
|
||||
helpers: { isDateDisabled, isDateUnavailable }
|
||||
} = createDateRangePicker();
|
||||
|
||||
export let data: DateRange;
|
||||
export let showLabel = true;
|
||||
export let label: string;
|
||||
export let id: string;
|
||||
export let required = false;
|
||||
export let hideRequired = false;
|
||||
export let tooltip: string;
|
||||
export let optionalText: string;
|
||||
export let showDates = true;
|
||||
|
||||
$: if ($value) {
|
||||
data = $value;
|
||||
}
|
||||
|
||||
$: console.log(data);
|
||||
</script>
|
||||
|
||||
{#if label}
|
||||
<Label {required} {hideRequired} {tooltip} {optionalText} hide={!showLabel} for={id}>
|
||||
{label}
|
||||
</Label>
|
||||
<!-- <span class="label" use:label>Hotel Nights</span> -->
|
||||
{/if}
|
||||
<div class="u-flex u-gap-4">
|
||||
{#if showDates}
|
||||
{#each $segmentContents.start as seg}
|
||||
<div {...$startSegment(seg.part)} use:startSegment>
|
||||
{seg.value}
|
||||
</div>
|
||||
{/each}
|
||||
<div aria-hidden="true">-</div>
|
||||
{#each $segmentContents.end as seg}
|
||||
<div {...$endSegment(seg.part)} use:endSegment>
|
||||
{seg.value}
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
<div>
|
||||
<button {...$trigger} use:trigger class="button is-secondary" type="button">
|
||||
<slot>Open calendar</slot>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div {...$content} use:content class="card dt-container">
|
||||
<div {...$calendar} use:calendar class="u-flex u-flex-vertical">
|
||||
<header class="u-flex u-main-space-between u-cross-center">
|
||||
<button type="button" class="button is-only-icon is-text" use:prevButton>
|
||||
<span class="icon-cheveron-left" aria-label="previous month"></span>
|
||||
</button>
|
||||
<div {...$heading} use:heading>
|
||||
{$headingValue}
|
||||
</div>
|
||||
<button type="button" class="button is-only-icon is-text" use:nextButton>
|
||||
<span class="icon-cheveron-right" aria-label="next month"></span>
|
||||
</button>
|
||||
</header>
|
||||
{#each $months as month}
|
||||
<table use:grid>
|
||||
<thead aria-hidden="true">
|
||||
<tr>
|
||||
{#each $daysOfWeek as day}
|
||||
<th class="dt-cell">
|
||||
<span class="u-flex u-main-center u-cross-center">
|
||||
{day}
|
||||
</span>
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each month.weeks as days}
|
||||
<tr>
|
||||
{#each days as date}
|
||||
<td
|
||||
class="dt-cell"
|
||||
role="gridcell"
|
||||
aria-disabled={$isDateDisabled(date) ||
|
||||
$isDateUnavailable(date)}>
|
||||
<div
|
||||
{...$cell(date, month.value)}
|
||||
use:cell
|
||||
class="u-flex u-main-center u-cross-center dt-button">
|
||||
{date.day}
|
||||
</div>
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.theme-dark) .dt-button {
|
||||
--dt-text-hover: var(--color-neutral-20);
|
||||
--dt-button-hover: var(--color-neutral-200);
|
||||
--dt-border-hover: var(--color-neutral-70);
|
||||
--dt-text-active: var(--color-neutral-60);
|
||||
--dt-button-active: var(--color-neutral-200);
|
||||
--dt-border-active: var(--color-neutral-60);
|
||||
}
|
||||
:global(.theme-light) .dt-button {
|
||||
--dt-text-hover: var(--color-neutral-100);
|
||||
--dt-button-hover: var(--color-neutral-30);
|
||||
--dt-border-hover: var(--color-neutral-15);
|
||||
--dt-text-active: var(--color-neutral-100);
|
||||
--dt-button-active: var(--color-neutral-30);
|
||||
--dt-border-active: var(--color-neutral-15);
|
||||
}
|
||||
|
||||
.dt-container {
|
||||
min-width: 20rem;
|
||||
}
|
||||
.dt-cell {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
padding: 0.1rem;
|
||||
border-radius: 100%;
|
||||
user-select: none;
|
||||
|
||||
[aria-disabled='true'] {
|
||||
pointer-events: none;
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
.dt-button {
|
||||
aspect-ratio: 1/1;
|
||||
border-radius: 100%;
|
||||
cursor: pointer;
|
||||
&:hover,
|
||||
&[data-highlighted],
|
||||
&[data-range-highlighted] {
|
||||
background-color: hsl(var(--dt-button-hover));
|
||||
color: hsl(var(--dt-text-hover));
|
||||
}
|
||||
&[data-selected] {
|
||||
background-color: hsl(var(--dt-button-active));
|
||||
color: hsl(var(--dt-text-active));
|
||||
}
|
||||
}
|
||||
|
||||
// [data-melt-calendar-cell][data-unavailable] {
|
||||
// @apply pointer-events-none text-red-400 line-through;
|
||||
// }
|
||||
|
||||
// [data-melt-calendar-cell][data-selected] {
|
||||
// @apply bg-magnum-400 text-neutral-950;
|
||||
// }
|
||||
|
||||
// [data-melt-calendar-cell][data-outside-visible-months] {
|
||||
// @apply pointer-events-none cursor-default opacity-40 hover:bg-transparent;
|
||||
// }
|
||||
|
||||
// [data-melt-calendar-cell][data-outside-month] {
|
||||
// @apply pointer-events-none cursor-default opacity-0 hover:bg-transparent;
|
||||
// }
|
||||
</style>
|
||||
@@ -38,10 +38,9 @@ export const load: LayoutLoad = async ({ depends, url }) => {
|
||||
];
|
||||
|
||||
if (!acceptedRoutes.some((n) => url.pathname.startsWith(n))) {
|
||||
const redirectUrl = url.pathname
|
||||
? `${url.search}&redirect=${url.pathname}`
|
||||
: url.search;
|
||||
throw redirect(303, `/login${redirectUrl}`);
|
||||
const redirectUrl = url.pathname ? `redirect=${url.pathname}` : '';
|
||||
const path = url.search ? `${url.search}&${redirectUrl}` : `?${redirectUrl}`;
|
||||
throw redirect(303, `/login${path}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -6,7 +6,7 @@
|
||||
import { wizard } from '$lib/stores/wizard.js';
|
||||
import { organization } from '$lib/stores/organization';
|
||||
import UsageRates from '$routes/console/wizard/cloudOrganization/usageRates.svelte';
|
||||
import { InputDate, InputSelect } from '$lib/elements/forms';
|
||||
import { InputDate, InputDateRange, InputSelect } from '$lib/elements/forms';
|
||||
import { page } from '$app/stores';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputDateRange></InputDateRange>
|
||||
|
||||
<Container>
|
||||
<Heading tag="h2" size="5">Usage</Heading>
|
||||
<div class="u-flex u-main-space-between common-section u-cross-center">
|
||||
@@ -56,7 +58,7 @@
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<InputDate id="date" label="test" showLabel={false}></InputDate>
|
||||
<!-- <InputDate id="date" label="test" showLabel={false}></InputDate> -->
|
||||
|
||||
<div class="u-flex u-gap-8 u-cross-center">
|
||||
<p class="text">Usage period:</p>
|
||||
|
||||
@@ -104,7 +104,11 @@
|
||||
</LabelCard>
|
||||
</li>
|
||||
<li>
|
||||
<LabelCard name="plan" bind:group={$createOrganization.billingPlan} value="tier-2">
|
||||
<LabelCard
|
||||
name="plan"
|
||||
bind:group={$createOrganization.billingPlan}
|
||||
value="tier-2"
|
||||
disabled>
|
||||
<svelte:fragment slot="custom">
|
||||
<div class="u-flex u-flex-vertical u-gap-4 u-width-full-line">
|
||||
<h4 class="body-text-2 u-bold">
|
||||
@@ -114,7 +118,8 @@
|
||||
{tierScale.description}
|
||||
</p>
|
||||
</div>
|
||||
<Pill>14 DAY FREE TRIAL</Pill>
|
||||
<!-- <Pill>14 DAY FREE TRIAL</Pill> -->
|
||||
<Pill>COMING SOON</Pill>
|
||||
</svelte:fragment>
|
||||
</LabelCard>
|
||||
</li>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import type { OrganizationUsage } from '$lib/sdk/billing';
|
||||
import type { Models } from '@appwrite.io/console';
|
||||
import { sizeToBytes } from '$lib/helpers/sizeConvertion';
|
||||
import { Pill } from '$lib/elements';
|
||||
|
||||
let usage: OrganizationUsage = null;
|
||||
let members: Models.MembershipList = null;
|
||||
@@ -112,6 +113,11 @@
|
||||
</h4>
|
||||
<p class="u-color-text-gray u-small">{tierFree.description}</p>
|
||||
</div>
|
||||
{#if $organization.billingPlan === 'tier-0'}
|
||||
<Pill disabled>CURRENT PLAN</Pill>
|
||||
{:else}
|
||||
<Pill>14 DAY FREE TRIAL</Pill>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</LabelCard>
|
||||
</li>
|
||||
@@ -133,6 +139,11 @@
|
||||
{tierPro.description}
|
||||
</p>
|
||||
</div>
|
||||
{#if $organization.billingPlan === 'tier-1'}
|
||||
<Pill disabled>CURRENT PLAN</Pill>
|
||||
{:else}
|
||||
<Pill>14 DAY FREE TRIAL</Pill>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</LabelCard>
|
||||
</li>
|
||||
@@ -141,7 +152,7 @@
|
||||
name="plan"
|
||||
bind:group={$changeOrganizationTier.billingPlan}
|
||||
value="tier-2"
|
||||
disabled={$organization.billingPlan === 'tier-2'}>
|
||||
disabled>
|
||||
<svelte:fragment slot="custom" let:disabled>
|
||||
<div
|
||||
class="u-flex u-flex-vertical u-gap-4 u-width-full-line"
|
||||
@@ -153,6 +164,7 @@
|
||||
{tierScale.description}
|
||||
</p>
|
||||
</div>
|
||||
<Pill disabled>COMING SOON</Pill>
|
||||
</svelte:fragment>
|
||||
</LabelCard>
|
||||
</li>
|
||||
|
||||
Reference in new issue
Block a user