Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved: UI for order details page(#283) #325

Merged
merged 44 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
428740b
Implemented: Mobile-Responsive Order Detail Page UI with Order Items …
sanskar345 Sep 20, 2023
eb2a5fd
Implemented: Order Detail Page UI, inspired by Job Manager app (#283)
sanskar345 Sep 21, 2023
dda48c5
Implemented: alphabatical ordering of export components and imports a…
sanskar345 Sep 21, 2023
ba26058
Implemented: option in setting to allow partial order rejection and c…
sanskar345 Sep 26, 2023
8b79775
Implemented: order item rejection history modal and report an issue m…
sanskar345 Sep 27, 2023
21869d8
Fixed: error while refreshing order detail page (#283)
sanskar345 Sep 27, 2023
2c85db2
Implemented: comment the code to display text below the reject order …
sanskar345 Sep 27, 2023
68dfd0a
Implemented: logic for showing user the status of the current order i…
sanskar345 Sep 29, 2023
2d531d3
Implemented logic to reject single item in an order (#283)
sanskar345 Sep 29, 2023
72c3cf7
Improved: logic to reject single item in an order (#283)
sanskar345 Oct 3, 2023
df0ae34
Implemented: entries in locale files (#283)
sanskar345 Oct 3, 2023
4f59112
Improved: code by removing the unwanted lines (#283)
sanskar345 Oct 3, 2023
e997b7c
Implemented: logic to fetch orderItemHistory and reject reasons and c…
sanskar345 Oct 3, 2023
53d6883
Improved: order detail page UI using css grid, removed the the usage …
sanskar345 Oct 4, 2023
b5b2ca3
Implemented: entries in locale files for partial order rejection card…
sanskar345 Oct 4, 2023
4c3b8d1
Implemented: display order item rejection history (#283)
sanskar345 Oct 4, 2023
11273ca
Improved: order detail page css - placing the grid item (#283)
sanskar345 Oct 5, 2023
9826ba9
Implemented: logic to fetch products that exist in order item rejecti…
sanskar345 Oct 5, 2023
228e81e
Improved: reject order alert heading and button label (#283)
sanskar345 Oct 5, 2023
a19a276
Implemented: show alert before rejecting a single item (#283)
sanskar345 Oct 5, 2023
4b3e6e0
Improved: code and indentation (#283)
sanskar345 Oct 5, 2023
b81152c
Implemented: service to reject a single order item (#283)
sanskar345 Oct 6, 2023
3368b32
Improved: code and removed conditions that are unnecessary (#283)
sanskar345 Oct 6, 2023
4817eef
Improved: the placement of empty states css code in variables.css (#283)
sanskar345 Oct 9, 2023
2d32058
Merge branch 'main' of https://github.com/hotwax/bopis into bopis/#283
sanskar345 Oct 11, 2023
2f7a6cb
Implemented: do not dispatch stock/addProducts action while dispatchi…
sanskar345 Oct 11, 2023
a3f2c89
Implemented: modal to select reject reason before rejecting an order …
sanskar345 Oct 11, 2023
315ffe0
Updated: files to use the translate function
ymaheshwari1 Oct 17, 2023
346184c
Removed: import from i18n and used dxp component(#283)
ymaheshwari1 Oct 17, 2023
0279ea9
Improved: usage of translate function by removing this reference(#283)
ymaheshwari1 Oct 17, 2023
eea8a63
Removed: logic for partial order rejection setting as that config is …
ymaheshwari1 Oct 17, 2023
32be16e
Improved: logic to fetch rejection config inside viewEnter hook(#283)
ymaheshwari1 Oct 17, 2023
c01b227
Improved: code to handle the case when the api fails in fetching orde…
ymaheshwari1 Oct 17, 2023
f11c1fb
Improved: copy button to determine it as clickable(#283)
ymaheshwari1 Oct 18, 2023
d60b33e
Improved: logic to reject single order item(#283)
ymaheshwari1 Oct 18, 2023
96d4dc5
Improved: variable name for rejection method and added logic to clear…
ymaheshwari1 Oct 18, 2023
b98e9ba
Fixed: issue when changing the order part id in url(#283)
ymaheshwari1 Oct 18, 2023
ca0fea2
Improved: variable names on the order rejection history modal(#283)
ymaheshwari1 Oct 18, 2023
a7a1b44
Merge main into bopis/#283
ymaheshwari1 Oct 31, 2023
21a5fe7
Improved: code to remove the unwanted variable(#283)
ymaheshwari1 Oct 31, 2023
439b585
Fixed: undefined case when open list does not have any orders but pac…
ymaheshwari1 Oct 31, 2023
5d455dc
Added: support to display empty state when all the order items are re…
ymaheshwari1 Nov 1, 2023
3d56f4f
Implemented: support to display payment status for the order on the d…
ymaheshwari1 Nov 1, 2023
91cee93
Fixed: logic to clear orders on logout, disabled reject item button o…
ymaheshwari1 Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/NotificationPreferenceModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,16 @@ export default defineComponent({
)
},
async confirmSave() {
const message = this.translate("Are you sure you want to update the notification preferences?");
const message = translate("Are you sure you want to update the notification preferences?");
const alert = await alertController.create({
header: this.translate("Update notification preferences"),
header: translate("Update notification preferences"),
message,
buttons: [
{
text: this.translate("Cancel"),
text: translate("Cancel"),
},
{
text: this.translate("Confirm"),
text: translate("Confirm"),
handler: async () => {
await this.updateNotificationPref();
modalController.dismiss({ dismissed: true });
Expand Down
113 changes: 113 additions & 0 deletions src/components/OrderItemRejHistoryModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="closeOutline" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Order item rejection history") }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item v-for="(item, index) in orderRejectionHistory" :key="index">
<ion-thumbnail slot="start">
<ShopifyImg :src="getProduct(item.productId).mainImageUrl" size="small" />
</ion-thumbnail>
<ion-label>
<h5>{{ getProduct(item.productId).brandName }}</h5>
<h2>{{ getProduct(item.productId).productName }}</h2>
<p v-if="$filters.getFeature(getProduct(item.productId).featureHierarchy, '1/COLOR/')">{{ translate("Color") }}: {{ $filters.getFeature(getProduct(item.productId).featureHierarchy, '1/COLOR/') }}</p>
<p v-if="$filters.getFeature(getProduct(item.productId).featureHierarchy, '1/SIZE/')">{{ translate("Size") }}: {{ $filters.getFeature(getProduct(item.productId).featureHierarchy, '1/SIZE/') }}</p>
</ion-label>
<ion-label slot="end" class="ion-text-right">
<h2>{{ getRejectReasonDescription(item.changeReasonEnumId) }}</h2>
<p>{{ item.changeUserLogin }}</p>
<p>{{ getTime(item.changeDatetime) }}</p>
</ion-label>
</ion-item>
</ion-list>

<!-- Empty state -->
<div v-if="!orderRejectionHistory.length && !isLoading" class="empty-state">
<p>{{ translate('No records found.') }}</p>
</div>
</ion-content>
</template>

<script lang="ts">
import {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonThumbnail,
IonLabel,
IonList,
IonTitle,
IonToolbar,
modalController
} from '@ionic/vue';
import { defineComponent } from 'vue';
import { closeOutline } from 'ionicons/icons';
import { mapGetters, useStore } from "vuex";
import { DateTime } from 'luxon';
import { translate } from '@hotwax/dxp-components';

export default defineComponent({
name: "OrderItemRejHistoryModal",
components: {
IonButton,
IonButtons,
IonContent,
IonHeader,
IonIcon,
IonItem,
IonThumbnail,
IonLabel,
IonList,
IonTitle,
IonToolbar,
},
data () {
return {
isLoading: true
}
},
computed: {
...mapGetters({
getProduct: 'product/getProduct',
order: "order/getCurrent",
rejectReasons: 'util/getRejectReasons',
orderRejectionHistory: 'order/getOrderItemRejectionHistory'
})
},
async mounted() {
await this.store.dispatch('order/getOrderItemRejectionHistory', { orderId: this.order.orderId, rejectReasonEnumIds: this.rejectReasons.reduce((enumIds: [], reason: any) => [...enumIds, reason.enumId], []) });
this.isLoading = false;
},
methods: {
closeModal() {
modalController.dismiss({ dismissed: true });
},
getRejectReasonDescription(rejectReasonEnumId: string) {
return this.rejectReasons.find((reason: any) => reason.enumId === rejectReasonEnumId)?.description;
},
getTime(time: number) {
return time ? DateTime.fromMillis(time).toLocaleString(DateTime.DATETIME_MED) : ''
}
},
setup() {
const store = useStore();

return {
closeOutline,
store,
translate
};
},
});
</script>
15 changes: 5 additions & 10 deletions src/components/ProductListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</ion-label>
<!-- Only show stock if its not a ship to store order -->
<div v-if="!isShipToStoreOrder">
<ion-note v-if="getProductStock(item.productId).quantityOnHandTotal >= 0">
<ion-note v-if="getProductStock(item.productId).quantityOnHandTotal >= 0" :color="updateColor(getProductStock(item.productId).quantityOnHandTotal)">
{{ getProductStock(item.productId).quantityOnHandTotal }} {{ translate('pieces in stock') }}
</ion-note>
<ion-spinner v-else-if="isFetchingStock" color="medium" name="crescent" />
Expand All @@ -26,15 +26,7 @@

<script lang="ts">
import { defineComponent } from "vue";
import {
IonButton,
IonIcon,
IonItem,
IonLabel,
IonNote,
IonSpinner,
IonThumbnail
} from "@ionic/vue";
import { IonButton, IonIcon, IonItem, IonLabel, IonNote, IonSpinner, IonThumbnail } from "@ionic/vue";
import { mapGetters, useStore } from 'vuex';
import { ShopifyImg, translate } from '@hotwax/dxp-components'
import { cubeOutline } from 'ionicons/icons'
Expand Down Expand Up @@ -75,6 +67,9 @@ export default defineComponent({
this.isFetchingStock = true
await this.store.dispatch('stock/fetchStock', { productId })
this.isFetchingStock = false
},
updateColor(stock: number) {
return stock ? stock < 10 ? 'warning' : 'success' : 'danger';
}
},
setup() {
Expand Down
129 changes: 129 additions & 0 deletions src/components/RejectOrderModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="closeOutline" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Reject Order") }}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-item lines="none">
<p>{{ translate('On rejecting this order, will be sent an email with alternate fulfilment options and this order will be removed from your dashboard.', { customerName: order?.customer?.name }) }}</p>
</ion-item>
<ion-list>
<ion-list-header>{{ translate("Select reason") }}</ion-list-header>
<ion-radio-group v-model="rejectReasonId">
<ion-item v-for="reason in unfillableReasons" :key="reason.id">
<ion-radio slot="start" :value="reason.id" />
<ion-label>{{ translate(reason.label) }}</ion-label>
</ion-item>
</ion-radio-group>
</ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button :disabled="!rejectReasonId" @click="confirmSave()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
</ion-content>
</template>

<script lang="ts">
import {
IonButton,
IonButtons,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonTitle,
IonToolbar,
IonRadio,
IonRadioGroup,
alertController,
modalController,
} from '@ionic/vue';
import { defineComponent } from 'vue';
import { closeOutline, saveOutline } from 'ionicons/icons';
import { mapGetters, useStore } from 'vuex'
import { translate } from '@hotwax/dxp-components';

export default defineComponent({
name: "RejectOrderModal",
components: {
IonButton,
IonButtons,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonListHeader,
IonTitle,
IonToolbar,
IonRadio,
IonRadioGroup
},
data() {
return {
unfillableReasons: JSON.parse(process.env.VUE_APP_UNFILLABLE_REASONS),
rejectReasonId: ''
}
},
computed: {
...mapGetters({
order: "order/getCurrent",
getProduct: 'product/getProduct',
})
},
methods: {
closeModal() {
modalController.dismiss({ dismissed: true });
},
async confirmSave() {
const alert = await alertController
.create({
header: translate('Reject Order'),
message: translate(`This order will be removed from your dashboard. This action cannot be undone.`, { space: '<br /><br />' }),
buttons: [{
text: translate('Cancel'),
role: 'cancel'
}, {
text: translate('Reject'),
handler: () => {
const part = { ...this.order.part, items: this.order.part.items.map((item: any) => ({ ...item, reason: this.rejectReasonId })) };
this.store.dispatch('order/setUnfillableOrderOrItem', { orderId: this.order.orderId, part }).then((resp) => {
if (resp) {
// Mark current order as rejected
this.store.dispatch('order/updateCurrent', { order: { ...this.order, rejected: true } })
}
this.closeModal();
})
},
}]
});
return alert.present();
}
},
setup() {
const store = useStore();

return {
closeOutline,
saveOutline,
store,
translate
};
}
});
</script>
Loading
Loading