Skip to content

Commit

Permalink
feat: process add to basket for loan id for instant lending and extra…
Browse files Browse the repository at this point in the history
…ct error scenarios
  • Loading branch information
mcstover committed Nov 16, 2021
1 parent f658b48 commit badd420
Showing 1 changed file with 234 additions and 59 deletions.
293 changes: 234 additions & 59 deletions src/pages/InstantActions/ProcessInstantLending.vue
Original file line number Diff line number Diff line change
@@ -1,57 +1,89 @@
<template>
<www-page class="instant-lending-processor kv-tailwind">
<www-page
id="instant-lending-processor"
:header-theme="lightHeader"
main-class="kv-tailwind"
>
<kv-page-container class="
tw-pt-4 tw-pb-8
md:tw-pt-6 md:tw-pb-12
lg:tw-pt-8 lg:tw-pb-1"
lg:tw-pt-8 lg:tw-pb-16"
>
<kv-grid class="tw-grid-cols-12">
<div class="
tw-col-span-12
md:tw-col-span-10 lg:tw-col-span-8
md:tw-col-start-2 lg:tw-col-start-3
tw-text-center"
md:tw-col-start-3 md:tw-col-span-8
lg:tw-col-start-4 lg:tw-col-span-6"
>
<div
v-if="loanNotFound || tokenValidationFailed"
class=""
>
<template v-if="loanNotFound">
<h1>We couldn't find that loan.</h1>
<p>This loan may have already been funded.</p>
<kv-button
to="/lend-by-category"
v-kv-track-event="['Instant Lending', 'click-Find-another-loan', 'Find another loan']"
>
Find another loan
</kv-button>
</template>
<template v-else-if="tokenValidationFailed">
<h1>Validation of your unique email link failed.</h1>
<div class="tw-text-center tw-m-0 tw-pb-2">
<kv-contentful-img
v-if="mediaProperties.url"
class=""
:contentful-src="mediaProperties.url"
:width="mediaProperties.width"
:height="mediaProperties.height"
fallback-format="jpg"
:alt="mediaProperties.description || mediaProperties.title"
/>
</div>

<h1
v-if="headline"
class="tw-text-h2 tw-mb-2 tw-text-center"
v-html="headline"
></h1>
<h3 v-if="subHeadline" class="tw-mb-2 tw-text-center" v-html="subHeadline"></h3>
<div v-if="bodyCopy" class="tw-mb-5 tw-text-center tw-prose" v-html="bodyCopy"></div>

<div class="tw-flex tw-justify-center tw-mb-5">
<kv-loading-spinner />
<br>
<div v-if="contentfulCta && contentfulCta.linkText" class="tw-mt-2 tw-text-right">
<kv-button
to="/lend-by-category"
v-kv-track-event="['Instant Lending', 'click-Find-another-loan', 'Find another loan']"
:href="contentfulCta.href"
v-kv-track-event="contentfulCta.analytics"
class="tw-mb-2"
>
Find another loan
{{ contentfulCta.linkText }}
</kv-button>
</template>
</div>
<div v-else>
<h1>Adding loan to basket</h1>
{{ loanId }} | {{ lendAmount }}
<div v-if="!showError" class="tw-flex tw-justify-center">
<kv-loading-spinner
class="tw-my-auto tw-mb-3"
/>
</div>
<div v-else>
<p>Another lender has selected this loan. Please choose a different borrower to support.</p>
<kv-button
to="/lend-by-category"
v-kv-track-event="['Instant Lending', 'click-Find-another-loan', 'Find another loan']"
</div>

<div
v-if="loan && imageHash"
class="tw-relative tw-flex tw-mx-auto tw-mb-8"
style="max-width: 26rem;"
>
<borrower-image
class="
tw-relative
tw-w-full
tw-bg-black
tw-rounded
"
:alt="'photo of ' + loan.name"
:aspect-ratio="3 / 4"
:default-image="{ width: 336 }"
:hash="imageHash"
:images="[
{ width: 416, viewSize: 480 },
{ width: 335, viewSize: 375 },
{ width: 280 },
]"
/>
<div v-if="countryName">
<summary-tag
class="tw-absolute tw-bottom-1 tw-left-1 tw-text-primary"
:city="city"
:state="state"
:country-name="countryName"
>
Find another loan
</kv-button>
<kv-material-icon
class="tw-h-2.5 tw-w-2.5 tw-mr-0.5"
:icon="mdiMapMarker"
/>
{{ formattedLocation }}
</summary-tag>
</div>
</div>
</div>
Expand All @@ -61,28 +93,73 @@
</template>

<script>
import { mdiMapMarker } from '@mdi/js';
import gql from 'graphql-tag';
import numeral from 'numeral';
import * as Sentry from '@sentry/vue';
import logFormatter from '@/util/logFormatter';
import updateLoanReservation from '@/graphql/mutation/updateLoanReservation.graphql';
import { formatContentGroupsFlat } from '@/util/contentfulUtils';
import { richTextRenderer } from '@/util/contentful/richTextRenderer';
import { lightHeader } from '@/util/siteThemes';
import WwwPage from '@/components/WwwFrame/WwwPage';
import BorrowerImage from '@/components/BorrowerProfile/BorrowerImage';
import SummaryTag from '@/components/BorrowerProfile/SummaryTag';
import KvButton from '~/@kiva/kv-components/vue/KvButton';
import KvGrid from '~/@kiva/kv-components/vue/KvGrid';
import KvContentfulImg from '~/@kiva/kv-components/vue/KvContentfulImg';
import KvLoadingSpinner from '~/@kiva/kv-components/vue/KvLoadingSpinner';
import KvPageContainer from '~/@kiva/kv-components/vue/KvPageContainer';
// import logFormatter from '@/util/logFormatter';
import KvMaterialIcon from '~/@kiva/kv-components/vue/KvMaterialIcon';
const processInstantLendingContent = gql`query instantLendingContent($loanId: Int!) {
contentful {
entries(contentKey:"process-instant-lending-cg", contentType: "contentGroup")
}
lend {
loan(id: $loanId) {
id
geocode {
city
state
country {
name
}
}
image {
id
hash
}
loanAmount
loanFundraisingInfo {
fundedAmount
reservedAmount
isExpiringSoon
}
name
status
}
}
}`;
export default {
inject: ['apollo'],
inject: ['apollo', 'cookieStore'],
metaInfo() {
return {
title: 'Instant Lending: Adding loan to basket.'
};
},
components: {
BorrowerImage,
KvButton,
KvGrid,
KvContentfulImg,
KvLoadingSpinner,
KvMaterialIcon,
KvPageContainer,
SummaryTag,
WwwPage
},
metaInfo: {
title: 'Processing Instant Lending'
},
props: {
errorType: {
type: String,
Expand All @@ -99,17 +176,94 @@ export default {
},
data() {
return {
errorCode: this.$route.query.error,
errorDescription: this.$route.query.error_description,
lightHeader,
loading: false,
loan: () => {},
loanAdded: false,
mdiMapMarker,
showError: false
};
},
apollo: {
query: processInstantLendingContent,
preFetch: true,
preFetchVariables({ route }) {
return { loanId: parseInt(route.params.loanId, 10) };
},
variables() {
return { loanId: parseInt(this.$route.params.loanId, 10) };
},
result({ data }) {
const contentfulData = data?.contentful?.entries?.items ?? null;
this.contentfulContent = contentfulData ? formatContentGroupsFlat(contentfulData) : {};
this.loan = data?.lend?.loan ?? {};
}
},
computed: {
bodyCopy() {
const defaultContent = 'We\'re getting you ready to checkout now!';
const contentfulRichText = this.genericContentBlock?.bodyCopy ?? null;
const bodyCopy = contentfulRichText ? richTextRenderer(contentfulRichText) : defaultContent;
return bodyCopy;
},
contentfulCta() {
return {
analtyics: this.genericContentBlock.primaryCtaKvTrackEvent ?? [],
href: this.genericContentBlock.primaryCtaLink ?? '#',
linkText: this.genericContentBlock.primaryCtaText ?? null,
};
},
countryName() {
return this.loan?.geocode?.country?.name || '';
},
city() {
return this.loan?.geocode?.city || '';
},
formattedLocation() {
if (this.distributionModel === 'direct') {
const formattedString = `${this.city}, ${this.state}, ${this.countryName}`;
return formattedString;
}
if (this.countryName === 'Puerto Rico') {
const formattedString = `${this.city}, PR`;
return formattedString;
}
return this.countryName;
},
genericContentBlock() {
return this.contentfulContent?.processInstantLendingCg?.contents?.[0] ?? {};
},
headline() {
// default headline
let headlineCopy = 'Adding loan to basket';
// Patch in contentful + loan name if available
if (this.loan && this.loan.name) {
headlineCopy = `${this.genericContentBlock?.headline} ${this.loan.name}`;
}
return headlineCopy;
},
imageHash() {
return this.loan?.image?.hash ?? '';
},
loanNotFound() {
return this.errorType === 'loan-not-found';
},
mediaProperties() {
const media = this.contentfulContent?.processInstantLendingCg?.media?.[0] ?? {};
return {
description: media?.description ?? '',
title: media?.title ?? '',
width: media?.file?.details?.image?.width ?? null,
height: media?.file?.details?.image?.height ?? null,
url: media?.file?.url ?? null
};
},
state() {
return this.loan?.geocode?.state || '';
},
subHeadline() {
return this.genericContentBlock.subHeadline ?? null;
},
tokenValidationFailed() {
return this.errorType === 'token-validation-failed';
}
Expand All @@ -124,12 +278,10 @@ export default {
price: numeral(this.lendAmount).format('0.00'),
},
}).then(({ errors }) => {
console.error(JSON.stringify(errors));
if (errors.length) {
if (typeof errors !== 'undefined' && errors.length) {
// Handle errors from adding to basket
errors.forEach(error => {
// this.$showTipMsg(error.message, 'error');
console.error(JSON.stringify(error));
logFormatter(error, 'error');
try {
this.$kvTrackEvent(
'Instant Lending',
Expand All @@ -140,7 +292,9 @@ export default {
} catch (e) {
// no-op
}
// Set error state
this.showError = true;
this.handleErrorRedirect();
});
} else {
try {
Expand All @@ -149,31 +303,52 @@ export default {
window.fbq('track', 'AddToCart', { content_category: 'Loan' });
}
} catch (e) {
console.error(e);
// no-op
}
// signify loan added to basket
this.loanAdded = true;
// start redirect process
this.handleRedirect();
}
}).catch(error => {
console.error(JSON.stringify(error));
// this.$showTipMsg('Failed to add loan. Please try again.', 'error');
console.log(error);
logFormatter(error, 'error');
this.$kvTrackEvent('Instant Lending', 'Add-to-Basket', 'Failed to add loan. Please try again.');
// Set error state
this.showError = true;
Sentry.captureException(error);
this.handleErrorRedirect();
}).finally(() => {
this.loading = false;
});
},
handleRedirect() {
// redirect to checkout
this.$router.push({ path: '/checkout', query: { instantLending: 'loan-added' } });
},
handleErrorRedirect() {
// redirect to error page
this.$router.push({ path: '/instant-lending-error', query: { instantLending: 'failed-to-add-loan' } });
}
},
mounted() {
// check for loan id, attempt to add to basket
if (this.loanId !== 0) {
this.addToBasket();
}
// logFormatter(
// `Auth0 authentication error: ${this.errorCode}: ${this.errorDescription}`,
// 'warn',
// { ...this.$route.query }
// );
// start timer for redirecting to checkout or error state
const redirectInterval = setInterval(() => {
if (this.loanAdded) {
clearInterval(redirectInterval);
this.handleRedirect();
} else if (this.showError) {
clearInterval(redirectInterval);
this.handleErrorRedirect();
}
}, 5500);
},
};
</script>

0 comments on commit badd420

Please sign in to comment.