first commit
This commit is contained in:
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FROM node:latest
|
||||||
|
|
||||||
|
ENV VITE_BASE_URL="http://localhost:4056"
|
||||||
|
ENV VITE_PAY_URL="http://localhost:4052"
|
||||||
|
ENV VITE_AUTO_URL="http://localhost:4053"
|
||||||
|
RUN mkdir -p /app
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
ENV PATH /app/node_modules/.bin:$PATH
|
||||||
|
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Vue 3 + TypeScript + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||||
|
|
||||||
|
## Type Support For `.vue` Imports in TS
|
||||||
|
|
||||||
|
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||||
|
|
||||||
|
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||||
|
|
||||||
|
1. Disable the built-in TypeScript Extension
|
||||||
|
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||||
|
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||||
|
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||||
1
env.production
Normal file
1
env.production
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_BASE_URL="https://api.freeport.cash"
|
||||||
15
index.html
Normal file
15
index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Oil</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2591
package-lock.json
generated
Normal file
2591
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
34
package.json
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "eamco_frontend_v2",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc && vite build",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@kyvg/vue3-notification": "^3.1.0",
|
||||||
|
"@vuelidate/core": "^2.0.3",
|
||||||
|
"@vuelidate/validators": "^2.0.4",
|
||||||
|
"@vueuse/core": "^10.7.0",
|
||||||
|
"axios": "^1.6.2",
|
||||||
|
"pinia": "^2.1.7",
|
||||||
|
"v-pagination-3": "^0.1.7",
|
||||||
|
"vue": "^3.3.11",
|
||||||
|
"vue-debounce": "^5.0.0",
|
||||||
|
"vue-router": "^4.2.5",
|
||||||
|
"vuelidate": "^0.7.7"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^4.5.2",
|
||||||
|
"autoprefixer": "^10.4.16",
|
||||||
|
"daisyui": "^4.4.19",
|
||||||
|
"postcss": "^8.4.32",
|
||||||
|
"tailwindcss": "^3.3.6",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"vite": "^5.0.8",
|
||||||
|
"vue-tsc": "^1.8.25"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
postcss.config.js
Normal file
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
||||||
1
public/vite.svg
Normal file
1
public/vite.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="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
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" />
|
||||||
1085
tailwind.config.js
Normal file
1085
tailwind.config.js
Normal file
File diff suppressed because it is too large
Load Diff
25
tsconfig.json
Normal file
25
tsconfig.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
|
||||||
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
}
|
||||||
10
tsconfig.node.json
Normal file
10
tsconfig.node.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
13
vite.config.ts
Normal file
13
vite.config.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
resolve: {},
|
||||||
|
build: {
|
||||||
|
sourcemap: true,
|
||||||
|
chunkSizeWarningLimit: 1600,
|
||||||
|
assetsInlineLimit: 2048, // 2kb
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user