Skip to content

Commit

Permalink
feat(payment): fix and finish datapack sub form
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasRichel committed Oct 29, 2021
1 parent 03a5280 commit b7feb00
Show file tree
Hide file tree
Showing 16 changed files with 174 additions and 87 deletions.
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ VUE_APP_URL_BIMDATACONNECT=https://connect-staging.bimdata.io
VUE_APP_URL_DOCUMENTATION=https://developers-staging.bimdata.io
VUE_APP_URL_MARKETPLACE=https://marketplace-staging.bimdata.io
VUE_APP_URL_OLD_PLATFORM=https://platform-old-staging.bimdata.io

# Subscription/Payment config
VUE_APP_PAYMENT_ENABLED=false
VUE_APP_PLATFORM_SUBSCRIPTION_PLAN_ID=
VUE_APP_DATAPACK_SUBSCRIPTION_PLAN_ID=
VUE_APP_PLATFORM_SUBSCRIPTION_STORAGE=1073741824
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
</template>

<script>
import { computed, ref } from "vue";
import { computed, inject, ref, watch } from "vue";
import { usePaddle } from "@/composables/paddle.js";
import { useSubscriptions } from "@/state/subscriptions.js";
Expand All @@ -63,22 +63,31 @@ export default {
type: Object,
required: true
},
subscriptions: {
type: Array,
required: true
subscription: {
type: Object,
default: null
}
},
emits: ["quantity-updated", "datapack-created"],
emits: ["quantity-updated", "datapack-created", "datapack-updated"],
setup(props, { emit }) {
const { getDatapackPrice } = usePaddle();
const { createDatapackSubscription } = useSubscriptions();
const { createDatapackSubscription, updateDatapackSubscription } =
useSubscriptions();
const loading = inject("loading", false);
const datapack = computed(() => props.subscription?.data_packs[0]);
const loading = ref(false);
const quantity = ref(1);
const unitPrice = ref(0);
const currency = ref("");
const totalPrice = computed(() => quantity.value * unitPrice.value);
watch(
() => quantity.value,
() => emit("quantity-updated", quantity.value)
);
// Get localized datapack price from Paddle
getDatapackPrice().then(({ price, currency: curr }) => {
unitPrice.value = price;
Expand All @@ -88,19 +97,27 @@ export default {
const decrement = () => {
if (quantity.value > 1) {
quantity.value--;
emit("quantity-updated", quantity.value);
}
};
const increment = () => {
quantity.value++;
emit("quantity-updated", quantity.value);
};
const submit = async () => {
try {
loading.value = true;
await createDatapackSubscription(props.space, quantity.value);
emit("datapack-created");
if (datapack.value) {
await updateDatapackSubscription(
props.space,
datapack.value,
datapack.value.quantity + quantity.value
);
emit("datapack-updated");
} else {
await createDatapackSubscription(props.space, quantity.value);
emit("datapack-created");
}
quantity.value = 1; // Reset quantity value
} finally {
loading.value = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
}

.text {
:first-child {
& > :first-child {
&::after {
content: " :";
}
}
:last-child {
& > :last-child {
font-size: 1.2rem;
font-weight: bold;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@
{{ $t("DatapackSubInfo.storage") }}
</div>
<div>
{{ totalQuantity }}
GB
<span>{{ formatBytes(spaceInfo.smartDataSizeAvailable) }}</span>
<span>
({{
$t("DatapackSubInfo.including", { quantity: datapacksQuantity })
}})
</span>
</div>
</div>
</div>
</div>
</template>

<script>
import { computed, ref, watch } from "vue";
import { computed } from "vue";
import { formatBytes } from "@/utils/files.js";
import heading from "./heading.svg";
import image from "./image.svg";
Expand All @@ -39,34 +44,25 @@ export default {
type: Object,
required: true
},
subscriptions: {
type: Array,
required: true
subscription: {
type: Object,
default: null
}
},
setup(props) {
const subscription = ref({});
const datapacks = ref([]);
const totalQuantity = computed(() =>
const datapacks = computed(() => props.subscription?.data_packs || []);
const datapacksQuantity = computed(() =>
datapacks.value.map(d => d.quantity).reduce((a, b) => a + b, 0)
);
watch(
() => props.subscriptions,
() => {
subscription.value = props.subscriptions[0] || {};
datapacks.value = subscription.value.data_packs || [];
},
{ immediate: true }
);
return {
// References
datapacks,
datapacksQuantity,
heading,
image,
subscription,
totalQuantity
// Methods
formatBytes
};
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default {
default: null
}
},
emits: ["subscription-created"],
setup(props) {
const { loadCheckout } = usePaddle();
const { generatePlatformSubscriptionLink } = useSubscriptions();
Expand Down
6 changes: 4 additions & 2 deletions src/i18n/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@
"DatapackSubInfo": {
"title": "Actual subscription",
"datapacks": "Active DataPacks",
"storage": "Active storage"
"storage": "Active storage",
"including": "including {quantity} GB of DataPack"
},

"FileActionsCell": {
Expand Down Expand Up @@ -703,6 +704,7 @@
"groupDeleteError": "Fail to delete group",
"subscriptionsFetchError": "Fail to fetch subscriptions",
"platformSubscribeError": "Fail to initialize platform subscription",
"datapackSubscribeError": "Fail to create datapack subscription"
"datapackSubscribeError": "Fail to create datapack subscription",
"datapackUpdateError": "Fail to update datapack subscription"
}
}
8 changes: 5 additions & 3 deletions src/i18n/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,9 @@

"DatapackSubInfo": {
"title": "Abonnement actuel",
"datapacks": "Récapitulatif DataPack actif :",
"storage": "Récapitulatif GB actif :"
"datapacks": "Récapitulatif DataPack actif",
"storage": "Récapitulatif GB actif",
"including": "dont {quantity} GB de DataPack"
},

"FileActionsCell": {
Expand Down Expand Up @@ -708,6 +709,7 @@
"groupDeleteError": "Échec de la suppression du groupe",
"subscriptionsFetchError": "Impossible de récupérer la liste des souscriptions",
"platformSubscribeError": "Erreur lors de la création du lien de souscription",
"datapackSubscribeError": "Échec de la souscription à un nouveau datapack"
"datapackSubscribeError": "Échec de la souscription à un nouveau datapack",
"datapackUpdateError": "Erreur lors de la mise à jour du datapack"
}
}
4 changes: 1 addition & 3 deletions src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import modelViewerResolver from "./resolvers/views/model-viewer.js";
import projectBoardResolver from "./resolvers/views/project-board.js";
import projectGroupsResolver from "./resolvers/views/project-groups.js";
import spaceBoardResolver from "./resolvers/views/space-board.js";
import subscriptionDatapackResolver from "./resolvers/views/subscription-datapack.js";

// Route components
import Layout from "@/Layout.vue";
Expand Down Expand Up @@ -113,8 +112,7 @@ const routes = [
name: routeNames.subscriptionDatapack,
component: SubscriptionDatapack,
meta: {
guard: subscriptionDatapackGuard,
resolver: subscriptionDatapackResolver
guard: subscriptionDatapackGuard
}
},
{
Expand Down
8 changes: 0 additions & 8 deletions src/router/resolvers/views/subscription-datapack.js

This file was deleted.

3 changes: 2 additions & 1 deletion src/services/ErrorService.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ const ERRORS = Object.freeze({
GROUP_DELETE_ERROR: "groupDeleteError",
SUBSCRIPTIONS_FETCH_ERROR: "subscriptionsFetchError",
PLATFORM_SUBSCRIBE_ERROR: "platformSubscribeError",
DATAPACK_SUBSCRIBE_ERROR: "datapackSubscribeError"
DATAPACK_SUBSCRIBE_ERROR: "datapackSubscribeError",
DATAPACK_UPDATE_ERROR: "datapackUpdateError"
});

class RuntimeError {
Expand Down
16 changes: 15 additions & 1 deletion src/services/SubscriptionService.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,27 @@ class PaymentService {
async createDatapackSubscription(space, quantity) {
try {
return await privateApiClient.post(
`/payment/organization/${space.organization.id}/cloud/${space.id}/subscription/generate-platform-subscription`,
`/payment/organization/${space.organization.id}/cloud/${space.id}/subscription/create-platform-data-pack-subscription`,
{ quantity }
);
} catch (error) {
throw new RuntimeError(ERRORS.DATAPACK_SUBSCRIBE_ERROR, error);
}
}

async updateDatapackSubscription(space, datapack, quantity) {
try {
return await privateApiClient.patch(
`/payment/organization/${space.organization.id}/cloud/${space.id}/subscription/update-platform-data-pack-subscription`,
{
subscription_id: datapack.subscription_id,
quantity
}
);
} catch (error) {
throw new RuntimeError(ERRORS.DATAPACK_UPDATE_ERROR, error);
}
}
}

const service = new PaymentService();
Expand Down
9 changes: 8 additions & 1 deletion src/services/api-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,14 @@ const privateApiFetch = async ({ method = "GET", path, body, json = true }) => {
if (response.headers.get("Content-Type") === "application/json") {
errorDetails = await response.text();
}
throw new Error(`request error ${response.status}: ${errorDetails}`);
throw new Error(
`[Private API Client] Request error ${response.status}: ${errorDetails}`
);
}
if (response.status === 204) {
// Do not try to parse response body in case
// of HTTP status "204 No Content"
return;
}
return await response.json();
};
Expand Down
16 changes: 15 additions & 1 deletion src/state/subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const getSpaceSubscriptions = space => {
return readonly(state.spacesSubscriptions[space?.id] || []);
};

const getSpaceActiveSubscription = space => {
return getSpaceSubscriptions(space).find(sub => sub.status === "active");
};

const retrieveSubscriptionPayments = (orga, space, subscription) => {
return SubscriptionService.fetchSubscriptionPayments(
orga,
Expand All @@ -74,6 +78,14 @@ const createDatapackSubscription = (space, quantity) => {
return SubscriptionService.createDatapackSubscription(space, quantity);
};

const updateDatapackSubscription = (space, datapack, quantity) => {
return SubscriptionService.updateDatapackSubscription(
space,
datapack,
quantity
);
};

export function useSubscriptions() {
const readonlyState = readonly(state);
return {
Expand All @@ -86,9 +98,11 @@ export function useSubscriptions() {
retrieveSpaceSubscriptions,
retrieveAllSpacesSubscriptions,
getSpaceSubscriptions,
getSpaceActiveSubscription,
retrieveSubscriptionPayments,
retrieveSpaceInformation,
generatePlatformSubscriptionLink,
createDatapackSubscription
createDatapackSubscription,
updateDatapackSubscription
};
}
21 changes: 21 additions & 0 deletions src/views/subscription-datapack/SubscriptionDatapack.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.subscription-datapack {
position: relative;
height: 100%;

&__title {
Expand Down Expand Up @@ -47,4 +48,24 @@
}
}
}

&__loader {
--view-container-padding: var(--spacing-unit) * 7 / 2;

position: absolute;
z-index: 51; // This is to overlay view-header (which has z-index: 50)
top: calc(0px - var(--view-container-padding));
left: calc(0px - var(--view-container-padding));
width: calc(100% + var(--view-container-padding) * 2);
height: calc(100% + var(--view-container-padding) * 2);
background-color: rgba(255 255 255 / 0.6);

display: flex;
justify-content: center;
align-items: center;

.bimdata-spinner {
transform: scale(3);
}
}
}
Loading

0 comments on commit b7feb00

Please sign in to comment.