Skip to content

Commit

Permalink
Merge pull request #36 from tighten/alk/customer-detail-page
Browse files Browse the repository at this point in the history
Add customer detail page
  • Loading branch information
faxblaster authored Aug 18, 2021
2 parents d251b6e + 3dae18b commit 80b9f25
Show file tree
Hide file tree
Showing 10 changed files with 769 additions and 56 deletions.
528 changes: 515 additions & 13 deletions dist/js/tool.js

Large diffs are not rendered by default.

97 changes: 67 additions & 30 deletions resources/js/components/ChargeDetailCard.vue
Original file line number Diff line number Diff line change
@@ -1,67 +1,104 @@
<template>
<loading-card :loading="initialLoading" class="mb-6 py-3 px-6">
<detail-text-field :field="{name: 'ID', value: charge.id}"></detail-text-field>
<detail-text-field :field="{name: 'Amount', value: amount }"></detail-text-field>
<detail-text-field :field="{name: 'Fee', value: fee }"></detail-text-field>
<detail-text-field :field="{name: 'Net', value: net }"></detail-text-field>
<detail-text-field :field="{name: 'Status', value: charge.status }"></detail-text-field>
<detail-text-field :field="{name: 'Created', value: date }"></detail-text-field>
<detail-text-field :field="{name: 'Metadata', value: charge.metadata }"></detail-text-field>
<detail-boolean-field :field="{name: 'Livemode', value: charge.livemode}"></detail-boolean-field>
<detail-boolean-field :field="{name: 'Captured', value: charge.captured}"></detail-boolean-field>
<detail-boolean-field :field="{name: 'Paid', value: charge.paid}"></detail-boolean-field>
<detail-boolean-field :field="{name: 'Refunded', value: charge.refunded}"></detail-boolean-field>
<detail-text-field :field="{name: 'Dispute', value: charge.dispute }"></detail-text-field>
<detail-text-field :field="{name: 'Fraud Details', value: charge.fraud_details }"></detail-text-field>
<detail-text-field :field="{name: 'Transfer Group', value: charge.transfer_group }"></detail-text-field>
<detail-text-field
:field="{ name: 'ID', value: charge.id }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Amount', value: amount }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Fee', value: fee }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Net', value: net }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Status', value: charge.status }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Created', value: date }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Metadata', value: charge.metadata }"
></detail-text-field>
<detail-boolean-field
:field="{ name: 'Livemode', value: charge.livemode }"
></detail-boolean-field>
<detail-boolean-field
:field="{ name: 'Captured', value: charge.captured }"
></detail-boolean-field>
<detail-boolean-field
:field="{ name: 'Paid', value: charge.paid }"
></detail-boolean-field>
<detail-boolean-field
:field="{ name: 'Refunded', value: charge.refunded }"
></detail-boolean-field>
<detail-text-field
:field="{ name: 'Dispute', value: charge.dispute }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Fraud Details', value: charge.fraud_details }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Transfer Group', value: charge.transfer_group }"
></detail-text-field>
</loading-card>
</template>

<script>
export default {
props: ['chargeId'],
props: ["chargeId"],
data() {
return {
initialLoading: true,
charge: {
amount: 0,
currency: ''
currency: "",
},
}
};
},
computed: {
amount() {
return this.formatMoney(this.charge.amount, this.charge.currency)
return this.formatMoney(this.charge.amount, this.charge.currency);
},
fee() {
if (! this.charge.balance_transaction) {
return 0
if (!this.charge.balance_transaction) {
return 0;
}
return this.formatMoney(this.charge.balance_transaction.fee, this.charge.balance_transaction.currency)
return this.formatMoney(
this.charge.balance_transaction.fee,
this.charge.balance_transaction.currency
);
},
net() {
if (! this.charge.balance_transaction) {
return 0
if (!this.charge.balance_transaction) {
return 0;
}
return this.formatMoney((this.charge.amount - this.charge.balance_transaction.fee), this.charge.currency)
return this.formatMoney(
this.charge.amount - this.charge.balance_transaction.fee,
this.charge.currency
);
},
date() {
return moment.unix(this.charge.created).format('YYYY/MM/DD h:mm:ss a')
return moment
.unix(this.charge.created)
.format("YYYY/MM/DD h:mm:ss a");
},
},
methods: {
moment: moment,
getCharge() {
Nova.request().get('/nova-vendor/nova-stripe/stripe/charges/' + this.chargeId)
Nova.request()
.get("/nova-vendor/nova-stripe/stripe/charges/" + this.chargeId)
.then((response) => {
this.charge = response.data.charge
this.initialLoading = false
Expand All @@ -70,12 +107,12 @@ export default {
},
formatMoney(amount, currency) {
return `${ (amount / 100).toFixed(2) } ${ currency.toUpperCase() }`
return `${(amount / 100).toFixed(2)} ${currency.toUpperCase()}`;
},
},
created() {
this.getCharge()
}
}
this.getCharge();
},
};
</script>
25 changes: 12 additions & 13 deletions resources/js/components/ChargesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@
data-testid="resource-table"
>
<thead>
<tr>
<!-- Id, Amount, Created date, Status-->
<th v-if="columns" v-for="column in columns" class="text-left">
<span class="inline-flex items-center capitalize">
{{ column.replaceAll('_', ' ') }}
</span>
</th>
<th>&nbsp;<!-- View --></th>
</tr>
<tr>
<!-- Id, Amount, Created date, Status-->
<th v-if="columns" v-for="column in columns" class="text-left">
<span class="inline-flex items-center capitalize">
{{ column.replaceAll('_', ' ') }}
</span>
</th>
<th>&nbsp;<!-- View --></th>
</tr>
</thead>

<tbody v-for="charge in charges">
<tr>
<td v-for="column in columns">
Expand Down Expand Up @@ -87,9 +86,6 @@ export default {
hasPrevious() {
return this.page > 1
},
statusClass(status) {
return this.statusClassList[status];
}
},
methods: {
moment: moment,
Expand Down Expand Up @@ -122,6 +118,9 @@ export default {
this.page--;
}
},
statusClass(status) {
return this.statusClassList[status];
},
},
filters: {
date(date) {
Expand Down
112 changes: 112 additions & 0 deletions resources/js/components/CustomerDetailCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<template>
<loading-card :loading="initialLoading" class="mb-6 py-3 px-6">
<detail-text-field
:field="{ name: 'ID', value: customer.id }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Name', value: customer.name }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Address', value: customer.address }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Email', value: customer.email }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Phone', value: customer.phone }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Balance', value: money(customer.currency, customer.balance) }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Created', value: date(customer.created) }"
></detail-text-field>
<detail-text-field
v-if="customer.shipping.address.line1 !== ''"
:field="{ name: 'Shipping Address', value: `${this.customer.shipping.address.line1} ${this.customer.shipping.address.line2}, ${this.customer.shipping.address.city}, ${this.customer.shipping.address.state} ${this.customer.shipping.address.postal_code}` }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Currency', value: customer.currency }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Default Source', value: customer.default_source }"
></detail-text-field>
<detail-boolean-field
:field="{ name: 'Delinquent', value: !customer.delinquent }"
></detail-boolean-field>
<detail-text-field
:field="{ name: 'Description', value: customer.description }"
></detail-text-field>g
<detail-text-field
:field="{ name: 'Discount', value: customer.discount }"
></detail-text-field>
<detail-text-field
:field="{ name: 'Invoice Prefix', value: customer.invoice_prefix }"
></detail-text-field>
<detail-boolean-field
:field="{ name: 'Livemode', value: customer.livemode }"
></detail-boolean-field>
<detail-text-field
:field="{ name: 'Metadata', value: customer.metadata }"
></detail-text-field>
<detail-text-field
:field="{
name: 'Next Invoice Sequence',
value: customer.next_invoice_sequence,
}"
></detail-text-field>
<detail-text-field
:field="{ name: 'Object', value: customer.object }"
></detail-text-field>

<detail-text-field
:field="{
name: 'Preferred Locales',
value: customer.preferred_locales,
}"
></detail-text-field>
<detail-text-field
:field="{ name: 'Tax Exempt', value: customer.tax_exempt }"
></detail-text-field>
</loading-card>
</template>

<script>
import moneyFormat from "../utils/moneyFormat";
export default {
props: ["customerId"],
data() {
return {
customer: {},
initialLoading: true,
money: moneyFormat,
};
},
computed: {
formattedShipping() {
return `${this.customer.shipping.address.line1} ${this.customer.shipping.address.line2} <br/>
${this.customer.shipping.address.city}, ${this.customer.shipping.address.state} ${this.customer.shipping.address.postal_code}`;
}
},
methods: {
date(date) {
return moment.unix(date).format("YYYY/MM/DD h:mm:ss a");
},
loadCustomer(id) {
Nova.request()
.get(
"/nova-vendor/nova-stripe/stripe/customers/" +
this.customerId
)
.then((response) => {
this.customer = response.data.customer;
this.initialLoading = false;
});
},
},
created() {
this.loadCustomer();
},
};
</script>
22 changes: 22 additions & 0 deletions resources/js/components/CustomersTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
Balance
</span>
</th>
<th>&nbsp;</th>
</tr>
</thead>

Expand All @@ -42,6 +43,27 @@
</span>
<span v-else>-</span>
</td>
<td>
<span>
<router-link
class="cursor-pointer text-70 hover:text-primary mr-3"
:to="{
name: 'customer-detail',
params: {
customerId: customer.id,
},
}"
:title="__('View')"
>
<icon
type="view"
width="22"
height="18"
view-box="0 0 22 16"
/>
</router-link>
</span>
</td>
</tr>
</tbody>
</table>
Expand Down
6 changes: 6 additions & 0 deletions resources/js/tool.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ Nova.booting((Vue, router) => {
component: require("./views/Customers"),
props: true,
},
{
name: "customer-detail",
path: "/nova-stripe/customers/:customerId",
component: require("./views/CustomerDetail"),
props: true,
},
]);
});
18 changes: 18 additions & 0 deletions resources/js/views/CustomerDetail.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<div>
<heading class="mb-6">Customer Details</heading>

<customer-detail-card :customer-id="customerId"/>
</div>
</template>

<script>
import CustomerDetailCard from "../components/CustomerDetailCard";
export default {
components: {
"customer-detail-card" : CustomerDetailCard
},
props: ["customerId"],
};
</script>
1 change: 1 addition & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@
Route::post('/stripe/charges/{id}/refund', StripeChargesController::class . '@refund');
Route::get('/stripe/balance', StripeBalanceController::class . '@index');
Route::get('/stripe/customers', StripeCustomersController::class . '@index');
Route::get('/stripe/customers/{id}', StripeCustomersController::class . '@show');
9 changes: 9 additions & 0 deletions src/Clients/StripeClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ public function refundCharge($chargeId)
}
}

public function getCustomer($id)
{
try {
return Customer::retrieve($id, ['api_key' => $this->apiKey]);
} catch (Exception $e) {

}
}

public function createCharge(array $params)
{
try {
Expand Down
Loading

0 comments on commit 80b9f25

Please sign in to comment.