Skip to content

Commit

Permalink
feat: improve entities & some logic (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
anbraten authored Oct 26, 2023
1 parent e1e0adf commit 5b3e042
Show file tree
Hide file tree
Showing 32 changed files with 791 additions and 280 deletions.
15 changes: 15 additions & 0 deletions packages/app/components/status/Invoice.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<template>
<UBadge v-if="invoice.status === 'draft'" size="xs" label="Draft" color="primary" variant="subtle" />
<UBadge v-else-if="invoice.status === 'pending'" size="xs" label="Pending" color="amber" variant="subtle" />
<UBadge v-else-if="invoice.status === 'processing'" size="xs" label="Processing" color="amber" variant="subtle" />
<UBadge v-else-if="invoice.status === 'paid'" size="xs" label="Paid" color="emerald" variant="subtle" />
<UBadge v-else-if="invoice.status === 'failed'" size="xs" label="Failed" color="rose" variant="subtle" />
</template>

<script lang="ts" setup>
import type { Invoice } from '@geprog/gringotts-client';
defineProps<{
invoice: Invoice;
}>();
</script>
13 changes: 13 additions & 0 deletions packages/app/components/status/Subscription.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<template>
<UBadge v-if="subscription.status === 'processing'" size="xs" label="Processing" color="amber" variant="subtle" />
<UBadge v-else-if="subscription.status === 'active'" size="xs" label="Active" color="emerald" variant="subtle" />
<UBadge v-else-if="subscription.status === 'error'" size="xs" label="Error" color="rose" variant="subtle" />
</template>

<script lang="ts" setup>
import type { Subscription } from '@geprog/gringotts-client';
defineProps<{
subscription: Subscription;
}>();
</script>
69 changes: 64 additions & 5 deletions packages/app/pages/customers/[customerId]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,48 @@
@select="selectSubscription"
>
<template #status-data="{ row }">
<UBadge v-if="row.status === 'active'" size="xs" label="Active" color="emerald" variant="subtle" />
<UBadge v-else-if="row.status === 'error'" size="xs" label="Error" color="rose" variant="subtle" />
<StatusSubscription :subscription="row" />
</template>

<template #lastPayment-data="{ row }">
<span v-if="row.lastPayment">{{ formatDate(row.lastPayment) }}</span>
</template>

<template #currentPeriodEnd-data="{ row }">
<span>{{ formatDate(row.currentPeriodStart) }} - {{ formatDate(row.currentPeriodEnd) }}</span>
</template>
</UTable>
</UCard>

<UCard>
<h2>Invoices</h2>

<UTable
:loading="invoicesPending"
:rows="invoices || []"
:columns="invoicesColumns"
:sort="{ column: 'date', direction: 'desc' }"
@select="selectInvoice"
>
<template #date-data="{ row }">
<span>{{ formatDate(row.date) }}</span>
</template>

<template #totalAmount-data="{ row }">
<span>{{ formatCurrency(row.totalAmount, row.currency) }}</span>
</template>

<template #status-data="{ row }">
<StatusInvoice :invoice="row" />
</template>
</UTable>
</UCard>
</div>
</template>

<script lang="ts" setup>
import { ContentType } from '@geprog/gringotts-client';
import type { PaymentMethod, Subscription } from '@geprog/gringotts-client';
import type { Invoice, PaymentMethod, Subscription } from '@geprog/gringotts-client';
const client = await useGringottsClient();
const route = useRoute();
Expand Down Expand Up @@ -133,6 +160,7 @@ const paymentMethodColumns = [
{
key: 'active',
label: 'Active',
sortable: true,
},
{
key: 'actions',
Expand Down Expand Up @@ -194,8 +222,8 @@ const subscriptionColumns = [
sortable: true,
},
{
key: 'nextPayment',
label: 'Next payment',
key: 'currentPeriodEnd',
label: 'Current period',
sortable: true,
},
];
Expand All @@ -208,6 +236,37 @@ async function selectSubscription(row: Subscription) {
await router.push(`/subscriptions/${row._id}`);
}
const invoicesColumns = [
{
key: 'number',
label: 'Number',
sortable: true,
},
{
key: 'date',
label: 'Date',
sortable: true,
},
{
key: 'status',
label: 'Status',
sortable: true,
},
{
key: 'totalAmount',
label: 'Total',
sortable: true,
},
];
const { data: invoices, pending: invoicesPending } = useAsyncData(async () => {
const { data } = await client.customer.listCustomerInvoices(customerId);
return data;
});
async function selectInvoice(row: Invoice) {
await router.push(`/invoices/${row._id}`);
}
const currency = 'EUR'; // TODO: use variable currency for balance
async function addNewPaymentMethod() {
Expand Down
64 changes: 26 additions & 38 deletions packages/app/pages/invoices/[invoiceId]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,7 @@
<div class="flex justify-between">
<h1 class="text-xl">Invoice: {{ invoice.number }}</h1>

<UBadge v-if="invoice.status === 'draft'" size="xs" label="Status: Draft" color="primary" variant="subtle" />
<UBadge
v-else-if="invoice.status === 'pending'"
size="xs"
label="Status: Pending"
color="amber"
variant="subtle"
/>
<UBadge v-else-if="invoice.status === 'paid'" size="xs" label="Status: Paid" color="emerald" variant="subtle" />
<UBadge v-else-if="invoice.status === 'failed'" size="xs" label="Status: Failed" color="rose" variant="subtle" />
<StatusInvoice :invoice="invoice" />
</div>

<UCard>
Expand All @@ -26,14 +17,20 @@
@click="downloadInvoice"
/>

<template v-if="subscription?.customer">
<router-link :to="`/customers/${subscription.customer._id}`">
<UButton :label="subscription.customer.name" icon="i-ion-people" size="sm" />
</router-link>
<router-link :to="`/subscriptions/${subscription._id}`">
<UButton label="Subscription" icon="i-ion-md-refresh" size="sm" />
</router-link>
</template>
<UButton
v-if="invoice.status === 'draft'"
label="Charge invoice"
icon="i-ion-bag-check-outline"
size="sm"
@click="chargeInvoice"
/>

<router-link v-if="invoice.customer" :to="`/customers/${invoice.customer._id}`">
<UButton :label="invoice.customer.name" icon="i-ion-people" size="sm" />
</router-link>
<router-link v-if="invoice.subscription" :to="`/subscriptions/${invoice.subscription._id}`">
<UButton label="Subscription" icon="i-ion-md-refresh" size="sm" />
</router-link>
</div>

<UForm :state="invoice" class="flex flex-col gap-4">
Expand All @@ -45,6 +42,10 @@
<DatePicker v-model="invoice.date" :disabled="disabled" />
</UFormGroup>

<UFormGroup v-if="invoice.customer" label="Customer" name="customer">
<UInput color="primary" variant="outline" v-model="invoice.customer.name" size="lg" disabled />
</UFormGroup>

<UFormGroup label="Amount" name="amount">
<UInput color="primary" variant="outline" v-model="invoice.amount" size="lg" :disabled="disabled">
<template #trailing>
Expand Down Expand Up @@ -88,18 +89,6 @@
</UInput>
</UFormGroup>

<template v-if="subscription && subscription.customer">
<UFormGroup label="Customer">
<UInput
color="primary"
variant="outline"
v-model="subscription.customer.name"
size="lg"
:disabled="disabled"
/>
</UFormGroup>
</template>

<!-- <UButton label="Save" type="submit" class="mx-auto" /> -->
</UForm>
</UCard>
Expand All @@ -121,7 +110,7 @@ const client = await useGringottsClient();
const route = useRoute();
const invoiceId = route.params.invoiceId as string;
const { data: invoice } = useAsyncData(async () => {
const { data: invoice, refresh } = useAsyncData(async () => {
const { data } = await client.invoice.getInvoice(invoiceId);
return data;
});
Expand Down Expand Up @@ -152,11 +141,10 @@ async function downloadInvoice() {
window.open(data.url, '_blank');
}
const { data: subscription } = useAsyncData(async () => {
const subscriptionId = invoice.value?.subscription?._id;
if (!subscriptionId) return null;
const { data } = await client.subscription.getSubscription(subscriptionId);
return data;
});
async function chargeInvoice() {
await client.invoice.patchInvoice(invoiceId, {
status: 'pending',
});
await refresh();
}
</script>
22 changes: 17 additions & 5 deletions packages/app/pages/invoices/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
<div class="w-full">
<h1 class="text-xl">Invoices</h1>

<UTable :loading="pending" :rows="invoices || []" :columns="invoiceColumns" @select="selectInvoice">
<UTable
:loading="pending"
:rows="invoices || []"
:columns="invoiceColumns"
:sort="{ column: 'date', direction: 'desc' }"
@select="selectInvoice"
>
<template #customer-data="{ row }">
<span>{{ row.customer.name }}</span>
</template>

<template #date-data="{ row }">
<span>{{ formatDate(row.date) }}</span>
</template>
Expand All @@ -12,10 +22,7 @@
</template>

<template #status-data="{ row }">
<UBadge v-if="row.status === 'draft'" size="xs" label="Draft" color="primary" variant="subtle" />
<UBadge v-else-if="row.status === 'pending'" size="xs" label="Pending" color="amber" variant="subtle" />
<UBadge v-else-if="row.status === 'paid'" size="xs" label="Paid" color="emerald" variant="subtle" />
<UBadge v-else-if="row.status === 'failed'" size="xs" label="Failed" color="rose" variant="subtle" />
<StatusInvoice :invoice="row" />
</template>
</UTable>
</div>
Expand All @@ -33,6 +40,11 @@ const invoiceColumns = [
label: 'Number',
sortable: true,
},
{
key: 'customer',
label: 'Customer',
sortable: true,
},
{
key: 'date',
label: 'Date',
Expand Down
33 changes: 26 additions & 7 deletions packages/app/pages/subscriptions/[subscriptionId]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
<h1 class="text-xl">Subscription: {{ subscription._id }}</h1>

<UCard>
<div class="flex justify-end mb-2 gap-2 items-center">
<UButton
v-if="subscription.status === 'error'"
label="Reset errror"
icon="i-ion-md-undo"
size="sm"
@click="resetError"
/>
</div>

<UForm :state="subscription" class="flex flex-col gap-4">
<UFormGroup v-if="subscription.customer" label="Customer" name="customer">
<UInput color="primary" variant="outline" v-model="subscription.customer.name" size="lg" disabled />
Expand All @@ -20,8 +30,12 @@
<DatePicker v-model="subscription.lastPayment" disabled />
</UFormGroup>

<UFormGroup label="Next payment" name="nextPayment">
<DatePicker v-model="subscription.nextPayment" disabled />
<UFormGroup label="Current period start" name="currentPeriodStart">
<DatePicker v-model="subscription.currentPeriodStart" disabled />
</UFormGroup>

<UFormGroup label="Current period end" name="currentPeriodEnd">
<DatePicker v-model="subscription.currentPeriodEnd" disabled />
</UFormGroup>

<UFormGroup label="Status" name="status">
Expand Down Expand Up @@ -52,10 +66,7 @@
</template>

<template #status-data="{ row }">
<UBadge v-if="row.status === 'draft'" size="xs" label="Draft" color="primary" variant="subtle" />
<UBadge v-else-if="row.status === 'pending'" size="xs" label="Pending" color="amber" variant="subtle" />
<UBadge v-else-if="row.status === 'paid'" size="xs" label="Paid" color="emerald" variant="subtle" />
<UBadge v-else-if="row.status === 'failed'" size="xs" label="Failed" color="rose" variant="subtle" />
<StatusInvoice :invoice="row" />
</template>

<template #totalAmount-data="{ row }">
Expand Down Expand Up @@ -88,7 +99,7 @@ const route = useRoute();
const router = useRouter();
const subscriptionId = route.params.subscriptionId as string;
const { data: subscription } = useAsyncData(async () => {
const { data: subscription, refresh } = useAsyncData(async () => {
const { data } = await client.subscription.getSubscription(subscriptionId);
return data;
});
Expand Down Expand Up @@ -143,4 +154,12 @@ const { data: invoices, pending: invoicesPending } = useAsyncData(async () => {
const { data } = await client.subscription.listSubscriptionInvoices(subscriptionId);
return data;
});
async function resetError() {
await client.subscription.patchSubscription(subscriptionId, {
status: 'active',
error: '',
});
await refresh();
}
</script>
19 changes: 9 additions & 10 deletions packages/app/pages/subscriptions/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
</template>

<template #status-data="{ row }">
<UBadge v-if="row.status === 'active'" size="xs" label="Active" color="emerald" variant="subtle" />
<UBadge v-else-if="row.status === 'error'" size="xs" label="Error" color="rose" variant="subtle" />
<StatusSubscription :subscription="row" />
</template>

<template #nextPayment-data="{ row }">
<span>{{ formatDate(row.nextPayment) }}</span>
<template #currentPeriodEnd-data="{ row }">
<span>{{ formatDate(row.currentPeriodStart) }} - {{ formatDate(row.currentPeriodEnd) }}</span>
</template>
</UTable>
</div>
Expand All @@ -31,18 +30,18 @@ const subscriptionColumns = [
label: 'ID',
},
{
key: 'status',
label: 'Status',
key: 'customer',
label: 'Customer',
sortable: true,
},
{
key: 'customer',
label: 'Customer',
key: 'status',
label: 'Status',
sortable: true,
},
{
key: 'nextPayment',
label: 'Next payment',
key: 'currentPeriodEnd',
label: 'Current period',
sortable: true,
},
];
Expand Down
Loading

0 comments on commit 5b3e042

Please sign in to comment.