first commit
This commit is contained in:
16
src/App.vue
Normal file
16
src/App.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<html class="opensans">
|
||||
<router-view />
|
||||
<notifications position="top center" />
|
||||
</html>
|
||||
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
BIN
src/assets/images/user_placeholder.png
Normal file
BIN
src/assets/images/user_placeholder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
16
src/assets/main.css
Normal file
16
src/assets/main.css
Normal file
@@ -0,0 +1,16 @@
|
||||
select {
|
||||
-webkit-appearance: listbox !important
|
||||
}
|
||||
input[type=file]::-webkit-file-upload-button,
|
||||
input[type=file]::file-selector-button {
|
||||
/*@apply text-white bg-gray-700 hover:bg-gray-600 rounded-md font-bold text-sm cursor-pointer border-0 py-2.5 pl-4 pr-4;*/
|
||||
}
|
||||
.wrapper {
|
||||
min-height: calc(100vh - 558px);
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.WrapperPlain {
|
||||
min-height: calc(100vh - 75px);
|
||||
margin-top: 20px;
|
||||
}
|
||||
1
src/assets/stripejs.js
Normal file
1
src/assets/stripejs.js
Normal file
File diff suppressed because one or more lines are too long
5
src/assets/tailwind.css
Normal file
5
src/assets/tailwind.css
Normal file
@@ -0,0 +1,5 @@
|
||||
@tailwind base;
|
||||
|
||||
@tailwind components;
|
||||
|
||||
@tailwind utilities;
|
||||
1
src/assets/vue.svg
Normal file
1
src/assets/vue.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
34
src/components/pagination.vue
Normal file
34
src/components/pagination.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
|
||||
<div class="col-span-12 btn-group flex justify-center">
|
||||
|
||||
<ul v-show="props.showPagination" :class="props.theme.list">
|
||||
|
||||
|
||||
<button class="btn" @click="props.setPrevPage">
|
||||
<a v-bind="{...props.aProps,...props.prevProps}">{{props.texts.prevPage}}</a>
|
||||
</button>
|
||||
|
||||
<button v-for="page in props.pages" :key="page" class="btn"
|
||||
v-on="props.pageEvents(page)">
|
||||
<a v-bind="props.aProps" :class="props.theme.link">{{page}}</a>
|
||||
</button>
|
||||
|
||||
<button class="btn" @click="props.setNextPage">
|
||||
<a v-bind="{...props.aProps, ...props.nextProps}">{{props.texts.nextPage}}</a>
|
||||
</button>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-span-12 flex justify-center">
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'pagination',
|
||||
props: ['props']
|
||||
}
|
||||
</script>
|
||||
8
src/decs.d.ts
vendored
Normal file
8
src/decs.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare module "axios";
|
||||
declare module "@kyvg/vue3-notification";
|
||||
declare module "v-pagination-3";
|
||||
declare module "vue-router";
|
||||
declare module "@vuelidate/core";
|
||||
declare module "@vuelidate/validators";
|
||||
declare module "pinia";
|
||||
declare module "@vueuse/core";
|
||||
4
src/index.css
Normal file
4
src/index.css
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
3
src/input.css
Normal file
3
src/input.css
Normal file
@@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
46
src/layouts/footers/footer.vue
Normal file
46
src/layouts/footers/footer.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
<template>
|
||||
<footer class="footer p-10 bg-neutral text-neutral-content mt-20">
|
||||
<nav>
|
||||
<h6 class="footer-title">Services</h6>
|
||||
<a class="link link-hover">Branding</a>
|
||||
<a class="link link-hover">Design</a>
|
||||
<a class="link link-hover">Marketing</a>
|
||||
<a class="link link-hover">Advertisement</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Company</h6>
|
||||
<a class="link link-hover">About us</a>
|
||||
<a class="link link-hover">Contact</a>
|
||||
<a class="link link-hover">Jobs</a>
|
||||
<a class="link link-hover">Press kit</a>
|
||||
</nav>
|
||||
<nav>
|
||||
<h6 class="footer-title">Legal</h6>
|
||||
<a class="link link-hover">Terms of use</a>
|
||||
<a class="link link-hover">Privacy policy</a>
|
||||
<a class="link link-hover">Cookie policy</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Footer',
|
||||
data() {
|
||||
return {
|
||||
user: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {},
|
||||
methods: {},
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
33
src/layouts/headers/SearchResults.vue
Normal file
33
src/layouts/headers/SearchResults.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<section>
|
||||
|
||||
<div v-for="user in customers" :key="user.id">
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: user['id'] } }">
|
||||
<div class="grid grid-cols-12 bg-neutral pb-5 hover:bg-accent">
|
||||
<div class="col-span-12"> {{ user['customer_first_name'] }} {{ user['customer_last_name'] }}</div>
|
||||
<div class="col-span-12">
|
||||
{{ user['customer_address'] }} {{ user['customer_town'] }} {{user.state}}
|
||||
</div>
|
||||
<div class="col-span-12"> {{user['customer_phone_number']}}</div>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
|
||||
import {defineComponent} from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SearchResults",
|
||||
props: ["customers"],
|
||||
|
||||
});
|
||||
</script>
|
||||
191
src/layouts/headers/headerauth.vue
Normal file
191
src/layouts/headers/headerauth.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
|
||||
<div class="navbar bg-base-100">
|
||||
<div class="basis-1/4 md:basis-1/4">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Auburn Oil
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="basis-1/4 md:basis-1/2 justify-center text-center">
|
||||
<input type="text" placeholder="Search " class="input input-bordered w-24 md:w-auto grow" v-model="searchTerm"/>
|
||||
</div>
|
||||
|
||||
<div class="basis-1/2 md:basis-1/4 justify-end gap-5">
|
||||
<router-link :to="{ name: 'customerCreate' }">
|
||||
<button class="btn">Create Customer</button>
|
||||
</router-link>
|
||||
|
||||
<div v-if="employee.id">
|
||||
<router-link :to="{ name: 'employeeProfile', params: { id: employee.id } }">
|
||||
<button class="btn">{{ user.user_name }}</button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="grid grid-cols-12 ">
|
||||
<div class="grow col-start-4 col-span-6 ">
|
||||
<SearchResults v-if="customers.length" :customers="customers"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {debounce} from "vue-debounce";
|
||||
import {defineComponent} from "vue";
|
||||
import axios from "axios";
|
||||
import authHeader from "../../services/auth.header";
|
||||
import SearchResults from "./SearchResults.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "HeaderAuth",
|
||||
components: {
|
||||
SearchResults,
|
||||
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus();
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
user: {
|
||||
user_id: 0,
|
||||
user_name: '',
|
||||
},
|
||||
employee: {
|
||||
id: '',
|
||||
user_id: '',
|
||||
employee_last_name: "",
|
||||
employee_first_name: "",
|
||||
employee_town: "",
|
||||
employee_address: "",
|
||||
employee_apt: "",
|
||||
employee_zip: "",
|
||||
employee_birthday: "",
|
||||
employee_phone_number: "",
|
||||
employee_start_date: "",
|
||||
employee_end_date: "",
|
||||
employee_type: '',
|
||||
employee_state: '',
|
||||
},
|
||||
loaded: false,
|
||||
searchTerm: '',
|
||||
customers: [],
|
||||
type_of_search: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
searchTerm() {
|
||||
this.performSearch();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
performSearch: debounce(async function () {
|
||||
console.log(this.searchTerm)
|
||||
if (this.searchTerm === "") {
|
||||
this.customers = [];
|
||||
return;
|
||||
}
|
||||
if (this.searchTerm.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.searchTerm.startsWith("@")) {
|
||||
this.type_of_search = 0
|
||||
} else if (this.searchTerm.startsWith("!")) {
|
||||
this.type_of_search = 1
|
||||
} else if (this.searchTerm.startsWith("#")) {
|
||||
this.type_of_search = 2
|
||||
} else {
|
||||
this.type_of_search = 2
|
||||
}
|
||||
|
||||
const searchUrl = this.getSearchUrl();
|
||||
const response = await (await fetch(searchUrl)).json();
|
||||
|
||||
this.customers = response;
|
||||
}, 600),
|
||||
getSearchUrl() {
|
||||
if (this.type_of_search == 0) {
|
||||
const url = "http://127.0.0.1:4056/search/customer";
|
||||
const params = {
|
||||
q: this.searchTerm,
|
||||
};
|
||||
const searchParams = new URLSearchParams(params);
|
||||
return `${url}?${searchParams}`;
|
||||
}
|
||||
else if (this.type_of_search == 1) {
|
||||
const url = "http://127.0.0.1:4056/search/customer";
|
||||
const params = {
|
||||
q: this.searchTerm,
|
||||
};
|
||||
const searchParams = new URLSearchParams(params);
|
||||
return `${url}?${searchParams}`;
|
||||
}
|
||||
else if (this.type_of_search == 2) {
|
||||
const url = "http://127.0.0.1:4056/search/customer";
|
||||
const params = {
|
||||
q: this.searchTerm,
|
||||
};
|
||||
const searchParams = new URLSearchParams(params);
|
||||
return `${url}?${searchParams}`;
|
||||
}
|
||||
else {
|
||||
const url = "http://127.0.0.1:4056/search/customer";
|
||||
const params = {
|
||||
q: this.searchTerm,
|
||||
};
|
||||
const searchParams = new URLSearchParams(params);
|
||||
return `${url}?${searchParams}`;
|
||||
}
|
||||
},
|
||||
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.employeeStatus()
|
||||
this.loaded = true;
|
||||
} else {
|
||||
localStorage.removeItem('user');
|
||||
this.$router.push('/login');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loaded = true;
|
||||
this.$router.push('/login');
|
||||
});
|
||||
},
|
||||
employeeStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/employee/userid/' + this.user.user_id;
|
||||
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.employee = response.data;
|
||||
this.loaded = true;
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
56
src/layouts/headers/headernoauth.vue
Normal file
56
src/layouts/headers/headernoauth.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
|
||||
<div class="navbar bg-base-100">
|
||||
<div class="basis-1/4 md:basis-1/4">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Auburn Oil
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="basis-1/4 md:basis-1/2 justify-center text-center">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="basis-1/2 md:basis-1/4 justify-end gap-5">
|
||||
<router-link :to="{ name: 'login' }">
|
||||
<button class="btn">Login</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'register' }">
|
||||
<button class="btn">Register</button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: "HeaderNoAuth",
|
||||
mounted () {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
user: null,
|
||||
loaded: false,
|
||||
clicked: false,
|
||||
hovered: false,
|
||||
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
67
src/layouts/headers/search.vue
Normal file
67
src/layouts/headers/search.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
|
||||
<div class="navbar bg-base-100">
|
||||
<div class="basis-1/4 md:basis-1/4">
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Auburn Oil
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="basis-1/4 md:basis-1/2 justify-center text-center">
|
||||
<input type="search" placeholder="Search " class="input input-bordered w-24 md:w-auto" v-model="searchTerm"/>
|
||||
</div>
|
||||
<SearchResults v-if="customers.length" :customers="customers" />
|
||||
<div class="basis-1/2 md:basis-1/4 justify-end gap-5">
|
||||
<router-link :to="{ name: 'customerCreate' }">
|
||||
<button class="btn">Create Customer</button>
|
||||
</router-link>
|
||||
|
||||
<!-- <div v-if="employee.id">-->
|
||||
<!-- <router-link :to="{ name: 'employeeProfile', params: { id: employee.id } }">-->
|
||||
<!-- <button class="btn">{{ user.user_name }}</button>-->
|
||||
<!-- </router-link>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { debounce } from "vue-debounce";
|
||||
import SearchResults from "./SearchResults.vue";
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
const searchTerm = ref("");
|
||||
const customers = ref([]);
|
||||
|
||||
const getSearchUrl = () => {
|
||||
const url = "https://dummyjson.com/products/search";
|
||||
const params = {
|
||||
q: searchTerm.value,
|
||||
limit: "5",
|
||||
};
|
||||
const searchParams = new URLSearchParams(params);
|
||||
return `${url}?${searchParams}`;
|
||||
};
|
||||
|
||||
const performSearch = debounce(async () => {
|
||||
console.log("searching")
|
||||
if (searchTerm.value === "") {
|
||||
customers.value = [];
|
||||
return;
|
||||
}
|
||||
if (searchTerm.value.length < 2) {
|
||||
return;
|
||||
}
|
||||
const searchUrl = getSearchUrl();
|
||||
const response = await (await fetch(searchUrl)).json();
|
||||
|
||||
customers.value = response.products;
|
||||
}, 600);
|
||||
|
||||
watch(searchTerm, () => {
|
||||
performSearch();
|
||||
});
|
||||
</script>
|
||||
107
src/layouts/sidebar/sidebar.vue
Normal file
107
src/layouts/sidebar/sidebar.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
|
||||
<div class="drawer sm:drawer-open">
|
||||
<input id="my-drawer-2" type="checkbox" class="drawer-toggle"/>
|
||||
<div class="drawer-content flex flex-col items-center justify-center ">
|
||||
</div>
|
||||
|
||||
<div class="drawer-side">
|
||||
<label for="my-drawer-2" aria-label="close sidebar" class="drawer-overlay"></label>
|
||||
|
||||
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
|
||||
|
||||
<!-- Sidebar content here -->
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<div class=" hover:underline py-1 px-5 font-bold">Home</div>
|
||||
</router-link>
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Customer</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
<div class=" hover:underline py-1">All Customers</div>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'customerCreate' }">
|
||||
<div class=" hover:underline py-1">Create Customer</div>
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Delivery</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'delivery' }">
|
||||
<div class=" hover:underline py-1">Waiting Deliveries</div>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'delivery' }">
|
||||
<div class=" hover:underline py-1">Out for Delivery</div>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryTicketsMissing' }">
|
||||
<div class=" hover:underline py-1">Delivered Tickets</div>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryTicketsMissing' }">
|
||||
<div class=" hover:underline py-1">Finalized Tickets</div>
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Service</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'service' }">
|
||||
<div class=" hover:underline py-1">Service</div>
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Automatics</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'auto' }">
|
||||
<div class=" hover:underline py-1">Automatics</div>
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Employees</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'employee' }">
|
||||
<div class=" hover:underline py-1">Employees</div>
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
|
||||
<div class="font-bold text-lg text-gray-500 pt-5">Admin</div>
|
||||
<li>
|
||||
<router-link :to="{ name: 'oilprice' }">
|
||||
<div class=" hover:underline py-1">Oil Pricing</div>
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'serviceprice' }">
|
||||
<div class=" hover:underline py-1">Service Pricing</div>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import {defineComponent} from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "SideBar",
|
||||
mounted() {
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
|
||||
methods: {},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
14
src/main.ts
Normal file
14
src/main.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createApp } from 'vue';
|
||||
import './assets/tailwind.css'
|
||||
import './assets/main.css'
|
||||
import App from './App.vue';
|
||||
import router from './router';
|
||||
import Notifications from '@kyvg/vue3-notification';
|
||||
import Pagination from 'v-pagination-3';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(createPinia());
|
||||
app.use(router)
|
||||
.component('pagination', Pagination);
|
||||
app.use(Notifications).mount('#app')
|
||||
222
src/pages/Index.vue
Normal file
222
src/pages/Index.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex text-2xl mb-5">
|
||||
Welcome {{ employee.employee_first_name }} {{ employee.employee_last_name }}!
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-12 gap-5">
|
||||
<div class="col-span-12 bg-neutral ">
|
||||
<div class="grid grid-cols-12 p-5">
|
||||
<div class="col-span-12 font-bold text-xl">Todays stats</div>
|
||||
<div class="col-span-6 py-2"> Total Deliveries: {{delivery_count}}</div>
|
||||
<div class="col-span-6 py-2"> Total Service Calls: {{service_count}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 bg-neutral" >
|
||||
<div class="grid grid-cols-12 p-5 ">
|
||||
<div class="col-span-12 font-bold text-xl">Todays Oil Price</div>
|
||||
<div class="col-span-12 py-2"> Price / Gallon: {{today_oil_price}}</div>
|
||||
<div class="col-span-12 py-2"> Same Day: ${{same_day}}</div>
|
||||
<div class="col-span-12 py-2"> Prime: ${{prime}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 bg-neutral" >
|
||||
<div class="grid grid-cols-12 p-5 ">
|
||||
<div class="col-span-12 font-bold text-xl">Todays Service Price</div>
|
||||
<div class="col-span-12 py-2"> Price / hour: ${{price_hourly}}</div>
|
||||
<div class="col-span-12 py-2"> Emergency Fee: ${{emergency_fee}}</div>
|
||||
<div class="col-span-12 py-2"> Emergency Price / hour: ${{emergency_rate}}</div>
|
||||
|
||||
<div class="col-span-12 py-2"> Cleaning ${{cleaning}}</div>
|
||||
<div class="col-span-12 py-2"> Out of Oil: ${{out_of_oil}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../services/auth.header'
|
||||
import Header from '../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../layouts/footers/footer.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Home',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
delivery_count: 0,
|
||||
service_count: 0,
|
||||
today_oil_price: '',
|
||||
|
||||
same_day: '',
|
||||
price_hourly: '',
|
||||
emergency_fee: '',
|
||||
emergency_rate: '',
|
||||
prime: '',
|
||||
cleaning: '',
|
||||
out_of_oil: '',
|
||||
|
||||
user: {
|
||||
user_id: 0,
|
||||
user_name: '',
|
||||
},
|
||||
employee: {
|
||||
id: '',
|
||||
user_id: '',
|
||||
employee_last_name: "",
|
||||
employee_first_name: "",
|
||||
employee_town: "",
|
||||
employee_address: "",
|
||||
employee_apt: "",
|
||||
employee_zip: "",
|
||||
employee_birthday: "",
|
||||
employee_phone_number: "",
|
||||
employee_start_date: "",
|
||||
employee_end_date: "",
|
||||
employee_type: '',
|
||||
employee_state: '',
|
||||
},
|
||||
loaded: false,
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.today_delivery_count()
|
||||
this.today_service_count()
|
||||
this.today_price_oil()
|
||||
this.today_price_service()
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.employeeStatus()
|
||||
} else {
|
||||
|
||||
localStorage.removeItem('user');
|
||||
this.$router.push('/login');
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
employeeStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/employee/userid/' + this.user.user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.employee = response.data;
|
||||
this.loaded = true;
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
today_delivery_count() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/stats/delivery/count/today'
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.delivery_count = response.data.data;
|
||||
})
|
||||
},
|
||||
today_service_count() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/stats/service/count/today'
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.service_count = response.data.data;
|
||||
})
|
||||
},
|
||||
today_price_oil() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/info/price/oil'
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.today_oil_price = response.data.price;
|
||||
})
|
||||
},
|
||||
today_price_service() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/info/price/service'
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.same_day = response.data.same_day;
|
||||
this.price_hourly = response.data.price_hourly;
|
||||
this.emergency_fee = response.data.emergency_fee;
|
||||
this.emergency_rate = response.data.emergency_rate;
|
||||
this.prime = response.data.prime;
|
||||
this.cleaning = response.data.cleaning;
|
||||
this.out_of_oil = response.data.out_of_oil;
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
186
src/pages/admin/oilprice.vue
Normal file
186
src/pages/admin/oilprice.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">
|
||||
Add oil Price
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Price Customer</label>
|
||||
<input v-model="CreateOilForm.basicInfo.price_for_customer"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Todays Price"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Price Employee</label>
|
||||
<input v-model="CreateOilForm.basicInfo.price_for_employee"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Todays Price Employee"/>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2"> Price from Supplier</label>
|
||||
<input v-model="CreateOilForm.basicInfo.price_from_supplier"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="prime" type="text" placeholder="Price Prime"/>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Create Price
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ServicePrice',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
CreateOilForm: {
|
||||
basicInfo: {
|
||||
price_from_supplier: '',
|
||||
price_for_customer: '',
|
||||
price_for_employee: '',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCurrentPrices()
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCurrentPrices() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/admin/oil/get";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
|
||||
this.CreateOilForm.basicInfo.price_from_supplier = response.data.price_from_supplier;
|
||||
this.CreateOilForm.basicInfo.price_for_customer = response.data.price_for_customer;
|
||||
this.CreateOilForm.basicInfo.price_for_employee = response.data.price_for_employee;
|
||||
}
|
||||
})
|
||||
},
|
||||
CreatePricing(payload: {
|
||||
price_from_supplier: string;
|
||||
price_for_customer: string;
|
||||
price_for_employee: string;
|
||||
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/admin/oil/create";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "update",
|
||||
text: "Prices have been updated!",
|
||||
type: "success",
|
||||
});
|
||||
this.$router.push({name: "oilprice"});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
price_from_supplier: this.CreateOilForm.basicInfo.price_from_supplier,
|
||||
price_for_customer: this.CreateOilForm.basicInfo.price_for_customer,
|
||||
price_for_employee: this.CreateOilForm.basicInfo.price_for_employee,
|
||||
};
|
||||
this.CreatePricing(payload);
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
21
src/pages/admin/routes.ts
Normal file
21
src/pages/admin/routes.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
import OilPrice from '../admin/oilprice.vue';
|
||||
import ServicePrice from "./serviceprice.vue";
|
||||
|
||||
const adminRoutes = [
|
||||
{
|
||||
path: '/oilprice',
|
||||
name: 'oilprice',
|
||||
component: OilPrice,
|
||||
},
|
||||
{
|
||||
path: '/serviceprice',
|
||||
name: 'serviceprice',
|
||||
component: ServicePrice,
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
export default adminRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
217
src/pages/admin/serviceprice.vue
Normal file
217
src/pages/admin/serviceprice.vue
Normal file
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">
|
||||
Change Pricing
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Hourly Service Rate</label>
|
||||
<input v-model="CreateServiceForm.basicInfo.price_service_hour"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Hourly Rate"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Hourly Emergency Service Rate</label>
|
||||
<input v-model="CreateServiceForm.basicInfo.price_emergency_service_hour"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Emergency Rate"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Emergency Fee </label>
|
||||
<input v-model="CreateServiceForm.basicInfo.price_emergency_call"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="After hour/ same day Fee"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Out of Oil Price</label>
|
||||
<input v-model="CreateServiceForm.basicInfo.price_emergency_call"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Out of oil price"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Prime Price</label>
|
||||
<input v-model="CreateServiceForm.basicInfo.price_prime"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="prime" type="text" placeholder="Price Prime"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Create Price
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ServicePrice',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
|
||||
CreateServiceForm: {
|
||||
basicInfo: {
|
||||
price_service_hour: '',
|
||||
price_emergency_service_hour: '',
|
||||
price_emergency_call: '',
|
||||
price_out_of_oil: '',
|
||||
price_prime: '',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCurrentPrices()
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCurrentPrices() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/admin/service/get";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.CreateServiceForm.basicInfo.price_service_hour = response.data.price_service_hour;
|
||||
this.CreateServiceForm.basicInfo.price_emergency_service_hour = response.data.price_emergency_service_hour;
|
||||
this.CreateServiceForm.basicInfo.price_emergency_call = response.data.price_emergency_call;
|
||||
this.CreateServiceForm.basicInfo.price_out_of_oil = response.data.price_out_of_oil;
|
||||
this.CreateServiceForm.basicInfo.price_prime = response.data.price_prime;
|
||||
}
|
||||
})
|
||||
},
|
||||
CreatePricing(payload: {
|
||||
price_service_hour: string;
|
||||
price_emergency_service_hour: string;
|
||||
price_emergency_call: string;
|
||||
price_out_of_oil: string;
|
||||
price_prime: string;
|
||||
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/admin/service/create";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
|
||||
notify({
|
||||
title: "update",
|
||||
text: "Prices have been updated!",
|
||||
type: "success",
|
||||
});
|
||||
this.$router.push({name: "serviceprice"});
|
||||
}
|
||||
if (response.data.error) {
|
||||
notify({
|
||||
title: "update",
|
||||
text: "error updating prices :(",
|
||||
type: "success",
|
||||
});
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
price_service_hour: this.CreateServiceForm.basicInfo.price_service_hour,
|
||||
price_emergency_service_hour: this.CreateServiceForm.basicInfo.price_emergency_service_hour,
|
||||
price_emergency_call: this.CreateServiceForm.basicInfo.price_emergency_call,
|
||||
price_out_of_oil: this.CreateServiceForm.basicInfo.price_out_of_oil,
|
||||
price_prime: this.CreateServiceForm.basicInfo.price_prime,
|
||||
};
|
||||
this.CreatePricing(payload);
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
166
src/pages/auth/changepassword.vue
Normal file
166
src/pages/auth/changepassword.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
|
||||
<template>
|
||||
<Header />
|
||||
<div class="WrapperPlain">
|
||||
<div class="container max-w-3xl mx-auto text-white">
|
||||
<div class="mt-5 mb-5 px-10 ">
|
||||
<nav class="rounded-md w-full">
|
||||
<ol class="list-reset flex">
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<a class="text-primary hover:text-primary ">Home</a>
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<span class="text-gray-500 mx-2">/</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="mx-auto max-w-lg flex items-center justify-center mb-10 mt-20 px-5">
|
||||
<form class="bg-neutral rounded-md px-8 pt-6 pb-8 mb-4 w-full" @submit.prevent="onSubmit">
|
||||
<div class="mb-4 text-center text-[28px] ">
|
||||
Change Password
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Enter New Password</label>
|
||||
<input v-model="ChangePasswordForm.new_password" class="rounded w-full py-2 px-3 input-primary text-black"
|
||||
id="password" type="password" placeholder="Password" />
|
||||
<span v-if="v$.ChangePasswordForm.new_password.$error" class="text-red-600 text-center">
|
||||
{{ v$.ChangePasswordForm.new_password.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label class="block text-white text-sm font-bold mb-2">Confirm New Password</label>
|
||||
<input v-model="ChangePasswordForm.password_confirm" class="rounded w-full py-2 px-3 input-primary text-black"
|
||||
id="passwordtwo" type="password" autocomplete="off" placeholder="Confirm Password" />
|
||||
<span v-if="v$.ChangePasswordForm.password_confirm.$error" class="text-red-600 text-center">
|
||||
{{ v$.ChangePasswordForm.password_confirm.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-center mb-6">
|
||||
<button
|
||||
class="bg-primary hover:bg-zinc-400 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||
type="submit">
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import axios from "axios";
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import useValidate from "@vuelidate/core";
|
||||
import { required, minLength } from "@vuelidate/validators";
|
||||
import Header from "../../layouts/headers/headerauth.vue";
|
||||
import authHeader from "../../services/auth.header";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: "changePassword",
|
||||
components: {
|
||||
Header,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
user_admin: 0,
|
||||
loaded: false,
|
||||
ChangePasswordForm: {
|
||||
new_password: "",
|
||||
password_confirm: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
validations () {
|
||||
return {
|
||||
ChangePasswordForm: {
|
||||
new_password: { required, minLength: minLength(6) },
|
||||
password_confirm: { required, minLength: minLength(6) },
|
||||
},
|
||||
};
|
||||
},
|
||||
created () {
|
||||
this.userStatus();
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus () {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response:any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.$router.push({ name: "login" });
|
||||
});
|
||||
},
|
||||
|
||||
sendWordRequest (payLoad: { new_password: string; password_confirm: string }) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/auth/change-password";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payLoad,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
}).then((response:any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Success!",
|
||||
type: "success",
|
||||
});
|
||||
this.$router.push({ name: "login" });
|
||||
}
|
||||
if (response.data.error) {
|
||||
notify({
|
||||
title: "Authorization Error",
|
||||
text: response.data.error,
|
||||
type: "error",
|
||||
});
|
||||
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Invalid Credentials.",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
onSubmit () {
|
||||
const payLoad = {
|
||||
|
||||
new_password: this.ChangePasswordForm.new_password,
|
||||
password_confirm: this.ChangePasswordForm.password_confirm,
|
||||
};
|
||||
this.v$.$validate(); // checks all inputs
|
||||
if (this.v$.$invalid) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Form Failure",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
|
||||
this.sendWordRequest(payLoad);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
197
src/pages/auth/login.vue
Normal file
197
src/pages/auth/login.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
|
||||
<template>
|
||||
<Header />
|
||||
<div class="WrapperPlain">
|
||||
<div class="max-w-7xl mx-auto ">
|
||||
<div class="mx-auto max-w-lg flex items-center justify-center mt-4">
|
||||
<form
|
||||
class="rounded-md px-8 pt-6 pb-8 mb-4 w-full bg-neutral"
|
||||
@submit.prevent="onSubmit"
|
||||
>
|
||||
<div class="mb-4 text-center text-[28px] ">Login</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Username</label>
|
||||
<input
|
||||
v-model="loginForm.username"
|
||||
class="rounded w-full py-2 px-3 input-primary text-black"
|
||||
id="username"
|
||||
type="text"
|
||||
placeholder="Username"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
v-if="v$.loginForm.username.$error"
|
||||
class="text-red-600 text-center"
|
||||
>
|
||||
{{ v$.loginForm.username.$errors[0].$message }}
|
||||
</span>
|
||||
|
||||
<div class="">
|
||||
<label class="block text-white text-sm font-bold mb-2">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
v-model="loginForm.password"
|
||||
class="rounded w-full py-2 px-3
|
||||
input-primary text-black"
|
||||
id="password"
|
||||
type="password"
|
||||
autocomplete="off"
|
||||
placeholder="Password"
|
||||
/>
|
||||
<span
|
||||
v-if="v$.loginForm.password.$error"
|
||||
class="text-red-600 text-center"
|
||||
>
|
||||
{{ v$.loginForm.password.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-center mb-6 mt-4">
|
||||
<button
|
||||
class="bg-primary hover:bg-zinc-400 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||
type="submit"
|
||||
>
|
||||
Sign In
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center mt-5">
|
||||
<router-link
|
||||
:to="{ name: 'lostPassword' }"
|
||||
class="text-center font-bold text-sm text-white hover:text-accent"
|
||||
>Forgot Password?</router-link
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-center mt-5">
|
||||
<router-link
|
||||
:to="{ name: 'register' }"
|
||||
class="text-center font-bold text-sm text-white hover:text-accent"
|
||||
>Register Here</router-link
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue"
|
||||
import axios from "axios"
|
||||
import { notify } from "@kyvg/vue3-notification"
|
||||
import useValidate from "@vuelidate/core"
|
||||
import { required, minLength } from "@vuelidate/validators"
|
||||
import Header from "../../layouts/headers/headernoauth.vue";
|
||||
import authHeader from "../../services/auth.header.ts"
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: "Login",
|
||||
components: { Header },
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
loginForm: {
|
||||
username: "",
|
||||
password: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.userStatus();
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
loginForm: {
|
||||
password: { required, minLength: minLength(6) },
|
||||
username: { required, minLength: minLength(6) },
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response:any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({ name: "home" });
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
sendLogin(payLoad: { username: string; password: string }) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/auth/login"
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payLoad,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response:any) => {
|
||||
if (response.data.user) {
|
||||
localStorage.setItem("auth_token", response.data.token);
|
||||
localStorage.setItem("auth_user", response.data.user);
|
||||
this.$router.push({ name: "home" });
|
||||
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "You have been logged in!",
|
||||
type: "success",
|
||||
});
|
||||
|
||||
}
|
||||
else if (response.data.locked) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Account has been locked for security reasons. Please unlock.",
|
||||
type: "error",
|
||||
});
|
||||
|
||||
this.$router.push({ name: "lostPassword" });
|
||||
}
|
||||
else {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Login Failure!",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Login Failure!",
|
||||
type: "error",
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
onSubmit() {
|
||||
const payLoad = {
|
||||
username: this.loginForm.username,
|
||||
password: this.loginForm.password,
|
||||
};
|
||||
this.v$.$validate(); // checks all inputs
|
||||
if (this.v$.$invalid) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Form Error: Fields must be filled out correctly",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
this.sendLogin(payLoad);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
131
src/pages/auth/lostpassword.vue
Normal file
131
src/pages/auth/lostpassword.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
<template>
|
||||
<Header />
|
||||
<div class="WrapperPlain">
|
||||
<div class="container max-w-3xl mx-auto text-white">
|
||||
<div class="mt-5 mb-5">
|
||||
<nav class="rounded-md w-full">
|
||||
<ol class="list-reset flex">
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
<a class="text-primary hover:text-primary ">Home</a>
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<span class="text-gray-500 mx-2">/</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mx-auto max-w-lg flex items-center justify-center mb-10 mt-12 text-white">
|
||||
<form class="bg-neutral rounded-md px-8 pt-6 pb-8 mb-4 w-full" @submit.prevent="onSubmit">
|
||||
<div class="mb-4 text-center text-[20px] ">
|
||||
In order to unlock your account, please enter your username/email below.
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<input v-model="ForgotForm.username" class="rounded w-full py-2 px-3 input-primary text-black" type="text"
|
||||
autocomplete="off" placeholder="Username" />
|
||||
<span v-if="v$.ForgotForm.username.$error" class="text-red-600 text-center">
|
||||
{{ v$.ForgotForm.username.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<input v-model="ForgotForm.email" class="rounded w-full py-2 px-3 input-primary text-black" type="text"
|
||||
autocomplete="off" placeholder="Email" />
|
||||
<span v-if="v$.ForgotForm.email.$error" class="text-red-600 text-center">
|
||||
{{ v$.ForgotForm.email.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex p-md justify-center">
|
||||
<button
|
||||
class="bg-primary hover:bg-zinc-400 text-white font-bold py-2 px-4 rounded focus:outline-blue-300 focus:outline-none focus:shadow-outline"
|
||||
type="submit">
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue"
|
||||
import axios from "axios"
|
||||
import { notify } from "@kyvg/vue3-notification"
|
||||
import useValidate from "@vuelidate/core"
|
||||
import { required } from "@vuelidate/validators"
|
||||
import Header from "../../layouts/headers/headernoauth.vue"
|
||||
|
||||
export default defineComponent({
|
||||
name: "lostPassword",
|
||||
components: {
|
||||
Header,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
ForgotForm: {
|
||||
email: "",
|
||||
username: "",
|
||||
},
|
||||
}
|
||||
},
|
||||
validations () {
|
||||
return {
|
||||
ForgotForm: {
|
||||
email: { required },
|
||||
username: { required },
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
sendWordRequest (payLoad: {
|
||||
email: string;
|
||||
username: string;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/auth/unlock-account"
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payLoad,
|
||||
})
|
||||
.then((response:any) => {
|
||||
if (response.data.ok) {
|
||||
localStorage.setItem("auth_token", response.data.token);
|
||||
localStorage.setItem("auth_user", response.data.user);
|
||||
this.$router.push({ name: "changePassword" });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Form Error",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
onSubmit () {
|
||||
const payLoad = {
|
||||
email: this.ForgotForm.email,
|
||||
username: this.ForgotForm.username,
|
||||
}
|
||||
|
||||
this.v$.$validate(); // checks all inputs
|
||||
if (this.v$.$invalid) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Form Failure",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.sendWordRequest(payLoad);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="ts" scoped></style>
|
||||
165
src/pages/auth/register.vue
Normal file
165
src/pages/auth/register.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
<template>
|
||||
<Header />
|
||||
<div class="WrapperPlain">
|
||||
<div class="container mx-auto max-w-lg text-white">
|
||||
<div class="mx-auto flex items-center justify-center ">
|
||||
<form class="bg-neutral rounded-md px-8 pt-6 pb-8 mb-4 mt-4 w-full" method="POST" @submit.prevent="onSubmit">
|
||||
<div class="mb-4 text-center text-[28px] ">Register</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2" for="username">Username</label>
|
||||
<input v-model="registerForm.username" class="rounded w-full py-2 px-3 input-primary text-black" id="username"
|
||||
type="text" placeholder="Login Username" />
|
||||
<span v-if="v$.registerForm.username.$error" class="text-red-600 text-center">
|
||||
{{ v$.registerForm.username.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2" for="username">Email</label>
|
||||
<input v-model="registerForm.email" class="rounded w-full py-2 px-3 input-primary text-black" id="email"
|
||||
type="text" placeholder="Email" />
|
||||
<span v-if="v$.registerForm.email.$error" class="text-red-600 text-center">
|
||||
{{ v$.registerForm.email.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2" for="password">Password</label>
|
||||
<input v-model="registerForm.password" class="rounded w-full py-2 px-3 input-primary text-black" id="password"
|
||||
type="password" autocomplete="off" placeholder="Password" />
|
||||
<span v-if="v$.registerForm.password.$error" class="text-red-600 text-center">
|
||||
{{ v$.registerForm.password.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2" for="password_confirm">Confirm Password</label>
|
||||
<input v-model="registerForm.password_confirm" class="rounded w-full py-2 px-3 input-primary text-black"
|
||||
id="password" type="password" autocomplete="off" placeholder="Confirm Password" />
|
||||
<span v-if="v$.registerForm.password_confirm.$error" class="text-red-600 text-center">
|
||||
{{ v$.registerForm.password_confirm.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-center mb-6">
|
||||
<button
|
||||
class="bg-primary hover:bg-zinc-400 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||
type="submit">
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center">
|
||||
<router-link :to="{ name: 'lostPassword' }"
|
||||
class="text-center font-bold text-sm text-blue-500 hover:text-blue-800">Forgot Password?</router-link>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center mt-5">
|
||||
<router-link :to="{ name: 'login' }"
|
||||
class="text-center font-bold text-sm text-blue-500 hover:text-blue-800">Login Here</router-link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import axios from "axios";
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import { useVuelidate } from '@vuelidate/core';
|
||||
import { required, email, minLength, sameAs } from "@vuelidate/validators";
|
||||
import Header from "../../layouts/headers/headernoauth.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "Register",
|
||||
components: { Header },
|
||||
data () {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
isAuthenticated: false,
|
||||
|
||||
registerForm: {
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
password_confirm: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
|
||||
},
|
||||
validations () {
|
||||
return {
|
||||
registerForm: {
|
||||
password: { required, minLength: minLength(6) },
|
||||
username: { required, minLength: minLength(6) },
|
||||
email: { email, required },
|
||||
password_confirm: {
|
||||
required,
|
||||
minLength: minLength(6),
|
||||
sameAs: sameAs(this.registerForm.password),
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSubmit () {
|
||||
const payLoad = {
|
||||
username: this.registerForm.username,
|
||||
password: this.registerForm.password,
|
||||
email: this.registerForm.email,
|
||||
};
|
||||
this.v$.$validate(); // checks all inputs
|
||||
if (this.v$.$invalid) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Form Failure; Fields must be filled our correctly.",
|
||||
type: "error",
|
||||
});
|
||||
} else {
|
||||
this.Register(payLoad);
|
||||
}
|
||||
},
|
||||
Register (payLoad: {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/auth/register";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payLoad,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response:any) => {
|
||||
console.log(response.data)
|
||||
if (response.data.error) {
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: response.data.error,
|
||||
type: "error",
|
||||
});
|
||||
};
|
||||
|
||||
if (response.data.ok) {
|
||||
|
||||
localStorage.setItem("auth_user", response.data.user);
|
||||
localStorage.setItem("auth_token", response.data.token);
|
||||
|
||||
this.$router.push({ name: "home" });
|
||||
notify({
|
||||
title: "Authorization",
|
||||
text: "Success",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
34
src/pages/auth/routes.ts
Normal file
34
src/pages/auth/routes.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
import Login from '../auth/login.vue';
|
||||
import Register from '../auth/register.vue';
|
||||
import changePassword from '../auth/changepassword.vue';
|
||||
import lostPassword from '../auth/lostpassword.vue';
|
||||
|
||||
|
||||
const authRoutes = [
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: Login,
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'register',
|
||||
component: Register,
|
||||
},
|
||||
{
|
||||
path: '/lostpassword',
|
||||
name: 'lostPassword',
|
||||
component: lostPassword,
|
||||
},
|
||||
{
|
||||
path: '/changepassword',
|
||||
name: 'changePassword',
|
||||
component: changePassword,
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
export default authRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
172
src/pages/automatic/home.vue
Normal file
172
src/pages/automatic/home.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'delivery' }">
|
||||
Delivery
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Automatics </div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Due Date</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
<th>Name</th>
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']">
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_name'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>
|
||||
{{ oil['expected_delivery_date'] }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AutomaticHome',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
16
src/pages/automatic/routes.ts
Normal file
16
src/pages/automatic/routes.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
|
||||
import AutomaticHome from './home.vue';
|
||||
|
||||
|
||||
|
||||
const autoRoutes = [
|
||||
{
|
||||
path: '/auto',
|
||||
name: 'auto',
|
||||
component: AutomaticHome,
|
||||
},
|
||||
]
|
||||
|
||||
export default autoRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
309
src/pages/card/addcard.vue
Normal file
309
src/pages/card/addcard.vue
Normal file
@@ -0,0 +1,309 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">
|
||||
Add Credit Card for {{ customer.customer_last_name }}
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Main Card</label>
|
||||
<input v-model="CreateCardForm.basicInfo.main_card"
|
||||
class="checkbox"
|
||||
id="fill"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Name on Card</label>
|
||||
<input v-model="CreateCardForm.basicInfo.card_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Name on Card"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.card_name.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.card_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Card Number</label>
|
||||
<input v-model="CreateCardForm.basicInfo.card_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Card Number"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.card_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.card_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expiration Month</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.expiration_month"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>01</option>
|
||||
<option>02</option>
|
||||
<option>03</option>
|
||||
<option>04</option>
|
||||
<option>05</option>
|
||||
<option>06</option>
|
||||
<option>07</option>
|
||||
<option>08</option>
|
||||
<option>09</option>
|
||||
<option>10</option>
|
||||
<option>11</option>
|
||||
<option>12</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expiration Year</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.expiration_year"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>2024</option>
|
||||
<option>2025</option>
|
||||
<option>2026</option>
|
||||
<option>2027</option>
|
||||
<option>2028</option>
|
||||
<option>2029</option>
|
||||
<option>2030</option>
|
||||
</select>
|
||||
|
||||
<span v-if="v$.CreateCardForm.basicInfo.expiration_year.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.expiration_year.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Type of Card</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.type_of_card"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>Visa</option>
|
||||
<option>MasterCard</option>
|
||||
<option>Discover</option>
|
||||
<option>American Express</option>
|
||||
</select>
|
||||
|
||||
<span v-if="v$.CreateCardForm.basicInfo.type_of_card.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.type_of_card.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Security Number</label>
|
||||
<input v-model="CreateCardForm.basicInfo.security_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Back of card"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.security_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.security_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Save Credit Card
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AddCardCreate',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
|
||||
customer: {
|
||||
id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
CreateCardForm: {
|
||||
basicInfo: {
|
||||
card_name: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
card_number:'',
|
||||
main_card: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
validations() {
|
||||
return {
|
||||
CreateCardForm: {
|
||||
basicInfo: {
|
||||
card_name: {required, minLength: minLength(1)},
|
||||
expiration_month: {required, minLength: minLength(1)},
|
||||
expiration_year: {required, minLength: minLength(1)},
|
||||
security_number: {required, minLength: minLength(1)},
|
||||
type_of_card: {required, minLength: minLength(1)},
|
||||
card_number: {required, minLength: minLength(1)},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
},
|
||||
methods: {
|
||||
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
CreateCard(payload: {
|
||||
card_name: string;
|
||||
expiration_month: string;
|
||||
expiration_year: string;
|
||||
type_of_card: string;
|
||||
security_number: string;
|
||||
card_number: string;
|
||||
main_card: boolean;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/create/" + this.customer.id;
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "customerProfile", params: { id: this.customer.id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
card_name: this.CreateCardForm.basicInfo.card_name,
|
||||
card_number: this.CreateCardForm.basicInfo.card_number,
|
||||
expiration_month: this.CreateCardForm.basicInfo.expiration_month,
|
||||
expiration_year: this.CreateCardForm.basicInfo.expiration_year,
|
||||
type_of_card: this.CreateCardForm.basicInfo.type_of_card,
|
||||
security_number: this.CreateCardForm.basicInfo.security_number,
|
||||
main_card: this.CreateCardForm.basicInfo.main_card,
|
||||
};
|
||||
this.CreateCard(payload);
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
382
src/pages/card/editcard.vue
Normal file
382
src/pages/card/editcard.vue
Normal file
@@ -0,0 +1,382 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">
|
||||
Credit Card Customer: {{ customer }}
|
||||
|
||||
</div>
|
||||
<div class="text-[20px]">
|
||||
Card Id: {{card.id}}
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full"
|
||||
enctype="multipart/form-data"
|
||||
@submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Main Card</label>
|
||||
<input v-model="CreateCardForm.basicInfo.main_card"
|
||||
class="checkbox"
|
||||
id="fill"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Name on Card</label>
|
||||
<input v-model="CreateCardForm.basicInfo.card_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Name on Card"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.card_name.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.card_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Card Number</label>
|
||||
<input v-model="CreateCardForm.basicInfo.card_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Card Number"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.card_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.card_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expiration Month</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.expiration_month"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>01</option>
|
||||
<option>02</option>
|
||||
<option>03</option>
|
||||
<option>04</option>
|
||||
<option>05</option>
|
||||
<option>06</option>
|
||||
<option>07</option>
|
||||
<option>08</option>
|
||||
<option>09</option>
|
||||
<option>10</option>
|
||||
<option>11</option>
|
||||
<option>12</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expiration Year</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.expiration_year"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>2024</option>
|
||||
<option>2025</option>
|
||||
<option>2026</option>
|
||||
<option>2027</option>
|
||||
<option>2028</option>
|
||||
<option>2029</option>
|
||||
<option>2030</option>
|
||||
</select>
|
||||
|
||||
<span v-if="v$.CreateCardForm.basicInfo.expiration_year.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.expiration_year.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Type of Card</label>
|
||||
<select
|
||||
v-model="CreateCardForm.basicInfo.type_of_card"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="Month"
|
||||
>
|
||||
<option>Visa</option>
|
||||
<option>MasterCard</option>
|
||||
<option>Discover</option>
|
||||
<option>American Express</option>
|
||||
</select>
|
||||
|
||||
<span v-if="v$.CreateCardForm.basicInfo.type_of_card.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.type_of_card.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Security Number</label>
|
||||
<input v-model="CreateCardForm.basicInfo.security_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Back of card"/>
|
||||
<span v-if="v$.CreateCardForm.basicInfo.security_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCardForm.basicInfo.security_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Edit Card
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EditCard',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: '',
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
customer_last_name: '',
|
||||
customer_first_name: '',
|
||||
customer_town: '',
|
||||
customer_state: '',
|
||||
customer_zip: '',
|
||||
customer_first_call: '',
|
||||
customer_email: '',
|
||||
customer_automatic: '',
|
||||
customer_phone_number: '',
|
||||
customer_home_type: '',
|
||||
customer_apt: '',
|
||||
customer_address: '',
|
||||
},
|
||||
card: {
|
||||
id: '',
|
||||
card_name: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
main_card: '',
|
||||
user_id: '',
|
||||
},
|
||||
|
||||
card_id: null,
|
||||
customer_id: null,
|
||||
CreateCardForm: {
|
||||
basicInfo: {
|
||||
card_name: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
card_number: '',
|
||||
main_card: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateCardForm: {
|
||||
basicInfo: {
|
||||
card_name: {required, minLength: minLength(1)},
|
||||
expiration_month: {required, minLength: minLength(1)},
|
||||
expiration_year: {required, minLength: minLength(1)},
|
||||
security_number: {required, minLength: minLength(1)},
|
||||
type_of_card: {required, minLength: minLength(1)},
|
||||
card_number: {required, minLength: minLength(1)},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCard(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCard(this.$route.params.id)
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.user.id = response.data.user.id;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user.id = '';
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
|
||||
this.customer_id = response.data.user_id;
|
||||
this.customer.customer_last_name= response.data.customer_last_name;
|
||||
this.customer.customer_first_name = response.data.customer_first_name;
|
||||
this.customer.customer_town = response.data.customer_town;
|
||||
this.customer.customer_state = response.data.customer_state;
|
||||
this.customer.customer_zip = response.data.customer_zip;
|
||||
this.customer.customer_first_call = response.data.customer_first_call;
|
||||
this.customer.customer_email = response.data.customer_email;
|
||||
this.customer.customer_automatic = response.data.customer_automatic;
|
||||
this.customer.customer_phone_number = response.data.customer_phone_number;
|
||||
this.customer.customer_home_type = response.data.customer_home_type;
|
||||
this.customer.customer_apt = response.data.customer_last_name;
|
||||
this.customer.customer_address = response.data.customer_last_name;
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getCard (card_id:any) {
|
||||
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id ;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.CreateCardForm.basicInfo.card_name= response.data.card.card_name;
|
||||
this.CreateCardForm.basicInfo.expiration_month= response.data.card.expiration_month;
|
||||
this.CreateCardForm.basicInfo.expiration_year= response.data.card.expiration_year;
|
||||
this.CreateCardForm.basicInfo.type_of_card= response.data.card.type_of_card;
|
||||
this.CreateCardForm.basicInfo.security_number= response.data.card.security_number;
|
||||
this.CreateCardForm.basicInfo.main_card= response.data.card.main_card;
|
||||
this.CreateCardForm.basicInfo.card_number= response.data.card.card_number;
|
||||
|
||||
this.user.id = response.data.card.user_id
|
||||
|
||||
this.card.id=response.data.card.id;
|
||||
this.card.user_id=response.data.card.user_id;
|
||||
this.card.card_name= response.data.card.card_name
|
||||
this.card.expiration_month=response.data.card.expiration_month;
|
||||
this.card.expiration_year=response.data.card.expiration_year;
|
||||
this.card.type_of_card=response.data.card.type_of_card;
|
||||
this.card.security_number=response.data.card.security_number;
|
||||
this.card.main_card=response.data.card.main_card;
|
||||
|
||||
this.getCustomer(response.data.card.user_id)
|
||||
}
|
||||
})
|
||||
},
|
||||
editCard(payload: {
|
||||
|
||||
card_name: string;
|
||||
expiration_month: string;
|
||||
expiration_year: string;
|
||||
type_of_card: string;
|
||||
security_number: string;
|
||||
main_card: boolean;
|
||||
}) {
|
||||
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/edit/" + this.$route.params.id ;
|
||||
axios({
|
||||
method: "put",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
console.log(response.data)
|
||||
console.log(this.user.id)
|
||||
this.$router.push({name: "customerProfile", params: { id: this.card.user_id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
card_name: this.CreateCardForm.basicInfo.card_name,
|
||||
expiration_month: this.CreateCardForm.basicInfo.expiration_month,
|
||||
expiration_year: this.CreateCardForm.basicInfo.expiration_year,
|
||||
type_of_card: this.CreateCardForm.basicInfo.type_of_card,
|
||||
security_number: this.CreateCardForm.basicInfo.security_number,
|
||||
card_number: this.CreateCardForm.basicInfo.card_number,
|
||||
main_card: this.CreateCardForm.basicInfo.main_card,
|
||||
};
|
||||
this.editCard(payload);
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
207
src/pages/card/home.vue
Normal file
207
src/pages/card/home.vue
Normal file
@@ -0,0 +1,207 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<router-link :to="{ name: 'customerCreate' }">
|
||||
<button class="btn">Create Customer</button>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Card Type</th>
|
||||
<th>Card Number</th>
|
||||
<th>Expiration</th>
|
||||
<th>Main Card</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="card in cards" :key="card['id']">
|
||||
<td>
|
||||
<router-link :to="{ name: 'cardview', params: { id: card['id'] } }">
|
||||
{{ card['name_on_card'] }}
|
||||
</router-link>
|
||||
</td>
|
||||
<td>{{ card['type_of_card'] }}</td>
|
||||
<td>{{ card['name_on_card'] }}</td>
|
||||
<td>{{ card['expiration_month'] }} / {{ card['expiration_year'] }}</td>
|
||||
<td>{{ card['main_card'] }} </td>
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'cardview', params: { id: card['id'] } }">
|
||||
Oil
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'cardedit', params: { id: card['id'] } }">
|
||||
Service
|
||||
</router-link>
|
||||
|
||||
<div @click="removeCard(card['id'])">x
|
||||
Remove Card
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage" :options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
|
||||
import { defineComponent } from 'vue'
|
||||
import axios from 'axios'
|
||||
import { notify } from "@kyvg/vue3-notification";
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CardHome',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
customer: null,
|
||||
customer_id: null,
|
||||
cards: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
console.log("here")
|
||||
this.get_all_cards(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
this.customer_id = response.data.user_id;
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
get_all_cards(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.cards = response.data
|
||||
console.log(response.data)
|
||||
})
|
||||
},
|
||||
|
||||
removeCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/remove/' + card_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Deletion",
|
||||
text: "Card Removed",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
29
src/pages/card/routes.ts
Normal file
29
src/pages/card/routes.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
|
||||
import CardHome from '../card/home.vue';
|
||||
import AddCardCreate from '../card/addcard.vue';
|
||||
import EditCard from "./editcard.vue";
|
||||
|
||||
|
||||
const cardRoutes = [
|
||||
{
|
||||
path: '/card',
|
||||
name: 'cardhome',
|
||||
component: CardHome,
|
||||
},
|
||||
|
||||
{
|
||||
path: '/card/add/:id',
|
||||
name: 'cardadd',
|
||||
component: AddCardCreate,
|
||||
},
|
||||
{
|
||||
path: '/card/edit/:id',
|
||||
name: 'cardedit',
|
||||
component: EditCard,
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
export default cardRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
328
src/pages/customer/create.vue
Normal file
328
src/pages/customer/create.vue
Normal file
@@ -0,0 +1,328 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div v-if="user">
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class="w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Create a customer</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
<div class="text-[18px] mt-5 mb-5">General Info</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2"> First Name</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_first_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="First Name"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_first_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_first_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2"> Last Name</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_last_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Last Name"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_last_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_last_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-5">
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Type</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="customer_type"
|
||||
v-model="CreateCustomerForm.basicInfo.customer_home_type">
|
||||
<option class="text-white" v-for="(customer, index) in custList"
|
||||
:key="index"
|
||||
:value="customer['value']">
|
||||
{{ customer['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-[18px] mt-5 mb-5">Customer Address</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Phone Number</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_phone_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="phone number" type="tel" placeholder="Phone Number" @input="acceptNumber()" />
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_phone_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_phone_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Street Address</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_address"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="address" type="text" placeholder="Address"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_address.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_address.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_apt"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="apt" type="text" placeholder="Apt, suite, unit, building, floor, etc"/>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-20 md:mb-5 ">
|
||||
<label class="block text-white text-sm font-bold mb-2">Town</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_town"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="town" type="text" placeholder="Town"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_town.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_town.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">State</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="customer_state"
|
||||
v-model="CreateCustomerForm.basicInfo.customer_state">
|
||||
<option class="text-white" v-for="(state, index) in stateList"
|
||||
:key="index"
|
||||
:value="state['value']">
|
||||
{{ state['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_state.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_state.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Zip Code</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_zip"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="zip" type="text" placeholder="Zip"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_zip.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_zip.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Email</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_email"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="email" type="text" placeholder="Email"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_email.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_email.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Automatic</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_automatic"
|
||||
class="checkbox"
|
||||
id="automatic"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Create Customer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {email, minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CustomerCreate',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
stateList: [],
|
||||
x: '',
|
||||
custList: [],
|
||||
new_user_id: 0,
|
||||
CreateCustomerForm: {
|
||||
basicInfo: {
|
||||
customer_last_name: "",
|
||||
customer_first_name: "",
|
||||
customer_town: "",
|
||||
customer_apt: "",
|
||||
customer_home_type: "",
|
||||
customer_zip: "",
|
||||
customer_automatic: "",
|
||||
customer_email: "",
|
||||
customer_phone_number: "",
|
||||
customer_state: "",
|
||||
customer_address: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateCustomerForm: {
|
||||
basicInfo: {
|
||||
customer_last_name: {required, minLength: minLength(1)},
|
||||
customer_first_name: {required, minLength: minLength(1)},
|
||||
customer_town: {required, minLength: minLength(1)},
|
||||
customer_home_type: {required},
|
||||
customer_zip: {required, minLength: minLength(5)},
|
||||
customer_email: {email, required},
|
||||
customer_phone_number: {required},
|
||||
customer_state: {required},
|
||||
customer_address: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomerTypeList();
|
||||
this.getStatesList();
|
||||
},
|
||||
methods: {
|
||||
acceptNumber() {
|
||||
let x = this.CreateCustomerForm.basicInfo.customer_phone_number.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
|
||||
if (x){
|
||||
this.CreateCustomerForm.basicInfo.customer_phone_number = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
|
||||
}
|
||||
else {
|
||||
this.CreateCustomerForm.basicInfo.customer_phone_number = ''
|
||||
}
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
CreateCustomer(payload: {
|
||||
customer_last_name: string;
|
||||
customer_first_name: string;
|
||||
customer_town: string;
|
||||
customer_zip: string;
|
||||
customer_email: string;
|
||||
customer_phone_number: string;
|
||||
customer_address: string;
|
||||
customer_apt: string;
|
||||
customer_automatic: string;
|
||||
customer_home_type: string,
|
||||
customer_state: string;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/create";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.new_user_id = response.data.user.user_id
|
||||
this.$router.push({ name: 'customerProfile', params: { id: this.new_user_id } });
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
customer_last_name: this.CreateCustomerForm.basicInfo.customer_last_name,
|
||||
customer_first_name: this.CreateCustomerForm.basicInfo.customer_first_name,
|
||||
customer_town: this.CreateCustomerForm.basicInfo.customer_town,
|
||||
customer_zip: this.CreateCustomerForm.basicInfo.customer_zip,
|
||||
customer_email: this.CreateCustomerForm.basicInfo.customer_email,
|
||||
customer_phone_number: this.CreateCustomerForm.basicInfo.customer_phone_number,
|
||||
customer_automatic: this.CreateCustomerForm.basicInfo.customer_automatic,
|
||||
customer_home_type: this.CreateCustomerForm.basicInfo.customer_home_type,
|
||||
customer_state: this.CreateCustomerForm.basicInfo.customer_state,
|
||||
customer_apt: this.CreateCustomerForm.basicInfo.customer_apt,
|
||||
customer_address: this.CreateCustomerForm.basicInfo.customer_address,
|
||||
};
|
||||
this.CreateCustomer(payload);
|
||||
},
|
||||
getCustomerTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/customertype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.custList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getStatesList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/states";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.stateList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
371
src/pages/customer/edit.vue
Normal file
371
src/pages/customer/edit.vue
Normal file
@@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div v-if="user">
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class="w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Edit customer: {{ customer.account_number }}</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
<div class="text-[18px] mt-5 mb-5">General Info</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2"> First Name</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_first_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="First Name"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_first_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_first_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2"> Last Name</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_last_name"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="Last Name"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_last_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_last_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-5">
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Type</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="customer_type"
|
||||
v-model="CreateCustomerForm.basicInfo.customer_home_type">
|
||||
<option class="text-white" v-for="(customer, index) in custList"
|
||||
:key="index"
|
||||
:value="customer['value']">
|
||||
{{ customer['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-[18px] mt-5 mb-5">Customer Address</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Phone Number</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_phone_number"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="phone number" type="text" placeholder="Phone Number" @input="acceptNumber()"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_phone_number.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_phone_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Street Address</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_address"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="address" type="text" placeholder="Address"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_address.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_address.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_apt"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="apt" type="text" placeholder="Apt, suite, unit, building, floor, etc"/>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-20 md:mb-5 ">
|
||||
<label class="block text-white text-sm font-bold mb-2">Town</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_town"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="town" type="text" placeholder="town"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_town.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_town.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">State</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="customer_state"
|
||||
v-model="CreateCustomerForm.basicInfo.customer_state">
|
||||
<option class="text-white" v-for="(state, index) in stateList"
|
||||
:key="index"
|
||||
:value="state['value']">
|
||||
{{ state['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_state.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_state.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Zip Code</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_zip"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="zip" type="text" placeholder="Zip"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_zip.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_zip.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Email</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_email"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="email" type="text" placeholder="Email"/>
|
||||
<span v-if="v$.CreateCustomerForm.basicInfo.customer_email.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.customer_email.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Automatic</label>
|
||||
<input v-model="CreateCustomerForm.basicInfo.customer_automatic"
|
||||
class="checkbox"
|
||||
id="automatic"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Edit Customer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {email, minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CustomerEdit',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
stateList: [],
|
||||
custList: [],
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_address: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
account_number: '',
|
||||
},
|
||||
CreateCustomerForm: {
|
||||
basicInfo: {
|
||||
customer_last_name: "",
|
||||
customer_first_name: "",
|
||||
customer_town: "",
|
||||
customer_apt: "",
|
||||
customer_home_type: "",
|
||||
customer_zip: "",
|
||||
customer_automatic: "",
|
||||
customer_email: "",
|
||||
customer_phone_number: "",
|
||||
customer_state: "",
|
||||
customer_address: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateCustomerForm: {
|
||||
basicInfo: {
|
||||
customer_last_name: {required, minLength: minLength(1)},
|
||||
customer_first_name: {required, minLength: minLength(1)},
|
||||
customer_town: {required, minLength: minLength(1)},
|
||||
customer_home_type: {required},
|
||||
customer_zip: {required, minLength: minLength(5)},
|
||||
customer_email: {email, required},
|
||||
customer_phone_number: {required},
|
||||
customer_state: {required},
|
||||
customer_address: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.getCustomer(this.$route.params.id)
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomerTypeList();
|
||||
this.getStatesList();
|
||||
},
|
||||
methods: {
|
||||
acceptNumber() {
|
||||
let x = this.CreateCustomerForm.basicInfo.customer_phone_number.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
|
||||
if (x) {
|
||||
this.CreateCustomerForm.basicInfo.customer_phone_number = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
|
||||
} else {
|
||||
this.CreateCustomerForm.basicInfo.customer_phone_number = '';
|
||||
}
|
||||
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
|
||||
// gets the item from parameter router
|
||||
getCustomer(userid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + userid;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.customer = response.data;
|
||||
this.CreateCustomerForm.basicInfo.customer_last_name = response.data.customer_last_name;
|
||||
this.CreateCustomerForm.basicInfo.customer_first_name = response.data.customer_first_name;
|
||||
this.CreateCustomerForm.basicInfo.customer_town = response.data.customer_town;
|
||||
this.CreateCustomerForm.basicInfo.customer_state = response.data.customer_state;
|
||||
this.CreateCustomerForm.basicInfo.customer_zip = response.data.customer_zip;
|
||||
this.CreateCustomerForm.basicInfo.customer_automatic = response.data.customer_automatic;
|
||||
this.CreateCustomerForm.basicInfo.customer_phone_number = response.data.customer_phone_number;
|
||||
this.CreateCustomerForm.basicInfo.customer_home_type = response.data.customer_home_type;
|
||||
this.CreateCustomerForm.basicInfo.customer_apt = response.data.customer_apt;
|
||||
this.CreateCustomerForm.basicInfo.customer_email = response.data.customer_email;
|
||||
this.CreateCustomerForm.basicInfo.customer_address = response.data.customer_address;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
editItem(payload: {
|
||||
customer_last_name: string;
|
||||
customer_first_name: string;
|
||||
customer_town: string;
|
||||
customer_zip: string;
|
||||
customer_email: string;
|
||||
customer_phone_number: string;
|
||||
customer_automatic: string;
|
||||
customer_home_type: string,
|
||||
customer_state: string;
|
||||
customer_address: string;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/edit/" + this.customer.id;
|
||||
axios({
|
||||
method: "put",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "customerProfile", params: {id: this.customer.id}});
|
||||
}
|
||||
;
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
;
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
customer_last_name: this.CreateCustomerForm.basicInfo.customer_last_name,
|
||||
customer_first_name: this.CreateCustomerForm.basicInfo.customer_first_name,
|
||||
customer_town: this.CreateCustomerForm.basicInfo.customer_town,
|
||||
customer_zip: this.CreateCustomerForm.basicInfo.customer_zip,
|
||||
customer_email: this.CreateCustomerForm.basicInfo.customer_email,
|
||||
customer_phone_number: this.CreateCustomerForm.basicInfo.customer_phone_number,
|
||||
customer_automatic: this.CreateCustomerForm.basicInfo.customer_automatic,
|
||||
customer_home_type: this.CreateCustomerForm.basicInfo.customer_home_type,
|
||||
customer_state: this.CreateCustomerForm.basicInfo.customer_state,
|
||||
customer_address: this.CreateCustomerForm.basicInfo.customer_address,
|
||||
};
|
||||
this.editItem(payload);
|
||||
},
|
||||
getCustomerTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/customertype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.custList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getStatesList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/states";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.stateList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
186
src/pages/customer/home.vue
Normal file
186
src/pages/customer/home.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Town</th>
|
||||
<th>Automatic</th>
|
||||
<th>Phone Number</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="person in customers" :key="person['id']">
|
||||
|
||||
<td>
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: person['id'] } }">
|
||||
{{ person['customer_first_name'] }} {{ person['customer_last_name'] }}
|
||||
</router-link>
|
||||
</td>
|
||||
<td>{{ person['customer_town'] }}</td>
|
||||
<td>
|
||||
<div v-if="person['customer_automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>{{ person['customer_phone_number'] }}</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
|
||||
<router-link :to="{ name: 'deliveryCreate', params: { id: person['id'] } }" class="cursor-pointer underline hover:text-blue-300">
|
||||
Oil
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'serviceCreate', params: { id: person['id'] } }" class="cursor-pointer underline hover:text-blue-300">
|
||||
Service
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{ name: 'customerEdit', params: { id: person['id'] } }" class="cursor-pointer underline hover:text-blue-300">
|
||||
Edit
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: person['id'] } }" class="cursor-pointer underline hover:text-blue-300">
|
||||
View
|
||||
</router-link>
|
||||
<a @click.prevent="deleteCustomer(person['id'])" class="cursor-pointer underline hover:text-blue-300">
|
||||
Delete
|
||||
</a>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CustomerHome',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
customers: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.customers = [];
|
||||
this.get_customers(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_customers(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/customer/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.customers = response.data
|
||||
})
|
||||
},
|
||||
deleteCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/customer/delete/' + user_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then(() => {
|
||||
|
||||
this.get_customers(1)
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
553
src/pages/customer/profile/home.vue
Normal file
553
src/pages/customer/profile/home.vue
Normal file
@@ -0,0 +1,553 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<div class=" w-full mt-10" v-if="customer !== null">
|
||||
|
||||
<div class="grid grid-cols-12 gap-5">
|
||||
<div class="col-span-4 bg-neutral p-5 ">
|
||||
<img src="../../../assets/images/user_placeholder.png"
|
||||
alt="Drone Image"
|
||||
width="200"
|
||||
height="250"/>
|
||||
</div>
|
||||
<div class="col-span-8 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex justify-evenly pb-5">
|
||||
<div class="btn">
|
||||
<router-link :to="{ name: 'deliveryCreate', params: { id: customer.id } }"
|
||||
class="cursor-pointer underline hover:text-blue-300">
|
||||
Create Delivery
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<router-link :to="{ name: 'serviceCreate', params: { id: customer.id } }"
|
||||
class="cursor-pointer underline hover:text-blue-300">
|
||||
Create Service
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<router-link :to="{ name: 'customerEdit', params: { id: customer.id } }" class="">
|
||||
Edit Customer
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex pb-5 text-lg">{{ customer.account_number }}</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
|
||||
{{ customer.customer_address }}
|
||||
<div v-if="customer.customer_apt != 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex text-2xl">
|
||||
Stats
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2 font-bold">Delivery</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Delivery Orders: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Gallons: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Last Delivery: 0
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2 font-bold">Service</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Service Calls: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Last Service Call: 0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 font-bold flex text-2xl">
|
||||
Credit Cards
|
||||
</div>
|
||||
<div class="col-span-6 font-bold flex ">
|
||||
|
||||
<router-link :to="{ name: 'cardadd', params: { id: customer.user_id } }">
|
||||
<button class="btn">Add Credit Card</button>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="text-red-600" v-if="credit_cards_count == 0">
|
||||
No Cards on File! Cash Customer till card added.
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ credit_cards_count }} credit card(s) on file.
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="card in credit_cards" class="col-span-12">
|
||||
|
||||
<div class="flex flex-row ">
|
||||
<div v-if="card.main_card" class="basis-1/3 p-2">
|
||||
<div class="bg-accent rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ card.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
|
||||
<a @click.prevent="editCard(card.id)" class="cursor-pointer underline hover:text-blue-300">Edit
|
||||
Card</a>
|
||||
<a @click.prevent="removeCard(card.id)" class="cursor-pointer underline hover:text-blue-300">Remove
|
||||
Card</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ card.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<a @click.prevent="editCard(card.id)" class="cursor-pointer underline hover:text-blue-300">Edit
|
||||
Card</a>
|
||||
<a @click.prevent="removeCard(card.id)" class="cursor-pointer underline hover:text-blue-300">Remove
|
||||
Card</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 font-bold flex text-2xl">
|
||||
Financial
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex text-2xl">Orders</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-12 ">
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<input type="radio" name="my_tabs_1" role="tab" class="tab" aria-label="Deliveries" checked/>
|
||||
<div role="tabpanel" class="tab-content pt-10">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
<th>Name</th>
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']">
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_name'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
|
||||
</td>
|
||||
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<input type="radio" name="my_tabs_1" role="tab" class="tab" aria-label="Service"/>
|
||||
<div role="tabpanel" class="tab-content pt-10">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Customer Name</th>
|
||||
<th>Status</th>
|
||||
<th>Service Type</th>
|
||||
<th>Scheduled Date</th>
|
||||
<th>Tech Name</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="service in service_orders" :key="service['id']">
|
||||
|
||||
<td>
|
||||
{{ service['customer_first_name'] }} {{ service['customer_last_name'] }}
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="service['status'] == 0">Waiting/not paid</div>
|
||||
<div v-else-if="service['status'] == 1">Paid /waiting</div>
|
||||
<div v-else-if="service['status'] == 2">Scheduled Today</div>
|
||||
<div v-else-if="service['status'] == 3">Completed/Unpaid</div>
|
||||
<div v-else-if="service['status'] == 4">Completed/Paid</div>
|
||||
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="service['service_type'] == 0">General</div>
|
||||
<div v-else-if="service['service_type'] == 1">Cleaning / Tuneup</div>
|
||||
<div v-else-if="service['service_type'] == 2">No Heat</div>
|
||||
<div v-else-if="service['service_type'] == 3">Install</div>
|
||||
<div v-else-if="service['service_type'] == 4">Call Back</div>
|
||||
<div v-else-if="service['service_type'] == 5">Quote</div>
|
||||
<div v-else-if="service['service_type'] == 6">Emergency</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>{{ service['scheduled_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="service['payment_type'] == 0">Cash C.O.D</div>
|
||||
<div v-else-if="service['payment_type'] == 1">Credit</div>
|
||||
<div v-else-if="service['payment_type'] == 2">Stripe</div>
|
||||
<div v-else-if="service['payment_type'] == 3">Cash/Credit</div>
|
||||
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>
|
||||
{{ service['tech_first_name'] }} {{ service['tech_last_name'] }}
|
||||
</td>
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'serviceEdit', params: { id: service['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import PaginationComp from "../../../components/pagination.vue";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'CustomerProfile',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
credit_cards: [
|
||||
{
|
||||
id: 0,
|
||||
name_on_card: '',
|
||||
main_card: false,
|
||||
card_number: '',
|
||||
expiration_month: '',
|
||||
type_of_card: '',
|
||||
last_four_digits: '',
|
||||
expiration_year: '',
|
||||
|
||||
}
|
||||
],
|
||||
credit_cards_count: 0,
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_address: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
account_number: '',
|
||||
},
|
||||
deliveries: [],
|
||||
service_orders: [],
|
||||
delivery_page: 1,
|
||||
delivery_perPage: 50,
|
||||
delivery_recordsLength: 0,
|
||||
delivery_options: {
|
||||
delivery_edgeNavigation: false,
|
||||
delivery_format: false,
|
||||
delivery_template: PaginationComp
|
||||
},
|
||||
|
||||
service_page: 1,
|
||||
service_perPage: 50,
|
||||
service_recordsLength: 0,
|
||||
service_options: {
|
||||
service_edgeNavigation: false,
|
||||
service_format: false,
|
||||
service_template: PaginationComp
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.getCreditCards(this.$route.params.id)
|
||||
this.getCreditCardsCount(this.$route.params.id)
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
this.getCustomerService(this.$route.params.id, this.service_page)
|
||||
this.getCustomerDelivery(this.$route.params.id, this.delivery_page)
|
||||
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.getCustomer(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
|
||||
getCustomer(userid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/customer/' + userid;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
|
||||
this.customer = response.data
|
||||
})
|
||||
},
|
||||
|
||||
getCreditCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/' + user_id;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
|
||||
this.credit_cards = response.data
|
||||
})
|
||||
},
|
||||
|
||||
getCreditCardsCount(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/onfile/' + user_id;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
|
||||
this.credit_cards_count = response.data.cards
|
||||
})
|
||||
},
|
||||
|
||||
getCustomerService(userid: any, service_page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/service/customer/' + userid + '/' + service_page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.service_orders = response.data
|
||||
})
|
||||
},
|
||||
|
||||
getCustomerDelivery(userid: any, delivery_page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/customer/' + userid + '/' + delivery_page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
|
||||
editCard(card_id: any) {
|
||||
this.$router.push({name: "cardedit", params: {id: card_id}});
|
||||
},
|
||||
|
||||
|
||||
removeCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/card/remove/' + card_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then(() => {
|
||||
this.getCreditCards(this.$route.params.id)
|
||||
this.getCreditCardsCount(this.$route.params.id)
|
||||
notify({
|
||||
title: "Card Status",
|
||||
text: "Card Removed",
|
||||
type: "Success",
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
33
src/pages/customer/routes.ts
Normal file
33
src/pages/customer/routes.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
import CustomerHome from '../customer/home.vue';
|
||||
import CustomerCreate from '../customer/create.vue';
|
||||
import CustomerEdit from "../customer/edit.vue";
|
||||
import CustomerProfile from "./profile/home.vue"
|
||||
|
||||
const customerRoutes = [
|
||||
{
|
||||
path: '/customer',
|
||||
name: 'customer',
|
||||
component: CustomerHome,
|
||||
},
|
||||
|
||||
{
|
||||
path: '/customer/create',
|
||||
name: 'customerCreate',
|
||||
component: CustomerCreate,
|
||||
},
|
||||
{
|
||||
path: '/customer/edit/:id',
|
||||
name: 'customerEdit',
|
||||
component: CustomerEdit,
|
||||
},
|
||||
{
|
||||
path: '/customer/:id',
|
||||
name: 'customerProfile',
|
||||
component: CustomerProfile,
|
||||
},
|
||||
]
|
||||
|
||||
export default customerRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
368
src/pages/delivery/create.vue
Normal file
368
src/pages/delivery/create.vue
Normal file
@@ -0,0 +1,368 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex pb-5 text-lg">{{customer.account_number}}</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Create Oil Delivery
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Fill </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.customer_asked_for_fill"
|
||||
class="checkbox"
|
||||
id="fill"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Gallons Ordered</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.gallons_ordered"
|
||||
:disabled="CreateOilOrderForm.basicInfo.customer_asked_for_fill == true"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="# gallons"/>
|
||||
<span v-if="v$.CreateOilOrderForm.basicInfo.gallons_ordered.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateOilOrderForm.basicInfo.gallons_ordered.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expected </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.expected_delivery_date"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date"
|
||||
min="2023-01-01" max="2030-01-01"/>
|
||||
<span v-if="v$.CreateOilOrderForm.basicInfo.expected_delivery_date.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateOilOrderForm.basicInfo.expected_delivery_date.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-control">
|
||||
<div class="label">
|
||||
<span class="label-text">Delivery notes</span>
|
||||
</div>
|
||||
<textarea class="textarea textarea-bordered h-24"
|
||||
placeholder="Describe any thing given from the customer .."
|
||||
v-model="CreateOilOrderForm.basicInfo.dispatcher_notes_taken"></textarea>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Prime</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.prime"
|
||||
class="checkbox"
|
||||
id="prime"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Same Day </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.same_day"
|
||||
class="checkbox"
|
||||
id="same_day"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="bg-neutral">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Cash</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.cash"
|
||||
class="checkbox"
|
||||
id="cash"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Credit </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.credit"
|
||||
class="checkbox"
|
||||
id="Credit"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Cards Payment</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="userCards"
|
||||
v-model="CreateOilOrderForm.basicInfo.userCards">
|
||||
<option class="text-white" v-for="(card, index) in userCards"
|
||||
:key="index"
|
||||
:value="card['id']">
|
||||
{{ card['type_of_card'] }} {{ card['card_number'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Create Oil Order
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryCreate',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
userCards: [],
|
||||
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: '',
|
||||
customer_asked_for_fill: false,
|
||||
expected_delivery_date: '',
|
||||
dispatcher_notes_taken: '',
|
||||
prime: false,
|
||||
userCards: [],
|
||||
same_day: false,
|
||||
credit: false,
|
||||
cash: false,
|
||||
credit_card_id: 0,
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
customer_last_name: '',
|
||||
customer_first_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_first_call: '',
|
||||
customer_email: '',
|
||||
customer_automatic: '',
|
||||
customer_phone_number: '',
|
||||
customer_home_type: 0,
|
||||
customer_apt: '',
|
||||
customer_address: '',
|
||||
account_number: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
this.getPaymentCards(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
this.getPaymentCards(this.$route.params.id);
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
console.log(this.customer)
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getPaymentCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/cards/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCards = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
CreateOilOrder(payload: {
|
||||
gallons_ordered: string;
|
||||
customer_asked_for_fill: boolean;
|
||||
prime: boolean;
|
||||
same_day: boolean;
|
||||
cash: boolean;
|
||||
credit: boolean;
|
||||
expected_delivery_date: string;
|
||||
dispatcher_notes_taken: string;
|
||||
credit_card_id: any;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/create/" + this.customer.id;
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
console.log(response.data)
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "payOil", params: {id: response.data.delivery_id}});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
gallons_ordered: this.CreateOilOrderForm.basicInfo.gallons_ordered,
|
||||
customer_asked_for_fill: this.CreateOilOrderForm.basicInfo.customer_asked_for_fill,
|
||||
expected_delivery_date: this.CreateOilOrderForm.basicInfo.expected_delivery_date,
|
||||
dispatcher_notes_taken: this.CreateOilOrderForm.basicInfo.dispatcher_notes_taken,
|
||||
prime: this.CreateOilOrderForm.basicInfo.prime,
|
||||
same_day: this.CreateOilOrderForm.basicInfo.same_day,
|
||||
cash: this.CreateOilOrderForm.basicInfo.cash,
|
||||
credit: this.CreateOilOrderForm.basicInfo.credit,
|
||||
credit_card_id: this.CreateOilOrderForm.basicInfo.userCards,
|
||||
};
|
||||
this.CreateOilOrder(payload);
|
||||
},
|
||||
|
||||
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
556
src/pages/delivery/edit.vue
Normal file
556
src/pages/delivery/edit.vue
Normal file
@@ -0,0 +1,556 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">
|
||||
Edit Oil Delivery
|
||||
</div>
|
||||
<div class="bg-neutral rounded-md mx-5 my-5">
|
||||
<div class="flex">
|
||||
Delivery id: {{ deliveryOrder.id }}
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1" v-if="deliveryOrder.payment_type==1">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.card_number }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-neutral rounded-md mx-5 my-5">
|
||||
<div class="flex">
|
||||
Order Date: {{ deliveryOrder.when_ordered }}
|
||||
</div>
|
||||
<div class="flex">
|
||||
Expected Delivery Date: {{ deliveryOrder.expected_delivery_date }}
|
||||
</div>
|
||||
<div class="flex">
|
||||
Price per gallon: {{ deliveryOrder.customer_price }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-neutral rounded-md mx-5 my-5">
|
||||
<div class="flex">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
|
||||
<div class="bg-neutral">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Cash</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.cash"
|
||||
class="checkbox"
|
||||
id="cash"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Credit </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.card"
|
||||
class="checkbox"
|
||||
id="Credit"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Cards Payment</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="userCards"
|
||||
v-model="CreateOilOrderForm.basicInfo.userCards">
|
||||
<option class="text-white" v-for="(card, index) in userCards"
|
||||
:key="index"
|
||||
:value="card['id']">
|
||||
{{ card['type_of_card'] }} {{ card['card_number'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Delivery Status</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="delivery_status"
|
||||
v-model="CreateOilOrderForm.basicInfo.delivery_status">
|
||||
<option class="text-white" v-for="(delivery, index) in deliveryStatus"
|
||||
:key="index"
|
||||
:value="delivery['value']">
|
||||
{{ delivery['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateOilOrderForm.basicInfo.delivery_status.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateCustomerForm.basicInfo.delivery_status.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Fill </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.customer_asked_for_fill"
|
||||
class="checkbox"
|
||||
id="fill"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Gallons Ordered</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.gallons_ordered"
|
||||
:disabled="CreateOilOrderForm.basicInfo.customer_asked_for_fill "
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="# gallons"/>
|
||||
<span v-if="v$.CreateOilOrderForm.basicInfo.gallons_ordered.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateOilOrderForm.basicInfo.gallons_ordered.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expected </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.expected_delivery_date"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date"
|
||||
min="2023-01-01" max="2030-01-01"/>
|
||||
<span v-if="v$.CreateOilOrderForm.basicInfo.expected_delivery_date.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateOilOrderForm.basicInfo.expected_delivery_date.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Delivery Notes</label>
|
||||
|
||||
<textarea class="textarea textarea-bordered h-24 w-full"
|
||||
placeholder="Describe any thing given from the customer .."
|
||||
v-model="CreateOilOrderForm.basicInfo.dispatcher_notes_taken"></textarea>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Prime</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.prime"
|
||||
class="checkbox"
|
||||
id="prime"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Same Day </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.same_day"
|
||||
class="checkbox"
|
||||
id="same_day"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Edit Oil Delivery
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryEdit',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
deliveryStatus: [],
|
||||
userCards: [],
|
||||
userCard: {
|
||||
date_added: '',
|
||||
user_id: '',
|
||||
card_number: '',
|
||||
last_four_digits: '',
|
||||
name_on_card: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
accepted_or_declined: '',
|
||||
main_card: '',
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
deliveryOrder: {
|
||||
id: '',
|
||||
customer_id: 0,
|
||||
customer_name: '',
|
||||
customer_address: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
gallons_ordered: 0,
|
||||
customer_asked_for_fill: 0,
|
||||
gallons_delivered: '',
|
||||
customer_filled: 0,
|
||||
delivery_status: 0,
|
||||
when_ordered: '',
|
||||
when_delivered: '',
|
||||
expected_delivery_date: '',
|
||||
automatic: 0,
|
||||
oil_id: 0,
|
||||
supplier_price: '',
|
||||
customer_price: '',
|
||||
customer_temperature: '',
|
||||
dispatcher_notes: '',
|
||||
prime: 0,
|
||||
same_day: 0,
|
||||
payment_type: 0,
|
||||
payment_card_id: 0,
|
||||
driver_employee_id: 0,
|
||||
driver_first_name: '',
|
||||
driver_last_name: '',
|
||||
},
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: '',
|
||||
customer_asked_for_fill: false,
|
||||
expected_delivery_date: '',
|
||||
dispatcher_notes_taken: '',
|
||||
prime: false,
|
||||
same_day: false,
|
||||
delivery_status: '',
|
||||
userCards: [],
|
||||
credit_card_id: 0,
|
||||
cash: false,
|
||||
card: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
delivery_status: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getDeliveryForm(this.$route.params.id);
|
||||
this.getDeliveryOrder(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getDeliveryForm(this.$route.params.id)
|
||||
this.getDeliveryOrder(this.$route.params.id);
|
||||
this.getDeliveryStatusList();
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
|
||||
getDeliveryOrder(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.CreateOilOrderForm.basicInfo.gallons_ordered = response.data.delivery.delivery_gallons_ordered;
|
||||
this.CreateOilOrderForm.basicInfo.customer_asked_for_fill = response.data.delivery.delivery_asked_for_fill;
|
||||
this.CreateOilOrderForm.basicInfo.expected_delivery_date = response.data.delivery.delivery_expected_delivery_date;
|
||||
this.CreateOilOrderForm.basicInfo.dispatcher_notes_taken = response.data.delivery.delivery_dispatcher_notes;
|
||||
this.CreateOilOrderForm.basicInfo.prime = response.data.delivery.delivery_prime;
|
||||
this.CreateOilOrderForm.basicInfo.same_day = response.data.delivery.delivery_same_day;
|
||||
this.CreateOilOrderForm.basicInfo.delivery_status = response.data.delivery.delivery_status;
|
||||
if (response.data.delivery.payment_type == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.userCards = response.data.delivery.payment_card_id;
|
||||
}
|
||||
if (response.data.delivery.delivery_prime == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.prime = true
|
||||
}
|
||||
if (response.data.delivery.delivery_same_day == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.same_day = true
|
||||
}
|
||||
|
||||
if (response.data.delivery.payment_type == 0) {
|
||||
this.CreateOilOrderForm.basicInfo.card = false
|
||||
this.CreateOilOrderForm.basicInfo.cash = true
|
||||
}
|
||||
if (response.data.delivery.payment_type == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.card = true
|
||||
this.CreateOilOrderForm.basicInfo.cash = false
|
||||
}
|
||||
if (response.data.delivery.payment_type == 2) {
|
||||
this.CreateOilOrderForm.basicInfo.card = true
|
||||
this.CreateOilOrderForm.basicInfo.cash = true
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getDeliveryForm(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.deliveryOrder = response.data
|
||||
this.getCustomer(this.deliveryOrder.customer_id)
|
||||
}
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
console.log(this.deliveryOrder.payment_card_id)
|
||||
this.getPaymentCards(this.deliveryOrder.customer_id);
|
||||
if (this.deliveryOrder.payment_type == 1 ) {
|
||||
this.getPaymentCard(this.deliveryOrder.payment_card_id)
|
||||
}
|
||||
if (this.deliveryOrder.payment_type == 2 ) {
|
||||
this.getPaymentCard(this.deliveryOrder.payment_card_id)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCard = response.data;
|
||||
this.CreateOilOrderForm.basicInfo.userCards = response.data.id
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getPaymentCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/cards/"+ user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCards = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
editOilOrder(payload: {
|
||||
gallons_ordered: string;
|
||||
customer_asked_for_fill: boolean;
|
||||
prime: boolean;
|
||||
same_day: boolean;
|
||||
delivery_status: string;
|
||||
expected_delivery_date: string;
|
||||
dispatcher_notes_taken: string;
|
||||
cash: boolean;
|
||||
credit: boolean;
|
||||
credit_card_id: any;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/edit/" + this.deliveryOrder.id;
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "delivery"});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
getDeliveryStatusList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/deliverystatus";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.deliveryStatus = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
gallons_ordered: this.CreateOilOrderForm.basicInfo.gallons_ordered,
|
||||
customer_asked_for_fill: this.CreateOilOrderForm.basicInfo.customer_asked_for_fill,
|
||||
expected_delivery_date: this.CreateOilOrderForm.basicInfo.expected_delivery_date,
|
||||
dispatcher_notes_taken: this.CreateOilOrderForm.basicInfo.dispatcher_notes_taken,
|
||||
prime: this.CreateOilOrderForm.basicInfo.prime,
|
||||
same_day: this.CreateOilOrderForm.basicInfo.same_day,
|
||||
delivery_status: this.CreateOilOrderForm.basicInfo.delivery_status,
|
||||
|
||||
cash: this.CreateOilOrderForm.basicInfo.cash,
|
||||
credit: this.CreateOilOrderForm.basicInfo.card,
|
||||
credit_card_id: this.CreateOilOrderForm.basicInfo.userCards,
|
||||
};
|
||||
this.editOilOrder(payload);
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
204
src/pages/delivery/home.vue
Normal file
204
src/pages/delivery/home.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryHome',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delete/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
76
src/pages/delivery/routes.ts
Normal file
76
src/pages/delivery/routes.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import DeliveryHome from './home.vue';
|
||||
import DeliveryCreate from "./create.vue";
|
||||
import DeliveryEdit from './edit.vue';
|
||||
import DeliveryOrder from './view.vue';
|
||||
import deliveryTicketsMissing from './update_tickets/missing_data_home.vue';
|
||||
import finalizeTicket from './update_tickets/finalize_ticket.vue';
|
||||
|
||||
import deliveryCancelled from './viewstatus/cancelled.vue';
|
||||
import deliveryIssue from './viewstatus/issue.vue';
|
||||
import deliveryDelivered from './viewstatus/delivered.vue';
|
||||
import deliveryOutForDelivery from './viewstatus/out_for_delivery.vue';
|
||||
import deliveryWaiting from './viewstatus/waiting.vue';
|
||||
|
||||
const deliveryRoutes = [
|
||||
{
|
||||
path: '/delivery',
|
||||
name: 'delivery',
|
||||
component: DeliveryHome,
|
||||
},
|
||||
|
||||
{
|
||||
path: '/delivery/create/:id',
|
||||
name: 'deliveryCreate',
|
||||
component: DeliveryCreate,
|
||||
},
|
||||
{
|
||||
path: '/delivery/edit/:id',
|
||||
name: 'deliveryEdit',
|
||||
component: DeliveryEdit,
|
||||
},
|
||||
{
|
||||
path: '/delivery/:id',
|
||||
name: 'deliveryOrder',
|
||||
component: DeliveryOrder,
|
||||
},
|
||||
{
|
||||
path: '/delivery/tickets/missing',
|
||||
name: 'deliveryTicketsMissing',
|
||||
component: deliveryTicketsMissing,
|
||||
},
|
||||
{
|
||||
path: '/delivery/tickets/finalize/:id',
|
||||
name: 'finalizeTicket',
|
||||
component: finalizeTicket,
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: '/delivery/cancelled',
|
||||
name: 'deliveryCancelled',
|
||||
component: deliveryCancelled,
|
||||
},
|
||||
{
|
||||
path: '/delivery/issue',
|
||||
name: 'deliveryIssue',
|
||||
component: deliveryIssue,
|
||||
},
|
||||
{
|
||||
path: '/delivery/delivered',
|
||||
name: 'deliveryDelivered',
|
||||
component: deliveryDelivered,
|
||||
},
|
||||
{
|
||||
path: '/delivery/outfordelivery',
|
||||
name: 'deliveryOutForDelivery',
|
||||
component: deliveryOutForDelivery,
|
||||
},
|
||||
{
|
||||
path: '/delivery/waiting',
|
||||
name: 'deliveryWaiting',
|
||||
component: deliveryWaiting,
|
||||
},
|
||||
]
|
||||
|
||||
export default deliveryRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
545
src/pages/delivery/update_tickets/finalize_ticket.vue
Normal file
545
src/pages/delivery/update_tickets/finalize_ticket.vue
Normal file
@@ -0,0 +1,545 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs mb-10">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md pb-5">
|
||||
<div class="text-[24px]">
|
||||
Finalize Oil Order # {{ deliveryOrder.id }}
|
||||
</div>
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Customer
|
||||
</div>
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-span-6 ">
|
||||
<div class="flex justify-end" v-if="deliveryOrder.id ">
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: deliveryOrder.id } }">
|
||||
<button class="btn">Edit Order</button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Delivery Status
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Status
|
||||
</div>
|
||||
<div class="col-span-12">
|
||||
<div v-if="deliveryOrder.delivery_status == 0">waiting</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 1">delivered</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 2">Out for Delivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 3">Cancelled</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 4">Partial Delivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 5">misdelivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 6">unknown</div>
|
||||
<div v-else></div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-5">
|
||||
Scheduled date/time
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.expected_delivery_date }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-5">
|
||||
When Called
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.when_ordered }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-5">
|
||||
Driver Name
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.driver_first_name }} {{ deliveryOrder.driver_last_name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Info
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.customer_asked_for_fill==1">Fill</div>
|
||||
<div v-else>Gallons delivered: {{ deliveryOrder.gallons_delivered }}</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.prime==1">
|
||||
Prime Required: Yes
|
||||
</div>
|
||||
<div v-if="deliveryOrder.prime==0">
|
||||
Prime Required: No
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.same_day==1">
|
||||
Same Day: Yes
|
||||
</div>
|
||||
<div v-if="deliveryOrder.same_day==0">
|
||||
Same Day: No
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Payment
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-2">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.payment_type==0">Cash</div>
|
||||
<div v-else-if="deliveryOrder.payment_type==1">Credit Card</div>
|
||||
<div v-else-if="deliveryOrder.payment_type==2">Credit Card & cash</div>
|
||||
<div v-else>No Payment Type Added</div>
|
||||
</div>
|
||||
<div class="col-span-12" v-if="deliveryOrder.payment_type==1">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-2">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12" v-if="deliveryOrder.payment_type==2">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 ">Total {{deliveryMoney.total_amount}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Change Details
|
||||
</div>
|
||||
<form class="rounded-md bg-neutral " enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
<div class="grid grid-cols-12 p-5">
|
||||
|
||||
<div class="col-span-12 mb-5 md:mb-0 gap-10 ">
|
||||
|
||||
<label class="block text-white text-sm font-bold mb-2">Gallons Ordered</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.gallons_delivered"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="text" placeholder="# gallons"/>
|
||||
|
||||
</div>
|
||||
<div class="col-span-12mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Prime</label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.prime"
|
||||
class="checkbox"
|
||||
id="prime"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Same Day </label>
|
||||
<input v-model="CreateOilOrderForm.basicInfo.same_day"
|
||||
class="checkbox"
|
||||
id="same_day"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button
|
||||
class="btn">
|
||||
Finalize Delivery
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'finalizeTicket',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: 0
|
||||
},
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_delivered: '',
|
||||
prime: false,
|
||||
same_day: false,
|
||||
cash: false,
|
||||
card: false,
|
||||
userCards: []
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
deliveryNotesDriver: [],
|
||||
|
||||
userCard: {
|
||||
date_added: '',
|
||||
user_id: '',
|
||||
card_number: '',
|
||||
last_four_digits: '',
|
||||
name_on_card: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
accepted_or_declined: '',
|
||||
main_card: '',
|
||||
},
|
||||
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
|
||||
deliveryMoney: {
|
||||
time_added: '',
|
||||
total_amount_oil: '',
|
||||
total_amount_emergency: '',
|
||||
total_amount_prime: '',
|
||||
total_amount_fee: '',
|
||||
total_amount: '',
|
||||
},
|
||||
|
||||
deliveryOrder: {
|
||||
id: '',
|
||||
customer_id: 0,
|
||||
customer_name: '',
|
||||
customer_address: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
gallons_ordered: 0,
|
||||
customer_asked_for_fill: 0,
|
||||
gallons_delivered: '',
|
||||
customer_filled: 0,
|
||||
delivery_status: 0,
|
||||
when_ordered: '',
|
||||
when_delivered: '',
|
||||
expected_delivery_date: '',
|
||||
automatic: 0,
|
||||
oil_id: 0,
|
||||
supplier_price: '',
|
||||
customer_price: '',
|
||||
customer_temperature: '',
|
||||
dispatcher_notes: '',
|
||||
prime: 0,
|
||||
same_day: 0,
|
||||
payment_type: 0,
|
||||
payment_card_id: '',
|
||||
driver_employee_id: 0,
|
||||
driver_first_name: '',
|
||||
driver_last_name: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getOilOrder(this.$route.params.id);
|
||||
this.getOilOrderMoney(this.$route.params.id);
|
||||
this.get_delivery_amount(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getOilOrder(this.$route.params.id);
|
||||
this.getOilOrderMoney(this.$route.params.id);
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.user.id = response.data.user_id;
|
||||
}
|
||||
})
|
||||
},
|
||||
getOilOrder(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.deliveryOrder = response.data
|
||||
this.getCustomer(this.deliveryOrder.customer_id)
|
||||
|
||||
if (this.deliveryOrder.payment_type == 1) {
|
||||
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
||||
}
|
||||
if (response.data.prime == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.prime = true
|
||||
}
|
||||
if (response.data.same_day == 1) {
|
||||
this.CreateOilOrderForm.basicInfo.same_day = true
|
||||
}
|
||||
|
||||
this.CreateOilOrderForm.basicInfo.gallons_delivered = response.data.gallons_delivered;
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
get_delivery_amount(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/amount/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCard = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
getOilOrderMoney(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/money/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.deliveryMoney = response.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
editOilOrder(payload: {
|
||||
gallons_delivered: string;
|
||||
prime: boolean;
|
||||
same_day: boolean;
|
||||
cash: boolean;
|
||||
credit: boolean;
|
||||
credit_card_id: any;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/deliverydata/finalize/" + this.deliveryOrder.id;
|
||||
axios({
|
||||
method: "put",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "Ticket is finalized",
|
||||
type: "success",
|
||||
});
|
||||
this.$router.push({name: "deliveryTicketsMissing"});
|
||||
}
|
||||
if (response.data.error) {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not finalize ticket",
|
||||
type: "error",
|
||||
});
|
||||
this.$router.push("deliveryTicketsMissing");
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
gallons_delivered: this.CreateOilOrderForm.basicInfo.gallons_delivered,
|
||||
prime: this.CreateOilOrderForm.basicInfo.prime,
|
||||
same_day: this.CreateOilOrderForm.basicInfo.same_day,
|
||||
cash: this.CreateOilOrderForm.basicInfo.cash,
|
||||
credit: this.CreateOilOrderForm.basicInfo.card,
|
||||
credit_card_id: this.CreateOilOrderForm.basicInfo.userCards,
|
||||
};
|
||||
this.editOilOrder(payload);
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
145
src/pages/delivery/update_tickets/missing_data_home.vue
Normal file
145
src/pages/delivery/update_tickets/missing_data_home.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
<th>Address</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']">
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }}</td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
|
||||
<td class="flex gap-5" v-if="oil['delivery_status'] == 1">
|
||||
<router-link :to="{ name: 'finalizeTicket', params: { id: oil['id'] } }">
|
||||
<button class="btn">Finalize</button>
|
||||
</router-link>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryTicketsMissing',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [
|
||||
|
||||
],
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.get_oil_orders()
|
||||
},
|
||||
methods: {
|
||||
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/deliverydata/pending';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
436
src/pages/delivery/view.vue
Normal file
436
src/pages/delivery/view.vue
Normal file
@@ -0,0 +1,436 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md pb-5">
|
||||
<div class="text-[24px]">
|
||||
View Oil Order # {{ deliveryOrder.id }}
|
||||
</div>
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Customer
|
||||
</div>
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-span-6 ">
|
||||
<div class="flex justify-end" v-if="deliveryOrder.id ">
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: deliveryOrder.id } }">
|
||||
<button class="btn">Edit Order</button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Delivery Status
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Status
|
||||
</div>
|
||||
<div class="col-span-12">
|
||||
<div v-if="deliveryOrder.delivery_status == 0">waiting</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 1">delivered</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 2">Out for Delivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 3">Cancelled</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 4">Partial Delivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 5">misdelivery</div>
|
||||
<div v-else-if="deliveryOrder.delivery_status == 6">unknown</div>
|
||||
<div v-else></div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
Scheduled date/time
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.expected_delivery_date }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
When Called
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.when_ordered }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
Driver Name
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ deliveryOrder.driver_first_name }} {{ deliveryOrder.driver_last_name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Amount
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.customer_asked_for_fill==1">Fill</div>
|
||||
<div v-else>{{ deliveryOrder.gallons_ordered }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Payment
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.payment_type==0">Cash</div>
|
||||
<div v-else-if="deliveryOrder.payment_type==1">Credit Card</div>
|
||||
<div v-else-if="deliveryOrder.payment_type==2">Credit Card & cash</div>
|
||||
<div v-else>No Payment Type Added</div>
|
||||
</div>
|
||||
<div class="col-span-12" v-if="deliveryOrder.payment_type==1">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12" v-if="deliveryOrder.payment_type==2">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Info
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.prime==1">
|
||||
Prime Required: Yes
|
||||
</div>
|
||||
<div v-if="deliveryOrder.prime==0">
|
||||
Prime Required: No
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.same_day==1">
|
||||
Same Day: Yes
|
||||
</div>
|
||||
<div v-if="deliveryOrder.same_day==0">
|
||||
Same Day: No
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Notes
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="deliveryOrder.dispatcher_notes!='None'">
|
||||
{{ deliveryOrder.dispatcher_notes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryOrder',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: 0
|
||||
},
|
||||
|
||||
deliveryNotesDriver: [],
|
||||
|
||||
userCard: {
|
||||
date_added: '',
|
||||
user_id: '',
|
||||
card_number: '',
|
||||
last_four_digits: '',
|
||||
name_on_card: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
accepted_or_declined: '',
|
||||
main_card: '',
|
||||
},
|
||||
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
|
||||
deliveryMoney: {
|
||||
time_added: '',
|
||||
total_amount_oil: '',
|
||||
total_amount_emergency: '',
|
||||
total_amount_prime: '',
|
||||
total_amount_fee: '',
|
||||
total_amount: '',
|
||||
},
|
||||
|
||||
deliveryOrder: {
|
||||
id: '',
|
||||
customer_id: 0,
|
||||
customer_name: '',
|
||||
customer_address: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
gallons_ordered: 0,
|
||||
customer_asked_for_fill: 0,
|
||||
gallons_delivered: '',
|
||||
customer_filled: 0,
|
||||
delivery_status: 0,
|
||||
when_ordered: '',
|
||||
when_delivered: '',
|
||||
expected_delivery_date: '',
|
||||
automatic: 0,
|
||||
oil_id: 0,
|
||||
supplier_price: '',
|
||||
customer_price: '',
|
||||
customer_temperature: '',
|
||||
dispatcher_notes: '',
|
||||
prime: 0,
|
||||
same_day: 0,
|
||||
payment_type: 0,
|
||||
payment_card_id: '',
|
||||
driver_employee_id: 0,
|
||||
driver_first_name: '',
|
||||
driver_last_name: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getOilOrder(this.$route.params.id);
|
||||
this.getOilOrderMoney(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getOilOrder(this.$route.params.id);
|
||||
this.getOilOrderMoney(this.$route.params.id);
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.user.id = response.data.user_id;
|
||||
}
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCard(card_id: any) {
|
||||
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCard = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
getOilOrder(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.deliveryOrder = response.data
|
||||
this.getCustomer(this.deliveryOrder.customer_id)
|
||||
if (this.deliveryOrder.payment_type == 1) {
|
||||
this.getPaymentCard(this.deliveryOrder.payment_card_id);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
getOilOrderMoney(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/money/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.deliveryMoney = response.data
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
204
src/pages/delivery/viewstatus/cancelled.vue
Normal file
204
src/pages/delivery/viewstatus/cancelled.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../../components/pagination.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryCancelled',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/issue/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/cancelled/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
204
src/pages/delivery/viewstatus/delivered.vue
Normal file
204
src/pages/delivery/viewstatus/delivered.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../../components/pagination.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryDelivered',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delivered/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delete/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
204
src/pages/delivery/viewstatus/issue.vue
Normal file
204
src/pages/delivery/viewstatus/issue.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../../components/pagination.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryIssue',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/issue/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delete/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
204
src/pages/delivery/viewstatus/out_for_delivery.vue
Normal file
204
src/pages/delivery/viewstatus/out_for_delivery.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../../components/pagination.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryOutForDelivery',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/outfordelivery/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delete/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
204
src/pages/delivery/viewstatus/waiting.vue
Normal file
204
src/pages/delivery/viewstatus/waiting.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Oil Deliveries</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
|
||||
<th>Address</th>
|
||||
<th>Gallons</th>
|
||||
<th>Date</th>
|
||||
<th>Automatic</th>
|
||||
<th>Prime</th>
|
||||
<th>Same Day</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="oil in deliveries" :key="oil['id']"> <router-link :to="{ name: 'customerProfile', params: { id: oil['customer_id'] } }">
|
||||
<td>{{ oil['customer_name'] }} </td>
|
||||
</router-link>
|
||||
<td>
|
||||
<div v-if="oil['delivery_status'] == 0">Waiting</div>
|
||||
<div v-else-if="oil['delivery_status'] == 1">delivered</div>
|
||||
<div v-else-if="oil['delivery_status'] == 2">Out for Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 3">Cancelled</div>
|
||||
<div v-else-if="oil['delivery_status'] == 4">Partial Delivery</div>
|
||||
<div v-else-if="oil['delivery_status'] == 5">Issue</div>
|
||||
<div v-else-if="oil['delivery_status'] == 10">Finalized</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>{{ oil['customer_town'] }}</td>
|
||||
<td>{{ oil['customer_address'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['customer_asked_for_fill'] == 1">Fill</div>
|
||||
<div v-else> {{ oil['gallons_ordered'] }}</div>
|
||||
</td>
|
||||
<td>{{ oil['expected_delivery_date'] }}</td>
|
||||
<td>
|
||||
<div v-if="oil['automatic'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['prime'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="oil['same_day'] == 0">No</div>
|
||||
<div v-else>Yes</div>
|
||||
</td>
|
||||
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'deliveryOrder', params: { id: oil['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<button @click.prevent="deleteCall(oil['id'])" class="btn">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage"
|
||||
:options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../../components/pagination.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'deliveryWaiting',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
deliveries: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.deliveries = [];
|
||||
this.get_oil_orders(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_oil_orders(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/waiting/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.deliveries = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/delivery/delete/' + delivery_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted oil order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting oil order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
342
src/pages/employee/create.vue
Normal file
342
src/pages/employee/create.vue
Normal file
@@ -0,0 +1,342 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div v-if="user">
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class="w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Create a new employee</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
|
||||
|
||||
|
||||
<div class="text-[18px] mt-10 mb-10">General Info</div>
|
||||
|
||||
<!-- last name -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Last Name</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_last_name"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="text" placeholder="Last Name" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_last_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_last_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- first name -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">First Name</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_first_name"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="text" placeholder="First Name" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_first_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_first_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- employee type -->
|
||||
<div class="flex gap-5">
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Type of employee</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="employee_type" v-model="CreateEmployeeForm.basicInfo.employee_type">
|
||||
<option class="text-white" v-for="(employee, index) in employList" :key="index"
|
||||
:value="employee['value']">
|
||||
{{ employee['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-[18px] mt-10 mb-10">Employee Address</div>
|
||||
|
||||
<!-- street address -->
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Street Address</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_address" class="input input-bordered w-full max-w-xs"
|
||||
id="address" type="text" placeholder="Address" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_address.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_address.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- apt -->
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_apt" class="input input-bordered w-full max-w-xs"
|
||||
id="apt" type="text" placeholder="Apt, suite, unit, building, floor, etc" />
|
||||
</div>
|
||||
|
||||
<!-- customer_town -->
|
||||
<div class="col-span-12 md:col-span-4 mb-20 md:mb-5 ">
|
||||
<label class="block text-white text-sm font-bold mb-2">Town</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_town" class="input input-bordered w-full max-w-xs"
|
||||
id="city" type="text" placeholder="Town" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_town.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_town.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- phone number -->
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Phone Number</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_phone_number"
|
||||
class="input input-bordered w-full max-w-xs" id="phone number" type="text" placeholder="Phone Number"
|
||||
@input="acceptNumber()" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_phone_number.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_phone_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- state -->
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">State</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="employee_state" v-model="CreateEmployeeForm.basicInfo.employee_state">
|
||||
<option class="text-white" v-for="(state, index) in stateList" :key="index" :value="state['value']">
|
||||
{{ state['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_state.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_state.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- zip -->
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Zip Code</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_zip" class="input input-bordered w-full max-w-xs"
|
||||
id="zip" type="text" placeholder="Zip" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_zip.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_zip.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee BirthDay</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_birthday" class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="1945-01-01" max="2030-01-01" />
|
||||
|
||||
</div>
|
||||
<div class="text-[18px] mt-10 mb-10">Employee Dates</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee Start Date</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_start_date"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="date" min="2023-01-01" max="2030-01-01" />
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee End Date</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_end_date" class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="2023-01-01" max="2030-01-01" />
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Create Employee
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EmployeeCreate',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
stateList: [],
|
||||
employList: [],
|
||||
employee_id: '',
|
||||
CreateEmployeeForm: {
|
||||
basicInfo: {
|
||||
employee_last_name: "",
|
||||
employee_first_name: "",
|
||||
employee_town: "",
|
||||
employee_address: "",
|
||||
employee_apt: "",
|
||||
employee_zip: "",
|
||||
employee_birthday: "",
|
||||
employee_phone_number: "",
|
||||
employee_start_date: "",
|
||||
employee_end_date: "",
|
||||
employee_type: "",
|
||||
employee_state: "",
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateEmployeeForm: {
|
||||
basicInfo: {
|
||||
employee_last_name: {required, minLength: minLength(1)},
|
||||
employee_first_name: {required, minLength: minLength(1)},
|
||||
employee_town: {required, minLength: minLength(1)},
|
||||
employee_type: {required},
|
||||
employee_zip: {required, minLength: minLength(5)},
|
||||
employee_state: {required},
|
||||
employee_apt: {required},
|
||||
employee_address: {required},
|
||||
employee_birthday: {required},
|
||||
employee_phone_number: {required},
|
||||
employee_start_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getEmployeeTypeList();
|
||||
this.getStatesList();
|
||||
},
|
||||
methods: {
|
||||
acceptNumber() {
|
||||
let x = this.CreateEmployeeForm.basicInfo.employee_phone_number.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
|
||||
if (x){
|
||||
this.CreateEmployeeForm.basicInfo.employee_phone_number = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
|
||||
}
|
||||
else {
|
||||
this.CreateEmployeeForm.basicInfo.employee_phone_number = ''
|
||||
}
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
CreateItem(payload: {
|
||||
employee_last_name: string;
|
||||
employee_first_name: string;
|
||||
employee_town: string;
|
||||
employee_address: string;
|
||||
employee_zip: string;
|
||||
employee_apt: string,
|
||||
employee_birthday: string;
|
||||
employee_phone_number: string;
|
||||
employee_start_date: string,
|
||||
employee_end_date: string;
|
||||
employee_type: string;
|
||||
employee_state: string;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/create";
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.employee_id= response.data['user_id']
|
||||
this.$router.push({name: "employeeProfile", params: { id: this.employee_id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
employee_last_name: this.CreateEmployeeForm.basicInfo.employee_last_name,
|
||||
employee_first_name: this.CreateEmployeeForm.basicInfo.employee_first_name,
|
||||
employee_town: this.CreateEmployeeForm.basicInfo.employee_town,
|
||||
employee_address: this.CreateEmployeeForm.basicInfo.employee_address,
|
||||
employee_zip: this.CreateEmployeeForm.basicInfo.employee_zip,
|
||||
employee_apt: this.CreateEmployeeForm.basicInfo.employee_apt,
|
||||
employee_birthday: this.CreateEmployeeForm.basicInfo.employee_birthday,
|
||||
employee_phone_number: this.CreateEmployeeForm.basicInfo.employee_phone_number,
|
||||
employee_start_date: this.CreateEmployeeForm.basicInfo.employee_start_date,
|
||||
employee_end_date: this.CreateEmployeeForm.basicInfo.employee_end_date,
|
||||
employee_type: this.CreateEmployeeForm.basicInfo.employee_type,
|
||||
employee_state: this.CreateEmployeeForm.basicInfo.employee_state,
|
||||
};
|
||||
this.CreateItem(payload);
|
||||
},
|
||||
getEmployeeTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/employeetype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.employList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getStatesList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/states";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.stateList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
379
src/pages/employee/edit.vue
Normal file
379
src/pages/employee/edit.vue
Normal file
@@ -0,0 +1,379 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div v-if="user">
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class="w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Edit employee</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
|
||||
<div class="text-[18px] mt-10 mb-10">General Info</div>
|
||||
|
||||
<!-- first name -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">First Name</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_first_name"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="text" placeholder="First Name" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_first_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_first_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- last name -->
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Last Name</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_last_name"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="text" placeholder="Last Name" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_last_name.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_last_name.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- employee type -->
|
||||
<div class="flex gap-5">
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Type of employee</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="employee_type" v-model="CreateEmployeeForm.basicInfo.employee_type">
|
||||
<option class="text-white" v-for="(employee, index) in employList" :key="index"
|
||||
:value="employee['value']">
|
||||
{{ employee['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-[18px] mt-10 mb-10">Employee Address</div>
|
||||
|
||||
<!-- street address -->
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Street Address</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_address" class="input input-bordered w-full max-w-xs"
|
||||
id="address" type="text" placeholder="Address" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_address.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_address.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- apt -->
|
||||
<div class="col-span-12 mb-5 md:mb-5">
|
||||
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_apt" class="input input-bordered w-full max-w-xs"
|
||||
id="apt" type="text" placeholder="Apt, suite, unit, building, floor, etc" />
|
||||
</div>
|
||||
|
||||
<!-- employee_town -->
|
||||
<div class="col-span-12 md:col-span-4 mb-20 md:mb-5 ">
|
||||
<label class="block text-white text-sm font-bold mb-2">Town</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_town" class="input input-bordered w-full max-w-xs"
|
||||
id="city" type="text" placeholder="Town" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_town.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_town.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- phone number -->
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-5">
|
||||
<label class="block text-white text-sm font-bold mb-2">Phone Number</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_phone_number" @input="acceptNumber()"
|
||||
class="input input-bordered w-full max-w-xs" id="phone number" type="text" placeholder="Phone Number" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_phone_number.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_phone_number.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- state -->
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">State</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="employee_state" v-model="CreateEmployeeForm.basicInfo.employee_state">
|
||||
<option class="text-white" v-for="(state, index) in stateList" :key="index" defaultValue="state_default"
|
||||
:value="state['value']">
|
||||
{{ state['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_state.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_state.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- zip -->
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
<label class="block text-white text-sm font-bold mb-2">Zip Code</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_zip" class="input input-bordered w-full max-w-xs"
|
||||
id="zip" type="text" placeholder="Zip" />
|
||||
<span v-if="v$.CreateEmployeeForm.basicInfo.employee_zip.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateEmployeeForm.basicInfo.employee_zip.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee BirthDay</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_birthday" class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="1945-01-01" max="2030-01-01" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-[18px] mt-10 mb-10">Employee Dates</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee Start Date</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_start_date"
|
||||
class="input input-bordered w-full max-w-xs" id="title" type="date" min="2023-01-01" max="2030-01-01" />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Employee End Date</label>
|
||||
<input v-model="CreateEmployeeForm.basicInfo.employee_end_date" class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="2023-01-01" max="2030-01-01" />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Edit Employee
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EmployeeEdit',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
stateList: [],
|
||||
employList: [],
|
||||
employee_id: '',
|
||||
state_default: '',
|
||||
CreateEmployeeForm: {
|
||||
basicInfo: {
|
||||
employee_last_name: "",
|
||||
employee_first_name: "",
|
||||
employee_town: "",
|
||||
employee_address: "",
|
||||
employee_apt: "",
|
||||
employee_zip: "",
|
||||
employee_birthday: "",
|
||||
employee_phone_number: "",
|
||||
employee_start_date: "",
|
||||
employee_end_date: "",
|
||||
employee_type: "",
|
||||
employee_state: "",
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateEmployeeForm: {
|
||||
basicInfo: {
|
||||
employee_last_name: {required, minLength: minLength(1)},
|
||||
employee_first_name: {required, minLength: minLength(1)},
|
||||
employee_town: {required, minLength: minLength(1)},
|
||||
employee_type: {required},
|
||||
employee_zip: {required, minLength: minLength(5)},
|
||||
employee_state: {required},
|
||||
employee_apt: {required},
|
||||
employee_address: {required},
|
||||
employee_birthday: {required},
|
||||
employee_phone_number: {required},
|
||||
employee_start_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.getEmployee(this.$route.params.id)
|
||||
},
|
||||
mounted() {
|
||||
this.getEmployeeTypeList();
|
||||
this.getStatesList();
|
||||
this.getEmployee(this.$route.params.id)
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getEmployee(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
acceptNumber() {
|
||||
let x = this.CreateEmployeeForm.basicInfo.employee_phone_number.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
|
||||
if (x){
|
||||
this.CreateEmployeeForm.basicInfo.employee_phone_number = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
|
||||
}
|
||||
else {
|
||||
this.CreateEmployeeForm.basicInfo.employee_phone_number = ''
|
||||
}
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
EditEmployee(payload: {
|
||||
employee_last_name: string;
|
||||
employee_first_name: string;
|
||||
employee_town: string;
|
||||
employee_address: string;
|
||||
employee_zip: string;
|
||||
employee_apt: string,
|
||||
employee_birthday: string;
|
||||
employee_phone_number: string;
|
||||
employee_start_date: string,
|
||||
employee_end_date: string;
|
||||
employee_type: string;
|
||||
employee_state: string;
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/edit/" + this.employee_id;
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "employeeProfile", params: { id: this.employee_id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getEmployee (userid:any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/" + userid;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.employee_id = response.data.id
|
||||
this.CreateEmployeeForm.basicInfo.employee_last_name= response.data.employee_last_name;
|
||||
this.CreateEmployeeForm.basicInfo.employee_first_name= response.data.employee_first_name;
|
||||
this.CreateEmployeeForm.basicInfo.employee_town= response.data.employee_town;
|
||||
this.CreateEmployeeForm.basicInfo.employee_type= response.data.employee_type;
|
||||
this.CreateEmployeeForm.basicInfo.employee_state= response.data.employee_state;
|
||||
this.CreateEmployeeForm.basicInfo.employee_zip= response.data.employee_zip;
|
||||
this.CreateEmployeeForm.basicInfo.employee_apt= response.data.employee_apt;
|
||||
this.CreateEmployeeForm.basicInfo.employee_address= response.data.employee_address;
|
||||
this.CreateEmployeeForm.basicInfo.employee_birthday= response.data.employee_birthday;
|
||||
this.CreateEmployeeForm.basicInfo.employee_phone_number= response.data.employee_phone_number;
|
||||
this.CreateEmployeeForm.basicInfo.employee_start_date= response.data.employee_start_date;
|
||||
this.CreateEmployeeForm.basicInfo.employee_end_date= response.data.employee_end_date;
|
||||
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
employee_last_name: this.CreateEmployeeForm.basicInfo.employee_last_name,
|
||||
employee_first_name: this.CreateEmployeeForm.basicInfo.employee_first_name,
|
||||
employee_town: this.CreateEmployeeForm.basicInfo.employee_town,
|
||||
employee_address: this.CreateEmployeeForm.basicInfo.employee_address,
|
||||
employee_zip: this.CreateEmployeeForm.basicInfo.employee_zip,
|
||||
employee_apt: this.CreateEmployeeForm.basicInfo.employee_apt,
|
||||
employee_birthday: this.CreateEmployeeForm.basicInfo.employee_birthday,
|
||||
employee_phone_number: this.CreateEmployeeForm.basicInfo.employee_phone_number,
|
||||
employee_start_date: this.CreateEmployeeForm.basicInfo.employee_start_date,
|
||||
employee_end_date: this.CreateEmployeeForm.basicInfo.employee_end_date,
|
||||
employee_type: this.CreateEmployeeForm.basicInfo.employee_type,
|
||||
employee_state: this.CreateEmployeeForm.basicInfo.employee_state,
|
||||
};
|
||||
this.EditEmployee(payload);
|
||||
},
|
||||
getEmployeeTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/employeetype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.employList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getStatesList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/states";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.stateList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
163
src/pages/employee/home.vue
Normal file
163
src/pages/employee/home.vue
Normal file
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'employee' }">
|
||||
employees
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<router-link :to="{ name: 'employeeCreate' }">
|
||||
<button class="btn">Create Employee</button>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th>Town</th>
|
||||
<th>Phone Number</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="person in employees" :key="person['id']">
|
||||
|
||||
<td>{{ person['employee_first_name'] }} {{ person['employee_last_name'] }}</td>
|
||||
|
||||
<td>
|
||||
<div v-if="person['employee_type'] == 0">Owner</div>
|
||||
<div v-else-if="person['employee_type'] == 1">Manager</div>
|
||||
<div v-else-if="person['employee_type'] == 2">Secretary</div>
|
||||
<div v-else-if="person['employee_type'] == 3">Office</div>
|
||||
<div v-else-if="person['employee_type'] == 4">Driver</div>
|
||||
<div v-else-if="person['employee_type'] == 5">Service Tech</div>
|
||||
<div v-else-if="person['employee_type'] == 6">Contract</div>
|
||||
<div v-else-if="person['employee_type'] == 7">Cash</div>
|
||||
<div v-else-if="person['employee_type'] == 8">Driver/Tech</div>
|
||||
<div v-else></div>
|
||||
|
||||
</td>
|
||||
|
||||
<td>{{ person['employee_town'] }}</td>
|
||||
|
||||
<td>{{ person['employee_phone_number'] }}</td>
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'employeeEdit', params: { id: person['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'employeeProfile', params: { id: person['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage" :options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EmployeeHome',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
employees: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.employees = [];
|
||||
this.get_employees(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_employees(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/employee/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.employees = response.data
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
251
src/pages/employee/profile/home.vue
Normal file
251
src/pages/employee/profile/home.vue
Normal file
@@ -0,0 +1,251 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class=" w-full mt-10" v-if="loaded">
|
||||
<div class="grid grid-cols-12 gap-5 ">
|
||||
<div class="col-span-3 ">
|
||||
<img src="../../../assets/images/user_placeholder.png"
|
||||
alt="Drone Image"
|
||||
width="200"
|
||||
height="250"/>
|
||||
</div>
|
||||
<div class="col-span-9 bg-neutral">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex justify-end">
|
||||
<div class="btn">
|
||||
<router-link :to="{ name: 'employeeEdit', params: { id: employee.id } }" >
|
||||
Edit Employee
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ employee.employee_first_name }}
|
||||
{{ employee.employee_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ employee.employee_address }}
|
||||
<div v-if="employee.employee_apt != 'None'">
|
||||
{{ employee.employee_apt }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ employee.employee_town }},
|
||||
</div>
|
||||
|
||||
<div class="pr-2">
|
||||
<div v-if="employee.employee_state == '0'">Massachusetts</div>
|
||||
<div v-else-if="employee.employee_state == '1'">Rhode Island</div>
|
||||
<div v-else-if="employee.employee_state == '2'">New Hampshire</div>
|
||||
<div v-else-if="employee.employee_state == '3'">Maine</div>
|
||||
<div v-else-if="employee.employee_state == '4'">Vermont</div>
|
||||
<div v-else-if="employee.employee_state == '5'">Maine</div>
|
||||
<div v-else-if="employee.employee_state == '6'">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ employee.employee_zip }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex" v-if="employee.employee_apt !== 'None'">
|
||||
{{ employee.employee_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ employee.employee_phone_number }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="employee.employee_type == '0'">owner</div>
|
||||
<div v-else-if="employee.employee_type == '1'">manager</div>
|
||||
<div v-else-if="employee.employee_type == '2'">secretary</div>
|
||||
<div v-else-if="employee.employee_type == '3'">office</div>
|
||||
<div v-else-if="employee.employee_type == '4'">driver</div>
|
||||
<div v-else-if="employee.employee_type == '5'">tech</div>
|
||||
<div v-else-if="employee.employee_type == '6'">contract</div>
|
||||
<div v-else-if="employee.employee_type == '7'">cash</div>
|
||||
<div v-else-if="employee.employee_type == '8'">driver/tech</div>
|
||||
<div v-else>Unknown employee type</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5 mt-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex text-2xl">
|
||||
Delivery
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2">
|
||||
Total Deliverys Done: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Gallons Delivered: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Prime: 0
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2">
|
||||
Total Service Calls: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Last Service Call: 0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 bg-neutral p-5 mt-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex text-2xl">
|
||||
Service
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2">
|
||||
Total Deliverys Done: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Gallons Delivered: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Total Prime: 0
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 py-2">
|
||||
Total Service Calls: 0
|
||||
</div>
|
||||
<div class="col-span-12 py-2">
|
||||
Last Service Call: 0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../../services/auth.header'
|
||||
import Header from '../../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../../layouts/footers/footer.vue'
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'employeeProfile',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user_placeholder: '',
|
||||
user: null,
|
||||
loaded: false,
|
||||
employee: {
|
||||
id: '',
|
||||
employee_last_name: "",
|
||||
employee_first_name: "",
|
||||
employee_town: "",
|
||||
employee_address: "",
|
||||
employee_apt: "",
|
||||
employee_zip: "",
|
||||
employee_birthday: "",
|
||||
employee_phone_number: "",
|
||||
employee_start_date: "",
|
||||
employee_end_date: "",
|
||||
employee_type: '',
|
||||
employee_state:'',
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getEmployee(this.$route.params.id)
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route() {
|
||||
this.getEmployee(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.getEmployee(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
|
||||
getEmployee (userid:any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/" + userid;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
console.log(response.data)
|
||||
this.employee = response.data;
|
||||
this.loaded = true;
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
32
src/pages/employee/routes.ts
Normal file
32
src/pages/employee/routes.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
import EmployeeHome from '../employee/home.vue';
|
||||
import EmployeeCreate from "../employee/create.vue";
|
||||
import EmployeeEdit from "../employee/edit.vue";
|
||||
import EmployeeProfile from "../employee/profile/home.vue";
|
||||
|
||||
const employeeRoutes = [
|
||||
{
|
||||
path: '/employee',
|
||||
name: 'employee',
|
||||
component: EmployeeHome,
|
||||
},
|
||||
{
|
||||
path: '/employee/create',
|
||||
name: 'employeeCreate',
|
||||
component: EmployeeCreate,
|
||||
},
|
||||
{
|
||||
path: '/employee/edit/:id',
|
||||
name: 'employeeEdit',
|
||||
component: EmployeeEdit,
|
||||
},
|
||||
{
|
||||
path: '/employee/:id',
|
||||
name: 'employeeProfile',
|
||||
component: EmployeeProfile,
|
||||
},
|
||||
]
|
||||
|
||||
export default employeeRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
17
src/pages/error/Error404.vue
Normal file
17
src/pages/error/Error404.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
|
||||
<div>
|
||||
<div style="font-size: 30vh">404</div>
|
||||
|
||||
<div class="text-h2" style="opacity: 0.4">Oops. Nothing here...</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Error404',
|
||||
})
|
||||
</script>
|
||||
172
src/pages/pay/cancel.vue
Normal file
172
src/pages/pay/cancel.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
Edit Delivery
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Create Oil Delivery {{ customer_id }}
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="checkoutOil">
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Order </label>
|
||||
<div class=""></div>
|
||||
<div class=""></div>
|
||||
<div class=""></div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Create Oil Order
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PayCancel',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
customer: null,
|
||||
customer_id: null,
|
||||
stripe: null,
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
this.getStripePublishableKey();
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
this.customer_id = response.datauser_id
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
checkoutOil() {
|
||||
// Get Checkout Session ID
|
||||
fetch('http://localhost:5001/create-checkout-session', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ book_id: book.id }),
|
||||
})
|
||||
.then((result) => result.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
// Redirect to Stripe Checkout
|
||||
return this.stripe.redirectToCheckout({ sessionId: data.sessionId });
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
},
|
||||
|
||||
getStripePublishableKey() {
|
||||
fetch('http://localhost:5001/config')
|
||||
.then((result) => result.json())
|
||||
.then((data) => {
|
||||
// Initialize Stripe.js
|
||||
this.stripe = Stripe(data.publicKey);
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
446
src/pages/pay/pay_oil.vue
Normal file
446
src/pages/pay/pay_oil.vue
Normal file
@@ -0,0 +1,446 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 mb-5">
|
||||
<div class=" col-span-12 text-[24px]">
|
||||
Confirm Payment Oil Delivery {{ delivery.id }}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-12 bg-neutral mb-5">
|
||||
|
||||
<div class="col-span-12 font-bold flex pb-5 text-lg">{{ customer.account_number }}</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_address }}
|
||||
<div v-if="customer.customer_apt != 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 ">
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div class="col-span-12 py-3">
|
||||
<div v-if="delivery.delivery_status == 0"> Delivery Status: Waiting</div>
|
||||
<div v-else-if="delivery.delivery_status == 1">Delivery Status: delivered</div>
|
||||
<div v-else-if="delivery.delivery_status == 2">Delivery Status: Out for Delivery</div>
|
||||
<div v-else-if="delivery.delivery_status == 3">Delivery Status: Cancelled</div>
|
||||
<div v-else-if="delivery.delivery_status == 4">Delivery Status: Partial Delivery</div>
|
||||
<div v-else-if="delivery.delivery_status == 5">Delivery Status: Issue</div>
|
||||
<div v-else></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 py-3">Expected Delivery: {{ delivery.expected_delivery_date }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div v-for="card in credit_cards" class="col-span-12">
|
||||
|
||||
<div class="flex flex-row ">
|
||||
<div v-if="card.main_card" class="basis-1/3 p-2">
|
||||
<div class="bg-accent rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.card_number }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.security_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.card_number }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.security_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div class="col-span-12 py-3">Price / Gallon: {{ delivery.customer_price }}</div>
|
||||
<div class="col-span-12 py-3">
|
||||
<div v-if="delivery.customer_asked_for_fill == 1"> Gallons Ordered: FILL (250)</div>
|
||||
<div v-else> Gallons Ordered: {{ delivery.gallons_ordered }}</div>
|
||||
</div>
|
||||
<div class="col-span-12 py-3" v-if="delivery.prime == 1">
|
||||
Prime Fee: {{ delivery.prime }}
|
||||
</div>
|
||||
<div class="col-span-12 py-3" v-if="delivery.same_day == 1">
|
||||
Same Day: {{ delivery.same_day }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold py-5 text-lg">Total: {{ delivery.total_price }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<!-- <button class="btn" @click="checkoutOilCreditStripe()">-->
|
||||
<!-- Pay Credit Card (Stripe)-->
|
||||
<!-- </button>-->
|
||||
<button class="btn" @click="checkoutOilUpdatePayment(0)">
|
||||
Cash Payment
|
||||
</button>
|
||||
<button class="btn" @click="checkoutOilUpdatePayment(1)">
|
||||
Pay Credit Terminal
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PayOil',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
user_id: 0,
|
||||
},
|
||||
delivery: {
|
||||
id: 0,
|
||||
customer_id: 0,
|
||||
customer_name: '',
|
||||
customer_address: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
gallons_ordered: 0,
|
||||
customer_asked_for_fill: 0,
|
||||
gallons_delivered: 0,
|
||||
customer_filled: 0,
|
||||
delivery_status: 0,
|
||||
when_ordered: '',
|
||||
when_delivered: '',
|
||||
expected_delivery_date: '',
|
||||
automatic: 0,
|
||||
oil_id: 0,
|
||||
supplier_price: 0,
|
||||
customer_price: 0,
|
||||
customer_temperature: 0,
|
||||
dispatcher_notes: '',
|
||||
prime: 0,
|
||||
same_day: 0,
|
||||
payment_type: 0,
|
||||
payment_card_id: 0,
|
||||
driver_employee_id: 0,
|
||||
driver_first_name: '',
|
||||
driver_last_name: '',
|
||||
pre_charge_amount: 0,
|
||||
total_price: 0,
|
||||
|
||||
},
|
||||
credit_cards: [
|
||||
{
|
||||
id: 0,
|
||||
name_on_card: '',
|
||||
main_card: false,
|
||||
card_number: '',
|
||||
expiration_month: '',
|
||||
type_of_card: '',
|
||||
last_four_digits: '',
|
||||
expiration_year: '',
|
||||
security_number: 0,
|
||||
|
||||
}
|
||||
],
|
||||
stripe: null,
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_address: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
account_number: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getOilOrder(this.$route.params.id)
|
||||
// this.getStripePublishableKey();
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
getOilOrder(delivery_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/order/" + delivery_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.delivery = response.data;
|
||||
this.getCustomer(this.delivery.customer_id)
|
||||
this.getCreditCards(this.delivery.customer_id)
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not get oil order",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getCreditCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/' + user_id;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
|
||||
this.credit_cards = response.data
|
||||
})
|
||||
},
|
||||
getCustomer(userid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/customer/' + userid;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.customer = response.data
|
||||
})
|
||||
},
|
||||
|
||||
checkoutOilUpdateCreditStripe() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/cash/" + this.delivery.id + '/2';
|
||||
axios({
|
||||
method: "PUT",
|
||||
url: path,
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as STRIPE credit card",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not update with credit card",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
checkoutOilUpdatePayment(payment_type: number) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/delivery/cash/" + this.delivery.id + '/' + payment_type;
|
||||
axios({
|
||||
method: "PUT",
|
||||
url: path,
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
if (payment_type == 1) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as credit (bank terminal)",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
if (payment_type == 0) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as cash (COD)",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
this.$router.push({name: "customerProfile", params: {id: this.customer.id}});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not update wth cash",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// checkoutOilCreditStripe() {
|
||||
//
|
||||
// let path = import.meta.env.VITE_PAY_URL + "/pay/charge";
|
||||
// axios({
|
||||
// method: "get",
|
||||
// url: path,
|
||||
// })
|
||||
// .then((response: any) => {
|
||||
// this.checkoutOilUpdateCreditStripe();
|
||||
// // Redirect to Stripe Checkout
|
||||
// return this.stripe.redirectToCheckout({sessionId: response.data.sessionId});
|
||||
// })
|
||||
// .catch(() => {
|
||||
// notify({
|
||||
// title: "Error",
|
||||
// text: "Could not find customer",
|
||||
// type: "error",
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
|
||||
// getStripePublishableKey() {
|
||||
// let path = import.meta.env.VITE_PAY_URL + "/pay/config";
|
||||
// axios({
|
||||
// method: "get",
|
||||
// url: path,
|
||||
// })
|
||||
// .then((response: any) => {
|
||||
// this.stripe = Stripe(response.data.publicKey);
|
||||
// })
|
||||
// .catch(() => {
|
||||
// notify({
|
||||
// title: "Error",
|
||||
// text: "Could not find customer",
|
||||
// type: "error",
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
//
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
484
src/pages/pay/pay_service.vue
Normal file
484
src/pages/pay/pay_service.vue
Normal file
@@ -0,0 +1,484 @@
|
||||
<template>
|
||||
<Header/>
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 mb-5">
|
||||
<div class=" col-span-12 text-[24px]">
|
||||
Confirm Payment Service Call {{ service_id }}
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-12 bg-neutral mb-5">
|
||||
<div class="col-span-12 font-bold flex pb-5 text-lg">{{ customer.account_number }}</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_address }}
|
||||
<div v-if="customer.customer_apt != 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 ">
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div class="col-span-12 py-3">
|
||||
<div v-if="service.service_type == '0'">Service Type: General</div>
|
||||
<div v-else-if="service.service_type == '1'">Service Type: Cleaning / Tuneup</div>
|
||||
<div v-else-if="service.service_type == '2'">Service Type: No Heat</div>
|
||||
<div v-else-if="service.service_type == '3'">Service Type: Install</div>
|
||||
<div v-else-if="service.service_type == '4'">Service Type: Call Back</div>
|
||||
<div v-else-if="service.service_type == '5'">Service Type: Quote</div>
|
||||
<div v-else-if="service.service_type == '6'">Service Type: Emergency</div>
|
||||
<div v-else></div>
|
||||
</div>
|
||||
<div class="col-span-12 py-3">Tech: {{ service.tech_first_name }} {{ service.tech_last_name }}</div>
|
||||
<div class="col-span-12 py-3">Expected Service Date: {{ service.scheduled_date }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div v-for="card in credit_cards" class="col-span-12">
|
||||
|
||||
<div class="flex flex-row ">
|
||||
<div v-if="card.main_card" class="basis-1/3 p-2">
|
||||
<div class="bg-accent rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.card_number }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.security_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ card.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.card_number }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.expiration_month }}/ {{ card.expiration_year }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ card.security_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-12 mb-5 bg-neutral">
|
||||
<div class="col-span-12 py-3">Price / hour: {{ service_prices.price_service_hour }}</div>
|
||||
<div class="col-span-12 py-3" v-if="service.payment_type == 0">Pay Method: Cash (COD)</div>
|
||||
<div class="col-span-12 py-3" v-if="service.payment_type == 1">Pay Method: Credit Card</div>
|
||||
<div class="col-span-12 py-3" v-if="service.payment_type == 2">Pay Method: Stripe</div>
|
||||
<div class="col-span-12 py-3" v-if="service.payment_type == 2">Pay Method: Cash/Credit Mix</div>
|
||||
<div class="col-span-12 font-bold py-5 text-lg">Pre-Charge: 300$</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<!-- <button class="btn" @click="checkoutServiceCreditStripe()">-->
|
||||
<!-- Pay Credit Card (Stripe)-->
|
||||
<!-- </button>-->
|
||||
<button class="btn" @click="checkoutServiceUpdatePayment(0)">
|
||||
Cash Payment
|
||||
</button>
|
||||
<button class="btn" @click="checkoutServiceUpdatePayment(1)">
|
||||
Pay Credit Terminal
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PayOil',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
user_id: 0,
|
||||
},
|
||||
service_id: null,
|
||||
service: {
|
||||
id: 0,
|
||||
customer_id: 0,
|
||||
customer_last_name: '',
|
||||
customer_first_name: '',
|
||||
customer_town: '',
|
||||
customer_state: '',
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_address: '',
|
||||
status: 0,
|
||||
service_type: '',
|
||||
when_called: '',
|
||||
scheduled_date: '',
|
||||
scheduled_time: '',
|
||||
when_serviced: '',
|
||||
completed: 0,
|
||||
tech_id: 0,
|
||||
tech_first_name: '',
|
||||
tech_last_name: '',
|
||||
payment_type: 0,
|
||||
payment_card_id: 0,
|
||||
},
|
||||
service_notes: {
|
||||
service_call_id: 0,
|
||||
dispatcher_notes: '',
|
||||
dispatcher_subject: '',
|
||||
time_added: '',
|
||||
dispatcher_id: 0,
|
||||
dispatcher_name: '',
|
||||
},
|
||||
service_prices: {
|
||||
id: 0,
|
||||
price_service_hour: 0,
|
||||
price_emergency_service_hour: 0,
|
||||
price_emergency_call: 0,
|
||||
price_out_of_oil: 0,
|
||||
price_prime: 0,
|
||||
price_same_day: 0,
|
||||
price_cleaning: 0,
|
||||
date: '',
|
||||
|
||||
},
|
||||
credit_cards: [
|
||||
{
|
||||
id: 0,
|
||||
name_on_card: '',
|
||||
main_card: false,
|
||||
card_number: '',
|
||||
expiration_month: '',
|
||||
type_of_card: '',
|
||||
last_four_digits: '',
|
||||
expiration_year: '',
|
||||
security_number: 0,
|
||||
}
|
||||
],
|
||||
stripe: null,
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_address: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
account_number: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus();
|
||||
this.getServiceOrder(this.$route.params.id);
|
||||
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.getServicePrices();
|
||||
// this.getStripePublishableKey();
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
},
|
||||
getServiceOrder(service_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/" + service_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.service = response.data;
|
||||
this.getCustomer(this.service.customer_id)
|
||||
this.getCreditCards(this.service.customer_id)
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not get service order",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getServicePrices() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/admin/service/get";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.service_prices = response.data;
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not get service order",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getServiceOrderNotes(service_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/call/notes" + service_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.service = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not get service order",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getCreditCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/payment/cards/' + user_id;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.credit_cards = response.data
|
||||
})
|
||||
},
|
||||
getCustomer(userid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/customer/' + userid;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.customer = response.data
|
||||
})
|
||||
},
|
||||
checkoutServiceUpdateCreditStripe() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/cash/" + this.service.id + '/2';
|
||||
axios({
|
||||
method: "PUT",
|
||||
url: path,
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as STRIPE credit card",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not update with credit card Stripe",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
checkoutServiceUpdatePayment(payment_type: number) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/paymenttype/" + this.service.id + '/' + payment_type;
|
||||
axios({
|
||||
method: "PUT",
|
||||
url: path,
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
if (payment_type == 1) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as credit (bank terminal)",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
if (payment_type == 0) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "marked payment as cash (COD)",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
|
||||
this.$router.push({name: "customerProfile", params: {id: this.customer.id}});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not update wth cash",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// checkoutServiceCreditStripe() {
|
||||
//
|
||||
// let path = import.meta.env.VITE_PAY_URL + "/pay/charge";
|
||||
// axios({
|
||||
// method: "get",
|
||||
// url: path,
|
||||
// })
|
||||
// .then((response: any) => {
|
||||
// this.checkoutServiceUpdateCreditStripe();
|
||||
// // Redirect to Stripe Checkout
|
||||
// return this.stripe.redirectToCheckout({sessionId: response.data.sessionId});
|
||||
// })
|
||||
// .catch(() => {
|
||||
// notify({
|
||||
// title: "Error",
|
||||
// text: "Could not find customer",
|
||||
// type: "error",
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
//
|
||||
// getStripePublishableKey() {
|
||||
// let path = import.meta.env.VITE_PAY_URL + "/pay/config";
|
||||
// axios({
|
||||
// method: "get",
|
||||
// url: path,
|
||||
// })
|
||||
// .then((response: any) => {
|
||||
// this.stripe = Stripe(response.data.publicKey);
|
||||
// })
|
||||
//
|
||||
// },
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
33
src/pages/pay/routes.ts
Normal file
33
src/pages/pay/routes.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
import PayOil from '../pay/pay_oil.vue';
|
||||
import PayService from "../pay/pay_service.vue";
|
||||
import PaySuccess from "../pay/success.vue";
|
||||
import PayCancel from "../pay/cancel.vue";
|
||||
|
||||
|
||||
const payRoutes = [
|
||||
{
|
||||
path: '/pay/service/:id',
|
||||
name: 'payService',
|
||||
component: PayService,
|
||||
},
|
||||
{
|
||||
path: '/pay/oil/:id',
|
||||
name: 'payOil',
|
||||
component: PayOil,
|
||||
},
|
||||
{
|
||||
path: '/pay/success',
|
||||
name: 'paySuccess',
|
||||
component: PaySuccess,
|
||||
},
|
||||
{
|
||||
path: '/pay/cancel',
|
||||
name: 'payCancel',
|
||||
component: PayCancel,
|
||||
},
|
||||
]
|
||||
|
||||
export default payRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
176
src/pages/pay/success.vue
Normal file
176
src/pages/pay/success.vue
Normal file
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'deliveryEdit', params: { id: oil['id'] } }">
|
||||
Edit Delivery
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Create Oil Delivery {{ customer_id }}
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="checkoutOil">
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Order </label>
|
||||
<div class=""></div>
|
||||
<div class=""></div>
|
||||
<div class=""></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Create Oil Order
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PaySuccess',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: null,
|
||||
customer: null,
|
||||
customer_id: null,
|
||||
stripe: null,
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateOilOrderForm: {
|
||||
basicInfo: {
|
||||
gallons_ordered: {required, minLength: minLength(1)},
|
||||
expected_delivery_date: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
this.getStripePublishableKey();
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
this.customer_id = response.data.user_id;
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
checkoutOil() {
|
||||
// Get Checkout Session ID
|
||||
fetch('http://localhost:5001/create-checkout-session', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ book_id: book.id }),
|
||||
})
|
||||
.then((result) => result.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
// Redirect to Stripe Checkout
|
||||
return this.stripe.redirectToCheckout({ sessionId: data.sessionId });
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
},
|
||||
|
||||
getStripePublishableKey() {
|
||||
fetch('http://localhost:5001/config')
|
||||
.then((result) => result.json())
|
||||
.then((data) => {
|
||||
// Initialize Stripe.js
|
||||
this.stripe = Stripe(data.publicKey);
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
400
src/pages/service/create.vue
Normal file
400
src/pages/service/create.vue
Normal file
@@ -0,0 +1,400 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar />
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex pb-5 text-lg">{{customer.account_number}}</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Service Category</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="customer_state" v-model="CreateServiceOrderForm.basicInfo.type_of_service">
|
||||
<option class="text-white" v-for="(cat, index) in serviceList" :key="index" :value="cat['value']">
|
||||
{{ cat['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.type_of_service.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.type_of_service.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label class="form-control w-full max-w-xs">
|
||||
<div class="label">
|
||||
<span class="label-text">Subject</span>
|
||||
</div>
|
||||
<input type="text" placeholder="Type here" class="input input-bordered w-full max-w-xs"
|
||||
v-model="CreateServiceOrderForm.basicInfo.dispatcher_subject_taken" />
|
||||
</label>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-control">
|
||||
<div class="label">
|
||||
<span class="label-text">What is the issue</span>
|
||||
</div>
|
||||
<textarea class="textarea textarea-bordered h-24" placeholder="Describe the issue for the service tech .."
|
||||
v-model="CreateServiceOrderForm.basicInfo.dispatcher_notes_taken"></textarea>
|
||||
</label>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expected Service Date </label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.date_scheduled" class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="2023-01-01" max="2030-01-01" />
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.date_scheduled.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.date_scheduled.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Service Tech</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example" id="customer_state"
|
||||
v-model="CreateServiceOrderForm.basicInfo.service_tech">
|
||||
<option class="text-white" v-for="(tech, index) in serviceTechsList" :key="index" :value="tech['id']">
|
||||
{{ tech['employee_last_name'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.service_tech.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.service_tech.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bg-neutral">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Cash</label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.cash"
|
||||
class="checkbox"
|
||||
id="cash"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Credit </label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.credit"
|
||||
class="checkbox"
|
||||
id="Credit"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Cards Payment</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="userCards"
|
||||
v-model="CreateServiceOrderForm.basicInfo.userCards">
|
||||
<option class="text-white" v-for="(card, index) in userCards"
|
||||
:key="index"
|
||||
:value="card['id']">
|
||||
{{ card['type_of_card'] }} {{ card['card_number'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Create Service Call
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ServiceCreate',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
},
|
||||
serviceList: [],
|
||||
serviceTechsList: [],
|
||||
userCards: [],
|
||||
service_id: 0,
|
||||
CreateServiceOrderForm: {
|
||||
basicInfo: {
|
||||
type_of_service: '',
|
||||
dispatcher_notes_taken: '',
|
||||
dispatcher_subject_taken: '',
|
||||
date_scheduled: '',
|
||||
service_tech: '',
|
||||
userCards: [],
|
||||
credit: false,
|
||||
cash: false,
|
||||
credit_card_id: 0,
|
||||
},
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
account_number: '',
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateServiceOrderForm: {
|
||||
basicInfo: {
|
||||
type_of_service: {required},
|
||||
dispatcher_notes_taken: {required, minLength: minLength(10)},
|
||||
dispatcher_subject_taken: {required, minLength: minLength(10)},
|
||||
date_scheduled: {required},
|
||||
service_tech: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.getServiceTypeList()
|
||||
this.getServiceTechsList()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getCustomer(this.$route.params.id);
|
||||
this.getPaymentCards(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getCustomer(this.$route.params.id)
|
||||
this.getPaymentCards(this.$route.params.id);
|
||||
},
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
console.log(this.customer)
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/cards/"+ user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCards = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
CreateServiceOrder(payload: {
|
||||
dispatcher_notes_taken: string,
|
||||
dispatcher_subject_taken: string,
|
||||
date_scheduled: string,
|
||||
type_of_service: string,
|
||||
dispatcher_id: number,
|
||||
cash: boolean,
|
||||
credit: boolean,
|
||||
credit_card_id: any,
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/create/" + this.customer.id;
|
||||
axios({
|
||||
method: "post",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.service_id = response.data.service_id
|
||||
this.$router.push({name: "payService", params: { id: this.service_id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
dispatcher_notes_taken: this.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken,
|
||||
dispatcher_subject_taken: this.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken,
|
||||
date_scheduled: this.CreateServiceOrderForm.basicInfo.date_scheduled,
|
||||
type_of_service: this.CreateServiceOrderForm.basicInfo.type_of_service,
|
||||
dispatcher_id: this.user.user_id,
|
||||
cash: this.CreateServiceOrderForm.basicInfo.cash,
|
||||
credit: this.CreateServiceOrderForm.basicInfo.credit,
|
||||
credit_card_id: this.CreateServiceOrderForm.basicInfo.userCards,
|
||||
|
||||
};
|
||||
this.CreateServiceOrder(payload);
|
||||
},
|
||||
|
||||
getServiceTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/servicetype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.serviceList = response.data;
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
|
||||
getServiceTechsList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/techs";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.serviceTechsList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
501
src/pages/service/edit.vue
Normal file
501
src/pages/service/edit.vue
Normal file
@@ -0,0 +1,501 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'customer' }">
|
||||
Customers
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md p-6 ">
|
||||
<div class="text-[24px]">Edit Service Call
|
||||
</div>
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_first_name }}
|
||||
{{ customer.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12
|
||||
|
||||
|
||||
font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="rounded-md px-8 pt-6 pb-8 mb-4 w-full" enctype="multipart/form-data" @submit.prevent="onSubmit">
|
||||
<div class="bg-neutral">
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Cash</label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.cash"
|
||||
class="checkbox"
|
||||
id="cash"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0 gap-10">
|
||||
<label class="block text-white text-sm font-bold cursor-pointer label">Credit </label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.card"
|
||||
class="checkbox"
|
||||
id="Credit"
|
||||
type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Customer Cards Payment</label>
|
||||
<select
|
||||
class="select select-bordered w-full max-w-xs"
|
||||
aria-label="Default select example" id="userCards"
|
||||
v-model="CreateServiceOrderForm.basicInfo.userCards">
|
||||
<option class="text-white" v-for="(card, index) in userCards"
|
||||
:key="index"
|
||||
:value="card['id']">
|
||||
{{ card['type_of_card'] }} {{ card['card_number'] }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 md:col-span-4 mb-5 md:mb-0">
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Service Category</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="customer_state" v-model="CreateServiceOrderForm.basicInfo.type_of_service">
|
||||
<option class="text-white" v-for="(cat, index) in serviceList" :key="index" :value="cat['value']">
|
||||
{{ cat['text'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.type_of_service.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.type_of_service.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<label class="form-control w-full max-w-xs">
|
||||
<div class="label">
|
||||
<span class="label-text">Subject</span>
|
||||
</div>
|
||||
<input type="text" placeholder="Type here" class="input input-bordered w-full max-w-xs"
|
||||
v-model="CreateServiceOrderForm.basicInfo.dispatcher_subject_taken"/>
|
||||
</label>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-control">
|
||||
<div class="label">
|
||||
<span class="label-text">What is the issue</span>
|
||||
</div>
|
||||
<textarea class="textarea textarea-bordered h-24" placeholder="Describe the issue for the service tech .."
|
||||
v-model="CreateServiceOrderForm.basicInfo.dispatcher_notes_taken"></textarea>
|
||||
</label>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken.$error"
|
||||
class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Expected Service Date </label>
|
||||
<input v-model="CreateServiceOrderForm.basicInfo.date_scheduled"
|
||||
class="input input-bordered w-full max-w-xs"
|
||||
id="title" type="date" min="2023-01-01" max="2030-01-01"/>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.date_scheduled.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.date_scheduled.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 mb-4">
|
||||
<label class="block text-white text-sm font-bold mb-2">Service Tech</label>
|
||||
<select class="select select-bordered w-full max-w-xs" aria-label="Default select example"
|
||||
id="customer_state"
|
||||
v-model="CreateServiceOrderForm.basicInfo.service_tech_id">
|
||||
<option class="text-white" v-for="(tech, index) in serviceTechsList" :key="index" :value="tech['id']">
|
||||
{{ tech['employee_last_name'] }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-if="v$.CreateServiceOrderForm.basicInfo.service_tech_id.$error" class="text-red-600 text-center">
|
||||
{{ v$.CreateServiceOrderForm.basicInfo.type_of_service.$errors[0].$message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-span-12 md:col-span-12 flex mt-5 mb-5">
|
||||
<button class="btn">
|
||||
Edit Service Call
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ServiceEdit',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: 0
|
||||
},
|
||||
serviceList: [],
|
||||
serviceTechsList: [],
|
||||
userCards: [],
|
||||
userCard: {
|
||||
date_added: '',
|
||||
user_id: '',
|
||||
card_number: '',
|
||||
last_four_digits: '',
|
||||
name_on_card: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
accepted_or_declined: '',
|
||||
main_card: '',
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
serviceCall: {
|
||||
id: 0,
|
||||
tech_id: 0,
|
||||
customer_id: 0,
|
||||
type_of_service: 0,
|
||||
dispatcher_notes_taken: '',
|
||||
dispatcher_subject_taken: '',
|
||||
date_scheduled: '',
|
||||
payment_type: 0,
|
||||
payment_card_id: 0,
|
||||
same_day: 0,
|
||||
|
||||
},
|
||||
CreateServiceOrderForm: {
|
||||
basicInfo: {
|
||||
type_of_service: '',
|
||||
dispatcher_notes_taken: '',
|
||||
dispatcher_subject_taken: '',
|
||||
date_scheduled: '',
|
||||
service_tech_id: '',
|
||||
userCards: [],
|
||||
credit_card_id: 0,
|
||||
cash: false,
|
||||
card: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateServiceOrderForm: {
|
||||
basicInfo: {
|
||||
type_of_service: {required},
|
||||
dispatcher_notes_taken: {required, minLength: minLength(10)},
|
||||
dispatcher_subject_taken: {required, minLength: minLength(10)},
|
||||
date_scheduled: {required},
|
||||
service_tech_id: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
this.getServiceTypeList()
|
||||
this.getServiceTechsList()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getServiceCall(this.$route.params.id);
|
||||
this.getServiceCallNotes(this.$route.params.id)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getServiceCall(this.$route.params.id)
|
||||
this.getServiceCallNotes(this.$route.params.id)
|
||||
this.getServiceTechsList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.user.id = response.data.user_id;
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
this.getPaymentCards(this.serviceCall.customer_id);
|
||||
if (this.serviceCall.payment_type == 1) {
|
||||
this.getPaymentCard(this.serviceCall.payment_card_id)
|
||||
}
|
||||
if (this.serviceCall.payment_type == 2) {
|
||||
this.getPaymentCard(this.serviceCall.payment_card_id)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCard = response.data;
|
||||
|
||||
this.CreateServiceOrderForm.basicInfo.userCards = response.data.id
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
getPaymentCards(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/cards/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCards = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
// gets the item from paramater router
|
||||
getServiceCall(serviceid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/" + serviceid;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.CreateServiceOrderForm.basicInfo.type_of_service = response.data.service_type;
|
||||
this.CreateServiceOrderForm.basicInfo.date_scheduled = response.data.scheduled_date;
|
||||
this.CreateServiceOrderForm.basicInfo.service_tech_id = response.data.tech_id;
|
||||
|
||||
this.CreateServiceOrderForm.basicInfo.date_scheduled = response.data.scheduled_date;
|
||||
|
||||
|
||||
this.serviceCall = response.data
|
||||
|
||||
if (response.data.payment_type == 0) {
|
||||
this.CreateServiceOrderForm.basicInfo.card = false
|
||||
this.CreateServiceOrderForm.basicInfo.cash = true
|
||||
}
|
||||
if (response.data.payment_type == 1) {
|
||||
this.CreateServiceOrderForm.basicInfo.card = true
|
||||
this.CreateServiceOrderForm.basicInfo.cash = false
|
||||
}
|
||||
if (response.data.payment_type == 2) {
|
||||
this.CreateServiceOrderForm.basicInfo.card = true
|
||||
this.CreateServiceOrderForm.basicInfo.cash = true
|
||||
}
|
||||
this.getCustomer(this.serviceCall.customer_id);
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getServiceCallNotes(serviceid: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/call/notes/" + serviceid;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken = response.data.dispatcher_notes;
|
||||
this.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken = response.data.dispatcher_subject;
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
EditServiceOrder(payload: {
|
||||
dispatcher_notes_taken: string;
|
||||
dispatcher_subject_taken: string;
|
||||
date_scheduled: string;
|
||||
type_of_service: string,
|
||||
tech_id: number,
|
||||
cash: boolean,
|
||||
credit: boolean,
|
||||
credit_card_id: any,
|
||||
}) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/edit/" + this.serviceCall.id;
|
||||
axios({
|
||||
method: "put",
|
||||
url: path,
|
||||
data: payload,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.$router.push({name: "serviceCall", params: { id: this.serviceCall.id }});
|
||||
}
|
||||
if (response.data.error) {
|
||||
this.$router.push("/");
|
||||
}
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
let payload = {
|
||||
dispatcher_notes_taken: this.CreateServiceOrderForm.basicInfo.dispatcher_notes_taken,
|
||||
dispatcher_subject_taken: this.CreateServiceOrderForm.basicInfo.dispatcher_subject_taken,
|
||||
date_scheduled: this.CreateServiceOrderForm.basicInfo.date_scheduled,
|
||||
type_of_service: this.CreateServiceOrderForm.basicInfo.type_of_service,
|
||||
tech_id: this.serviceCall.tech_id,
|
||||
|
||||
cash: this.CreateServiceOrderForm.basicInfo.cash,
|
||||
credit: this.CreateServiceOrderForm.basicInfo.card,
|
||||
credit_card_id: this.CreateServiceOrderForm.basicInfo.userCards,
|
||||
|
||||
};
|
||||
this.EditServiceOrder(payload);
|
||||
},
|
||||
|
||||
getServiceTypeList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/query/servicetype";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.serviceList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
getServiceTechsList() {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/employee/techs";
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.serviceTechsList = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
216
src/pages/service/home.vue
Normal file
216
src/pages/service/home.vue
Normal file
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10 ">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<div class="flex start">Service Calls</div>
|
||||
<table class="table">
|
||||
<!-- head -->
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Customer Name</th>
|
||||
<th>Scheduled Date</th>
|
||||
<th>Status</th>
|
||||
<th>Town</th>
|
||||
<th>Service Type</th>
|
||||
<th>Initial Call</th>
|
||||
<th>Tech Name</th>
|
||||
<th>Payment Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr v-for="service in service_calls" :key="service['id']">
|
||||
<td>
|
||||
<router-link :to="{ name: 'customerProfile', params: { id: person['id'] } }">
|
||||
{{ person['customer_first_name'] }} {{ person['customer_last_name'] }}
|
||||
</router-link>
|
||||
</td>
|
||||
<td>
|
||||
{{ service['scheduled_date'] }}
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="service['status'] == 0">Waiting/not paid</div>
|
||||
<div v-else-if="service['status'] == 1">Paid /waiting</div>
|
||||
<div v-else-if="service['status'] == 2">Scheduled Today</div>
|
||||
<div v-else-if="service['status'] == 3">Completed/Unpaid</div>
|
||||
<div v-else-if="service['status'] == 4">Completed/Paid</div>
|
||||
|
||||
<div v-else></div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ service['customer_town'] }}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<div v-if="service['service_type'] == 0">General</div>
|
||||
<div v-else-if="service['service_type'] == 1">Cleaning / Tuneup</div>
|
||||
<div v-else-if="service['service_type'] == 2">No Heat</div>
|
||||
<div v-else-if="service['service_type'] == 3">Install</div>
|
||||
<div v-else-if="service['service_type'] == 4">Call Back</div>
|
||||
<div v-else-if="service['service_type'] == 5">Quote</div>
|
||||
<div v-else-if="service['service_type'] == 6" class="text-red-700 font-bold">Emergency</div>
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td>
|
||||
{{ service['when_called'] }}
|
||||
</td>
|
||||
<td>
|
||||
{{ service['tech_first_name'] }} {{ service['tech_last_name'] }}
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="service['payment_type'] == 0">Cash C.O.D</div>
|
||||
<div v-else-if="service['payment_type'] == 1">Credit</div>
|
||||
<div v-else-if="service['payment_type'] == 2">Stripe</div>
|
||||
<div v-else-if="service['payment_type'] == 3">Cash/Credit</div>
|
||||
|
||||
<div v-else></div>
|
||||
</td>
|
||||
<td class="flex gap-5">
|
||||
<router-link :to="{ name: 'serviceCall', params: { id: service['id'] } }">
|
||||
<button class="btn">View</button>
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'serviceEdit', params: { id: service['id'] } }">
|
||||
<button class="btn">Edit</button>
|
||||
</router-link>
|
||||
|
||||
<button @click.prevent="deleteCall(service['id'])" class="btn">Delete</button>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="flex justify-center" v-if="recordsLength > 9">
|
||||
<pagination @paginate="getPage" :records="recordsLength" v-model="page" :per-page="perPage" :options="options">
|
||||
</pagination>
|
||||
<div class="flex justify-center mb-10"> {{ recordsLength }} items Found</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import PaginationComp from '../../components/pagination.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ServiceCall',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
token: null,
|
||||
user: null,
|
||||
service_calls: [],
|
||||
page: 1,
|
||||
perPage: 50,
|
||||
recordsLength: 0,
|
||||
options: {
|
||||
edgeNavigation: false,
|
||||
format: false,
|
||||
template: PaginationComp
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
mounted() {
|
||||
this.getPage(this.page)
|
||||
|
||||
},
|
||||
methods: {
|
||||
getPage: function (page: any) {
|
||||
// we simulate an api call that fetch the records from a backend
|
||||
this.service_calls = [];
|
||||
this.get_service_call(page)
|
||||
},
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.user = null
|
||||
})
|
||||
},
|
||||
get_service_call(page: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/service/all/' + page;
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
this.service_calls = response.data
|
||||
})
|
||||
},
|
||||
deleteCall(service_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/service/delete/' + service_id;
|
||||
axios({
|
||||
method: 'delete',
|
||||
url: path,
|
||||
headers: authHeader(),
|
||||
}).then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
notify({
|
||||
title: "Success",
|
||||
text: "deleted service order",
|
||||
type: "success",
|
||||
});
|
||||
this.getPage(this.page)
|
||||
} else {
|
||||
notify({
|
||||
title: "Failure",
|
||||
text: "error deleting service order",
|
||||
type: "success",
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
32
src/pages/service/routes.ts
Normal file
32
src/pages/service/routes.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
import ServiceHome from '../service/home.vue';
|
||||
import ServiceCreate from '../service/create.vue';
|
||||
import ServiceEdit from '../service/edit.vue';
|
||||
import ServiceCall from '../service/view.vue';
|
||||
|
||||
const serviceRoutes = [
|
||||
{
|
||||
path: '/service',
|
||||
name: 'service',
|
||||
component: ServiceHome,
|
||||
},
|
||||
{
|
||||
path: '/service/:id',
|
||||
name: 'serviceCall',
|
||||
component: ServiceCall,
|
||||
},
|
||||
{
|
||||
path: '/service/create/:id',
|
||||
name: 'serviceCreate',
|
||||
component: ServiceCreate,
|
||||
},
|
||||
{
|
||||
path: '/service/edit/:id',
|
||||
name: 'serviceEdit',
|
||||
component: ServiceEdit,
|
||||
},
|
||||
]
|
||||
|
||||
export default serviceRoutes
|
||||
//sourceMappingURL=index.ts.map
|
||||
423
src/pages/service/view.vue
Normal file
423
src/pages/service/view.vue
Normal file
@@ -0,0 +1,423 @@
|
||||
<template>
|
||||
<Header/>
|
||||
|
||||
<div class="flex">
|
||||
<div class="">
|
||||
<SideBar/>
|
||||
</div>
|
||||
<div class=" w-full px-10">
|
||||
<div class="text-sm breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<router-link :to="{ name: 'home' }">
|
||||
Home
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'service' }">
|
||||
Service Home
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 rounded-md pb-5">
|
||||
<div class="text-[24px]">
|
||||
View Service Call # {{ serviceCall.id }}
|
||||
</div>
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Customer
|
||||
</div>
|
||||
<div class="col-span-6 bg-neutral p-5">
|
||||
<div class="grid grid-cols-12">
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ serviceCall.customer_first_name }}
|
||||
{{ serviceCall.customer_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_town }},
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
<div v-if="customer.customer_state == 0">Massachusetts</div>
|
||||
<div v-else-if="customer.customer_state == 1">Rhode Island</div>
|
||||
<div v-else-if="customer.customer_state == 2">New Hampshire</div>
|
||||
<div v-else-if="customer.customer_state == 3">Maine</div>
|
||||
<div v-else-if="customer.customer_state == 4">Vermont</div>
|
||||
<div v-else-if="customer.customer_state == 5">Connecticut</div>
|
||||
<div v-else-if="customer.customer_state == 6">New York</div>
|
||||
<div v-else>Unknown state</div>
|
||||
</div>
|
||||
<div class="pr-2">
|
||||
{{ customer.customer_zip }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12 font-bold flex" v-if="customer.customer_apt !== 'None'">
|
||||
{{ customer.customer_apt }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
<div v-if="customer.customer_home_type == 0">Residential</div>
|
||||
<div v-else-if="customer.customer_home_type == 1">apartment</div>
|
||||
<div v-else-if="customer.customer_home_type == 2">condo</div>
|
||||
<div v-else-if="customer.customer_home_type == 3">commercial</div>
|
||||
<div v-else-if="customer.customer_home_type == 4">business</div>
|
||||
<div v-else-if="customer.customer_home_type == 5">construction</div>
|
||||
<div v-else-if="customer.customer_home_type == 6">container</div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold flex">
|
||||
{{ customer.customer_phone_number }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 ">
|
||||
<div class="flex justify-end" v-if="serviceCall.id ">
|
||||
<router-link :to="{ name: 'serviceEdit', params: { id: serviceCall.id } }">
|
||||
<button class="btn">Edit Service Call</button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-6">
|
||||
<div class="col-span-12 font-bold">
|
||||
Service Status
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Service Category
|
||||
|
||||
</div>
|
||||
<div class="col-span-12">
|
||||
<div v-if="serviceCall.service_type == 0">General</div>
|
||||
<div v-else-if="serviceCall.service_type == 1">Cleaning / Tuneup</div>
|
||||
<div v-else-if="serviceCall.service_type == 2">No Heat</div>
|
||||
<div v-else-if="serviceCall.service_type == 3">Install</div>
|
||||
<div v-else-if="serviceCall.service_type == 4">Call Back</div>
|
||||
<div v-else-if="serviceCall.service_type == 5">Quote</div>
|
||||
<div v-else-if="serviceCall.service_type == 6">Emergency</div>
|
||||
<div v-else></div>
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
Scheduled date/time
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ serviceCall.scheduled_date }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
Tech Name
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ serviceCall.tech_first_name }} {{ serviceCall.tech_last_name }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
When Called
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ serviceCall.when_called }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Dispatcher Notes
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Subject
|
||||
</div>
|
||||
<div class="col-span-12">
|
||||
{{ serviceCallNotes.dispatcher_subject }}
|
||||
</div>
|
||||
<div class="col-span-12 font-bold mt-10">
|
||||
Notes
|
||||
</div>
|
||||
<div class="col-span-12 ">
|
||||
{{ serviceCallNotes.dispatcher_notes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Amount
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="serviceCall.customer_asked_for_fill==1">Fill</div>
|
||||
<div v-else>{{ serviceCall.gallons_ordered }}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-span-6 mt-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
Payment
|
||||
</div>
|
||||
<div class="grid grid-cols-12 bg-neutral p-5">
|
||||
<div class="col-span-12 font-bold">
|
||||
<div v-if="serviceCall.payment_type==0">Cash</div>
|
||||
<div v-else-if="serviceCall.payment_type==1">Credit Card</div>
|
||||
<div v-else-if="serviceCall.payment_type==2">Credit Card & cash</div>
|
||||
<div v-else>No Payment Type Added</div>
|
||||
</div>
|
||||
<div class="col-span-12" v-if="serviceCall.payment_type==1">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-12" v-if="serviceCall.payment_type==2">
|
||||
<div class="flex">
|
||||
<div class="basis-1/3 p-2">
|
||||
<div class="bg-neutral rounded-md border-2 ">
|
||||
<div class="flex p-3">
|
||||
{{ userCard.type_of_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.name_on_card }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
****-****-****-{{ userCard.last_four_digits }}
|
||||
</div>
|
||||
<div class="flex p-1 pl-4">
|
||||
{{ userCard.expiration_month }}/ {{ userCard.expiration_year }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer/>
|
||||
</template>
|
||||
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import axios from 'axios'
|
||||
import authHeader from '../../services/auth.header'
|
||||
import Header from '../../layouts/headers/headerauth.vue'
|
||||
import SideBar from '../../layouts/sidebar/sidebar.vue'
|
||||
import Footer from '../../layouts/footers/footer.vue'
|
||||
import useValidate from "@vuelidate/core";
|
||||
import {notify} from "@kyvg/vue3-notification"
|
||||
import {minLength, required} from "@vuelidate/validators";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'serviceCall',
|
||||
|
||||
components: {
|
||||
Header,
|
||||
SideBar,
|
||||
Footer,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
v$: useValidate(),
|
||||
user: {
|
||||
id: 0
|
||||
},
|
||||
serviceTech: [],
|
||||
userCard: {
|
||||
date_added: '',
|
||||
user_id: '',
|
||||
card_number: '',
|
||||
last_four_digits: '',
|
||||
name_on_card: '',
|
||||
expiration_month: '',
|
||||
expiration_year: '',
|
||||
type_of_card: '',
|
||||
security_number: '',
|
||||
accepted_or_declined: '',
|
||||
main_card: '',
|
||||
|
||||
},
|
||||
customer: {
|
||||
id: 0,
|
||||
user_id: 0,
|
||||
customer_first_name: '',
|
||||
customer_last_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_home_type: 0,
|
||||
customer_phone_number: '',
|
||||
},
|
||||
serviceCallNotes: {
|
||||
service_call_id: '',
|
||||
dispatcher_notes: '',
|
||||
dispatcher_subject: '',
|
||||
time_added: '',
|
||||
dispatcher_id: '',
|
||||
dispatcher_name: '',
|
||||
},
|
||||
serviceCall: {
|
||||
id: 0,
|
||||
customer_id: 0,
|
||||
customer_last_name: '',
|
||||
customer_first_name: '',
|
||||
customer_town: '',
|
||||
customer_state: 0,
|
||||
customer_zip: '',
|
||||
customer_apt: '',
|
||||
customer_address: '',
|
||||
status: 0,
|
||||
service_type: 0,
|
||||
when_called: '',
|
||||
scheduled_date: '',
|
||||
scheduled_time: '',
|
||||
when_serviced: '',
|
||||
completed: 0,
|
||||
tech_id: 0,
|
||||
tech_first_name: '',
|
||||
tech_last_name: '',
|
||||
payment_type: 0,
|
||||
payment_card_id: 0,
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
validations() {
|
||||
return {
|
||||
CreateServiceOrderForm: {
|
||||
basicInfo: {
|
||||
type_of_service: {required},
|
||||
dispatcher_notes_taken: {required, minLength: minLength(10)},
|
||||
dispatcher_subject_taken: {required, minLength: minLength(10)},
|
||||
date_scheduled: {required},
|
||||
service_tech_id: {required},
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.userStatus()
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getServiceCall(this.$route.params.id);
|
||||
this.getServiceCallNotes(this.$route.params.id);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getServiceCall(this.$route.params.id);
|
||||
this.getServiceCallNotes(this.$route.params.id);
|
||||
},
|
||||
|
||||
methods: {
|
||||
userStatus() {
|
||||
let path = import.meta.env.VITE_BASE_URL + '/auth/whoami';
|
||||
axios({
|
||||
method: 'get',
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data.ok) {
|
||||
this.user = response.data.user;
|
||||
this.user.id = response.data.user_id;
|
||||
}
|
||||
})
|
||||
},
|
||||
getCustomer(user_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/customer/" + user_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.customer = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
notify({
|
||||
title: "Error",
|
||||
text: "Could not find customer",
|
||||
type: "error",
|
||||
});
|
||||
});
|
||||
},
|
||||
getPaymentCard(card_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/payment/card/" + card_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
})
|
||||
.then((response: any) => {
|
||||
this.userCard = response.data;
|
||||
})
|
||||
.catch(() => {
|
||||
});
|
||||
},
|
||||
|
||||
getServiceCall(service_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/call/" + service_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.serviceCall = response.data
|
||||
this.getCustomer(this.serviceCall.customer_id)
|
||||
if (this.serviceCall.payment_type != null) {
|
||||
this.getPaymentCard(this.serviceCall.payment_card_id);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getServiceCallNotes(service_id: any) {
|
||||
let path = import.meta.env.VITE_BASE_URL + "/service/call/notes/" + service_id;
|
||||
axios({
|
||||
method: "get",
|
||||
url: path,
|
||||
withCredentials: true,
|
||||
headers: authHeader(),
|
||||
})
|
||||
.then((response: any) => {
|
||||
if (response.data) {
|
||||
this.serviceCallNotes = response.data
|
||||
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
2
src/router/index.d.ts
vendored
Normal file
2
src/router/index.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
declare const router: import("vue-router").Router;
|
||||
export default router;
|
||||
42
src/router/index.ts
Normal file
42
src/router/index.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { createRouter, createWebHistory } from "vue-router";
|
||||
|
||||
import authRoutes from '../pages/auth/routes.ts';
|
||||
import oilRoutes from '../pages/delivery/routes.ts';
|
||||
import serviceRoutes from '../pages/service/routes.ts';
|
||||
import employeeRoutes from '../pages/employee/routes.ts';
|
||||
import payRoutes from '../pages/pay/routes.ts';
|
||||
import customerRoutes from '../pages/customer/routes.ts';
|
||||
import Home from '../pages/Index.vue';
|
||||
import cardRoutes from '../pages/card/routes.ts'
|
||||
import autoRoutes from '../pages/automatic/routes.ts'
|
||||
import Error404 from '../pages/error/Error404.vue'
|
||||
import adminRoutes from "../pages/admin/routes.ts";
|
||||
|
||||
const routes = [
|
||||
...cardRoutes,
|
||||
...authRoutes,
|
||||
...payRoutes,
|
||||
...serviceRoutes,
|
||||
...employeeRoutes,
|
||||
...customerRoutes,
|
||||
...oilRoutes,
|
||||
...autoRoutes,
|
||||
...adminRoutes,
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home,
|
||||
},
|
||||
// Error Pages
|
||||
{
|
||||
path: '/:catchAll(.*)*',
|
||||
component: Error404,
|
||||
},
|
||||
]
|
||||
|
||||
let router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
export default router
|
||||
//sourceMappingURL=index.ts.map
|
||||
1
src/services/auth.header.d.ts
vendored
Normal file
1
src/services/auth.header.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export default function authHeader(): Record<string, string>;
|
||||
12
src/services/auth.header.ts
Normal file
12
src/services/auth.header.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export default function authHeader (): Record<string, string> {
|
||||
|
||||
let user_token = localStorage.getItem('auth_user')
|
||||
let auth_token = localStorage.getItem('auth_token')
|
||||
|
||||
if (user_token && auth_token) {
|
||||
return { 'Authorization': 'bearer ' + auth_token };
|
||||
}
|
||||
else {
|
||||
return {'Authorization': 'None'};
|
||||
}
|
||||
}
|
||||
38
src/stores/auth.store.js
Normal file
38
src/stores/auth.store.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import { fetchWrapper } from '@/helpers';
|
||||
import { router } from '@/router';
|
||||
|
||||
|
||||
const baseUrl = `${import.meta.env.VITE_BASE_URL}/users`;
|
||||
|
||||
export const useAuthStore = defineStore({
|
||||
id: 'auth',
|
||||
state: () => ({
|
||||
// initialize state from local storage to enable user to stay logged in
|
||||
user: JSON.parse(localStorage.getItem('user')),
|
||||
returnUrl: null
|
||||
}),
|
||||
actions: {
|
||||
async login(username, password) {
|
||||
|
||||
const user = await fetchWrapper.post(`${baseUrl}/authenticate`,
|
||||
{ username, password });
|
||||
|
||||
// update pinia state
|
||||
this.user = user;
|
||||
|
||||
// store user details and jwt in local storage to keep user logged in between page refreshes
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
|
||||
// redirect to previous url or default to home page
|
||||
router.push(this.returnUrl || '/');
|
||||
|
||||
},
|
||||
logout() {
|
||||
this.user = null;
|
||||
localStorage.removeItem('user');
|
||||
router.push('/account/login');
|
||||
}
|
||||
}
|
||||
});
|
||||
64
src/stores/users.store.js
Normal file
64
src/stores/users.store.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
import { fetchWrapper } from '@/helpers';
|
||||
import { useAuthStore } from '@/stores';
|
||||
|
||||
const baseUrl = `${import.meta.env.VITE_BASE_URL}/auth`;
|
||||
|
||||
export const useUsersStore = defineStore({
|
||||
id: 'users',
|
||||
state: () => ({
|
||||
users: {},
|
||||
user: {}
|
||||
}),
|
||||
actions: {
|
||||
async register(user) {
|
||||
await fetchWrapper.post(`${baseUrl}/register`, user);
|
||||
},
|
||||
async getAll() {
|
||||
this.users = { loading: true };
|
||||
try {
|
||||
this.users = await fetchWrapper.get(baseUrl);
|
||||
} catch (error) {
|
||||
this.users = { error };
|
||||
}
|
||||
},
|
||||
async getById(id) {
|
||||
this.user = { loading: true };
|
||||
try {
|
||||
this.user = await fetchWrapper.get(`${baseUrl}/${id}`);
|
||||
} catch (error) {
|
||||
this.user = { error };
|
||||
}
|
||||
},
|
||||
async update(id, params) {
|
||||
await fetchWrapper.put(`${baseUrl}/${id}`, params);
|
||||
|
||||
// update stored user if the logged-in user updated their own record
|
||||
const authStore = useAuthStore();
|
||||
if (id === authStore.user.id) {
|
||||
// update local storage
|
||||
const user = { ...authStore.user, ...params };
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
|
||||
// update auth user in pinia state
|
||||
authStore.user = user;
|
||||
}
|
||||
},
|
||||
async delete(id) {
|
||||
// add isDeleting prop to user being deleted
|
||||
this.users.find(x => x.id === id).isDeleting = true;
|
||||
|
||||
await fetchWrapper.delete(`${baseUrl}/${id}`);
|
||||
|
||||
// remove user from list after deleted
|
||||
this.users = this.users.filter(x => x.id !== id);
|
||||
|
||||
// auto logout if the logged in user deleted their own record
|
||||
const authStore = useAuthStore();
|
||||
if (id === authStore.user.id) {
|
||||
authStore.logout();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
Reference in New Issue
Block a user