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

Implemented UI for the product store creation and management #3

Merged
merged 10 commits into from
May 22, 2024
Merged
65 changes: 65 additions & 0 deletions src/components/SelectOperatingCountriesModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<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("Select operating countries") }}</ion-title>
</ion-toolbar>
</ion-header>

<ion-content>
<ion-searchbar :placeholder="translate('Search country')" />

<ion-list>
<ion-item>
<ion-checkbox>
<ion-label>
<p class="overline">{{ "GEO ID" }}</p>
{{ "<countryName>" }}
</ion-label>
</ion-checkbox>
</ion-item>
<ion-item>
<ion-checkbox>
<ion-label>
<p class="overline">{{ "GEO ID" }}</p>
{{ "<countryName>" }}
</ion-label>
</ion-checkbox>
</ion-item>
<ion-item>
<ion-checkbox>
<ion-label>
<p class="overline">{{ "GEO ID" }}</p>
{{ "<countryName>" }}
</ion-label>
</ion-checkbox>
</ion-item>
</ion-list>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button>
<ion-icon :icon="checkmarkOutline" />
</ion-fab-button>
</ion-fab>
</ion-content>
</template>

<script setup lang="ts">
import { IonButton, IonButtons, IonCheckbox, IonContent, IonFab, IonFabButton, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonSearchbar, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { checkmarkOutline, closeOutline } from "ionicons/icons";
import { translate } from "@/i18n";

function closeModal() {
modalController.dismiss({ dismissed: true });
}
</script>

<style scoped>
ion-content {
--padding-bottom: 80px;
}
</style>
85 changes: 85 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,109 @@
{
"Add": "Add",
"Add configurations": "Add configurations",
"App": "App",
"Approval": "Approval",
"Approve on import": "Approve on import",
"Auto approve orders": "Auto approve orders",
"Auto cancellations days": "Auto cancellations days",
"Auto order cancellation": "Auto order cancellation",
"Brokering": "Brokering",
"Built:": "Built: {builtTime}",
"Cancel": "Cancel",
"Cancel order before fulfillment": "Cancel order before fulfillment",
"Cancellations": "Cancellations",
"Change": "Change",
"Choosing a product identifier allows you to view products with your preferred identifiers.": "Choosing a product identifier allows you to view products with your preferred identifiers.",
"Click the backdrop to dismiss.": "Click the backdrop to dismiss.",
"Company name": "Company name",
"Configurations": "Configurations",
"Configure cancellation threshold for unfulfilled orders based on a specified number of days.": "Configure cancellation threshold for unfulfilled orders based on a specified number of days.",
"Configure inventory computation for pre-sell items based on inventory channels and pre-sell queues.": "Configure inventory computation for pre-sell items based on inventory channels and pre-sell queues.",
"Configure when no further order information is needed prior to order approval.": "Configure when no further order information is needed prior to order approval.",
"Confirm": "Confirm",
"Control what your customers are allowed to edit on their own when they are editing their order on Re-route Fulfillment.": "Control what your customers are allowed to edit on their own when they are editing their order on Re-route Fulfillment.",
"Create a new product store": "Create a new product store",
"Create deadline days": "Create deadline days",
"Create new product store": "Create new product store",
"Create new tag": "Create new tag",
"Create product store": "Create product store",
"Delivery address": "Delivery address",
"Delivery method": "Delivery method",
"Display current physical quantity expected at locations while inventory counting.": "Display current physical quantity expected at locations while inventory counting.",
"Edit": "Edit",
"Fetching time zones": "Fetching time zones",
"Fulfillment": "Fulfillment",
"Global identifier": "Global identifier",
"Go to OMS": "Go to OMS",
"Hold pre-order physical inventory": "Hold pre-order physical inventory",
"ID": "ID",
"Id prefix": "Id prefix",
"Identifier": "Identifier",
"Import": "Import",
"Inventory": "Inventory",
"Inventory reservation": "Inventory reservation",
"Inventory view": "Inventory view",
"Login": "Login",
"Logging in...": "Logging in...",
"Logout": "Logout",
"Manage configurations": "Manage configurations",
"Minimum shipment threshold": "Minimum shipment threshold",
"Name": "Name",
"No product store found.": "No product store found.",
"No time zone found": "No time zone found",
"Notifications": "Nofifications",
"OMS": "OMS",
"OMS instance": "OMS instance",
"Operating countries": "Operating countries",
"Operating in": "Operating in",
"Order": "Order",
"Order brokering": "Order brokering",
"Order edit permissions": "Order edit permissions",
"Order splitting": "Order splitting",
"Orders tagged with this tag will undergo line item check for fulfillment facility selection.": "Orders tagged with this tag will undergo line item check for fulfillment facility selection.",
"Partial order rejection": "Partial order rejection",
"Password": "Password",
"Pick up location": "Pick up location",
"Pre-order computation": "Pre-order computation",
"Pre-order group": "Pre-order group",
"Preferred identifier": "Preferred identifier",
"Preselected facility tag": "Preselected facility tag",
"Primary identifier": "Primary identifier",
"Product": "Product",
"Product Identifier": "Product Identifier",
"Product store": "Product store",
"Product store name": "Product store name",
"Product store represents a brand in OMS": "Product store represents a brand in OMS",
"Returns": "Returns",
"Re-route fulfillment": "Re-route fulfillment",
"Routing": "Routing",
"Save billing information": "Save billing information",
"Search country": "Search country",
"Search time zones": "Search time zones",
"Seat Allocation": "Seat Allocation",
"Secondary identifier": "Secondary identifier",
"Select operating countries": "Select operating countries",
"Select time zone": "Select time zone",
"Send notification to Shopify": "Send notification to Shopify",
"Settings": "Settings",
"Setup product store": "Setup product store",
"Shipment method": "Shipment method",
"Shipping facility tag": "Shipping facility tag",
"Show systemic inventory": "Show systemic inventory",
"Specify any preferred prefix to be added to internal order IDs.": "Specify any preferred prefix to be added to internal order IDs.",
"Specify the number of days permitted for creating returns for in-store.": "Specify the number of days permitted for creating returns for in-store.",
"Specify whether you reject a BOPIS order partially when any order item inventory is insufficient at the store.": "Specify whether you reject a BOPIS order partially when any order item inventory is insufficient at the store.",
"Split orders into multiple groups and fulfill them from different fulfillment centers.": "Split orders into multiple groups and fulfill them from different fulfillment centers.",
"Store billing information associated with orders in OMS.": "Store billing information associated with orders in OMS.",
"Store pickup": "Store pickup",
"Tag will hold the preselected fulfillment facility value.": "Tag will hold the preselected fulfillment facility value.",
"The identifier used globally throughout the business operations.": "The identifier used globally throughout the business operations.",
"The name of the parent organization that owns all brands deployed on the OMS": "The name of the parent organization that owns all brands deployed on the OMS",
"The timezone you select is used to ensure automations you schedule are always accurate to the time you select.": "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.",
"This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.": "This is the name of the OMS you are connected to right now. Make sure that you are connected to the right instance before proceeding.",
"Time zone updated successfully": "Time zone updated successfully",
"Timezone": "Timezone",
"Update tracking information upon order shipment in Shopify.": "Update tracking information upon order shipment in Shopify.",
"Username": "Username",
"Version:": "Version: {appVersion}"
}
27 changes: 26 additions & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { RouteRecordRaw } from "vue-router";
import Login from "@/views/Login.vue"
import store from "@/store"
import Tabs from "@/views/Tabs.vue"
import CreateProductStore from "@/views/CreateProductStore.vue";
import AddConfigurations from "@/views/AddConfigurations.vue";
import ProductStoreDetails from "@/views/ProductStoreDetails.vue";

const authGuard = (to: any, from: any, next: any) => {
if (store.getters["user/isAuthenticated"]) {
Expand Down Expand Up @@ -31,15 +34,37 @@ const routes: Array<RouteRecordRaw> = [
children: [
{
path: "",
redirect: "/settings"
redirect: "/product-store"
},
{
path: "product-store",
name: "ProductStore",
component: () => import("@/views/ProductStore.vue")
},
{
path: "settings",
name: "Settings",
component: () => import("@/views/Settings.vue")
}
],
beforeEnter: authGuard
},
{
path: "/create-product-store",
name: "CreateProductStore",
component: CreateProductStore
},
{
path: "/add-configurations",
name: "AddConfigurations",
component: AddConfigurations
},
{
path: "/product-store-details/:productStoreId",
name: "ProductStoreDetails",
component: ProductStoreDetails,
props: true
},
{
path: "/login",
name: "Login",
Expand Down
5 changes: 5 additions & 0 deletions src/theme/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ http://ionicframework.com/docs/theming/ */
}
}

body {
/** Border variable **/
--border-medium: 1px solid var(--ion-color-medium);
}

.empty-state {
max-width: 100%;
display: flex;
Expand Down
73 changes: 73 additions & 0 deletions src/views/AddConfigurations.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-back-button default-href="/tabs/create-product-store" slot="start"></ion-back-button>
<ion-title>{{ translate("Add configurations") }}</ion-title>
<ion-buttons slot="end">
<ion-button slot="icon-only">
<ion-icon :icon="informationCircleOutline" />
</ion-button>
</ion-buttons>
<ion-progress-bar value="0.75" />
</ion-toolbar>
</ion-header>

<ion-content>
<main>
<h1 class="ion-margin-start">{{ translate('Configurations') }}</h1>

<ion-list>
<ion-list-header>
<ion-label>{{ translate("Product") }}</ion-label>
</ion-list-header>

<ion-item>
<ion-icon slot="start" :icon="shirtOutline"/>
<ion-select interface="popover" :label="translate('Product Identifier')" value="sku">
<ion-select-option value="sku">{{ "SKU" }}</ion-select-option>
</ion-select>
</ion-item>

<ion-list-header>
<ion-label>{{ translate("Order") }}</ion-label>
</ion-list-header>

<ion-item>
<ion-toggle>{{ translate("Auto approve orders") }}</ion-toggle>
</ion-item>
<ion-item lines="none">
<ion-input label-placement="floating" label="Sales order ID prefix" helper-text="Add a custom prefix to HotWax order IDs: <inputValue>10001" />
</ion-item>
</ion-list>

<ion-button class="ion-margin-top" @click="setupProductStore()">
{{ translate("Setup product store") }}
<ion-icon slot="end" :icon="arrowForwardOutline"/>
</ion-button>
</main>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import { IonBackButton, IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonList, IonListHeader, IonPage, IonProgressBar, IonSelect, IonSelectOption, IonTitle, IonToggle, IonToolbar } from "@ionic/vue";
import { arrowForwardOutline, informationCircleOutline, shirtOutline } from "ionicons/icons";
import { translate } from "@/i18n";
import { useRouter } from "vue-router";

const router = useRouter();

function setupProductStore() {
router.push("/product-store-details")
}
</script>

<style scoped>
@media (min-width: 700px) {
main {
max-width: 375px;
margin: auto;
}
}
</style>
80 changes: 80 additions & 0 deletions src/views/CreateProductStore.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-back-button default-href="/tabs/product-store" slot="start"></ion-back-button>
<ion-title>{{ translate("Create product store") }}</ion-title>
<ion-progress-bar value="0.25" />
</ion-toolbar>
</ion-header>

<ion-content>
<main>
<h1 class="ion-margin-start">{{ translate('Create a new product store') }}</h1>

<ion-item lines="none">
<ion-input label-placement="floating" :label="translate('Company name')" :helper-text="translate('The name of the parent organization that owns all brands deployed on the OMS')" :clear-input="true" />
</ion-item>
<ion-item lines="none">
<ion-input label-placement="floating" :label="translate('Name')" :helper-text="translate('Product store represents a brand in OMS')" :clear-input="true" />
</ion-item>
<ion-item lines="none">
<ion-input label-placement="floating" :label="translate('ID')" :helper-text="translate('Product store represents a brand in OMS')" :clear-input="true" />
</ion-item>

<ion-item>
<ion-icon slot="start" :icon="mapOutline"/>
<ion-label>{{ translate("Operating countries") }}</ion-label>
<ion-button fill="outline" slot="end" @click="openSelectOperatingCountriesModal()">{{ translate("Add") }}</ion-button>
</ion-item>

<ion-item lines="none">
<ion-chip outline>
{{ "<countryName>" }}
<ion-icon :icon="closeCircleOutline" />
</ion-chip>
<ion-chip outline>
{{ "<countryName>" }}
<ion-icon :icon="closeCircleOutline" />
</ion-chip>
</ion-item>

<ion-button class="ion-margin-top" @click="manageConfigurations()">
{{ translate("Manage configurations") }}
<ion-icon slot="end" :icon="arrowForwardOutline"/>
</ion-button>
</main>
</ion-content>
</ion-page>
</template>

<script setup lang="ts">
import { IonBackButton, IonButton, IonChip, IonContent, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonPage, IonProgressBar, IonTitle, IonToolbar, modalController } from "@ionic/vue";
import { arrowForwardOutline, closeCircleOutline, mapOutline } from "ionicons/icons";
import { translate } from "@/i18n";
import { useRouter } from "vue-router";
import SelectOperatingCountriesModal from "@/components/SelectOperatingCountriesModal.vue";

const router = useRouter();

function manageConfigurations() {
router.push("/add-configurations")
}

async function openSelectOperatingCountriesModal() {
const modal = await modalController.create({
component: SelectOperatingCountriesModal
})

modal.present()
}
</script>

<style scoped>
@media (min-width: 700px) {
main {
max-width: 375px;
margin: auto;
}
}
</style>
Loading
Loading