169 lines
4.7 KiB
Svelte
169 lines
4.7 KiB
Svelte
<script>
|
|
import InputField from '$lib/components/InputField.svelte';
|
|
import SmallLoader from '$lib/components/SmallLoader.svelte';
|
|
import { createEventDispatcher } from 'svelte';
|
|
import { applyAction, enhance } from '$app/forms';
|
|
import { receive, send } from '$lib/utils/helpers';
|
|
import { t } from 'svelte-i18n';
|
|
import { defaultSubscription } from '$lib/utils/defaults';
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
|
|
export let form;
|
|
|
|
/** @type {App.Locals['user'] } */
|
|
export let user;
|
|
|
|
/** @type {App.Types['subscription'] | null} */
|
|
export let subscription;
|
|
|
|
console.log('Opening subscription modal with:', subscription);
|
|
$: subscription = subscription || { ...defaultSubscription() };
|
|
$: isLoading = subscription === undefined || user === undefined;
|
|
let isUpdating = false;
|
|
|
|
/** @type {import('../../routes/auth/about/[id]/$types').SubmitFunction} */
|
|
const handleUpdate = async () => {
|
|
isUpdating = true;
|
|
return async ({ result }) => {
|
|
isUpdating = false;
|
|
if (result.type === 'success' || result.type === 'redirect') {
|
|
dispatch('close');
|
|
} else {
|
|
document.querySelector('.modal .container')?.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
await applyAction(result);
|
|
};
|
|
};
|
|
</script>
|
|
|
|
{#if isLoading}
|
|
<SmallLoader width={30} message={$t('loading.subscription_data')} />
|
|
{:else if user && subscription}
|
|
<form class="content" action="?/updateSubscription" method="POST" use:enhance={handleUpdate}>
|
|
<input name="susbscription[id]" type="hidden" bind:value={subscription.id} />
|
|
<h1 class="step-title" style="text-align: center;">
|
|
{subscription.id ? $t('subscriptions.edit') : $t('subscriptions.create')}
|
|
</h1>
|
|
{#if form?.errors}
|
|
{#each form?.errors as error (error.id)}
|
|
<h4
|
|
class="step-subtitle warning"
|
|
in:receive|global={{ key: error.id }}
|
|
out:send|global={{ key: error.id }}
|
|
>
|
|
{$t(error.field) + ': ' + $t(error.key)}
|
|
</h4>
|
|
{/each}
|
|
{/if}
|
|
<div class="tab-content" style="display: block">
|
|
<InputField
|
|
name="subscription[name]"
|
|
label={$t('subscriptions.name')}
|
|
bind:value={subscription.name}
|
|
placeholder={$t('placeholder.subscription_name')}
|
|
required={true}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
<InputField
|
|
name="subscription[details]"
|
|
label={$t('details')}
|
|
type="textarea"
|
|
bind:value={subscription.details}
|
|
placeholder={$t('placeholder.subscription_details')}
|
|
required={true}
|
|
/>
|
|
<InputField
|
|
name="subscription[conditions]"
|
|
type="textarea"
|
|
label={$t('subscriptions.conditions')}
|
|
bind:value={subscription.conditions}
|
|
placeholder={$t('placeholder.subscription_conditions')}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
<InputField
|
|
name="subscription[monthly_fee]"
|
|
type="number"
|
|
label={$t('subscriptions.monthly_fee')}
|
|
bind:value={subscription.monthly_fee}
|
|
placeholder={$t('placeholder.subscription_monthly_fee')}
|
|
required={true}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
<InputField
|
|
name="subscription[hourly_rate]"
|
|
type="number"
|
|
label={$t('subscriptions.hourly_rate')}
|
|
bind:value={subscription.hourly_rate}
|
|
required={true}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
<InputField
|
|
name="subscription[included_hours_per_year]"
|
|
type="number"
|
|
label={$t('subscriptions.included_hours_per_year')}
|
|
bind:value={subscription.included_hours_per_year}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
<InputField
|
|
name="included_hours_per_month"
|
|
type="number"
|
|
label={$t('subscriptions.included_hours_per_month')}
|
|
bind:value={subscription.included_hours_per_month}
|
|
readonly={subscription.id > 0}
|
|
/>
|
|
</div>
|
|
<div class="button-container">
|
|
{#if isUpdating}
|
|
<SmallLoader width={30} message={$t('loading.updating')} />
|
|
{:else}
|
|
<button type="button" class="button-dark" on:click={() => dispatch('cancel')}>
|
|
{$t('cancel')}</button
|
|
>
|
|
<button type="submit" class="button-dark">{$t('confirm')}</button>
|
|
{/if}
|
|
</div>
|
|
</form>
|
|
{/if}
|
|
|
|
<style>
|
|
.tab-content {
|
|
padding: 1rem;
|
|
border-radius: 0 0 3px 3px;
|
|
background-color: var(--surface0);
|
|
border: 1px solid var(--surface1);
|
|
margin-top: 1rem;
|
|
}
|
|
.button-container {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
margin-top: 1rem;
|
|
width: 100%;
|
|
}
|
|
|
|
.button-container button {
|
|
flex: 1 1 0;
|
|
min-width: 120px;
|
|
max-width: calc(50% - 5px);
|
|
background-color: var(--surface1);
|
|
color: var(--text);
|
|
border: 1px solid var(--overlay0);
|
|
transition: all 0.2s ease-in-out;
|
|
}
|
|
|
|
.button-container button:hover {
|
|
background-color: var(--surface2);
|
|
border-color: var(--lavender);
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.button-container button {
|
|
flex-basis: 100%;
|
|
max-width: none;
|
|
}
|
|
}
|
|
</style>
|