Skip to content

Commit c603cbc

Browse files
committed
vuex
1 parent f64c5b1 commit c603cbc

File tree

5 files changed

+243
-2
lines changed

5 files changed

+243
-2
lines changed

vue-noob-4/client/src/App.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div>
33
<app-navbar />
4+
<app-alerts />
45
<div class="my-3">
56
<router-view />
67
</div>
@@ -9,16 +10,23 @@
910

1011
<script>
1112
import Navbar from "./components/layouts/Navbar";
13+
import Alerts from "./components/layouts/Alerts";
1214
export default {
1315
name: "App",
1416
components: {
1517
appNavbar: Navbar,
18+
appAlerts: Alerts,
1619
},
1720
};
1821
</script>
1922

2023
<style>
21-
button {
24+
button,
25+
input {
2226
box-shadow: none !important;
27+
outline: none !important;
28+
}
29+
::-webkit-scrollbar {
30+
width: 0;
2331
}
2432
</style>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<template>
2+
<div class="alerts-div">
3+
<div class="toast" :class="{show: $store.state.alerts}" role="alert">
4+
<div class="toast-header">
5+
<strong class="mr-auto text-danger">{{ $store.state.alerts && $store.state.alerts.type }}</strong>
6+
<button @click="$store.commit('CLEAR_ALERT')" type="button" class="ml-2 mb-1 close">
7+
<span aria-hidden="true">&times;</span>
8+
</button>
9+
</div>
10+
<div class="toast-body">{{ $store.state.alerts && $store.state.alerts.msg }}</div>
11+
</div>
12+
</div>
13+
</template>
14+
15+
<script>
16+
export default {
17+
name: "AppAlert",
18+
};
19+
</script>
20+
21+
<style scoped>
22+
.alerts-div {
23+
position: absolute;
24+
top: 2em;
25+
right: 2em;
26+
}
27+
.toast {
28+
background-color: rgba(216, 155, 155, 0.26);
29+
}
30+
.toast.show {
31+
transition: ease 0.3s;
32+
}
33+
</style>

vue-noob-4/client/src/components/pages/addCustomer.vue

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,129 @@
11
<template>
2-
<div class="container"></div>
2+
<div class="container">
3+
<h1 class="text-primary">Add Customer</h1>
4+
<hr class="my-2" />
5+
<form @submit.prevent="handleSubmit">
6+
<div class="jumbotron my-3 p-4">
7+
<h4>Customer Info</h4>
8+
<div class="form-group">
9+
<label>First Name</label>
10+
<input
11+
required
12+
v-model="customer.firstName"
13+
type="text"
14+
class="form-control"
15+
placeholder="Enter Fisrt Name"
16+
/>
17+
</div>
18+
<div class="form-group">
19+
<label>Last Name</label>
20+
<input
21+
required
22+
v-model="customer.lastName"
23+
type="text"
24+
class="form-control"
25+
placeholder="Enter Last Name"
26+
/>
27+
</div>
28+
</div>
29+
<div class="jumbotron my-3 p-4">
30+
<h4>Customer Contact</h4>
31+
<div class="form-group">
32+
<label>Email Address</label>
33+
<input
34+
required
35+
v-model="customer.email"
36+
type="email"
37+
class="form-control"
38+
placeholder="Enter Email Address"
39+
/>
40+
</div>
41+
<div class="form-group">
42+
<label>Phone Number</label>
43+
<input
44+
required
45+
v-model="customer.phone"
46+
type="tel"
47+
class="form-control"
48+
placeholder="Enter Phone Number"
49+
/>
50+
</div>
51+
</div>
52+
<div class="jumbotron my-3 p-4">
53+
<h4>Customer location</h4>
54+
<div class="form-group">
55+
<label>Address</label>
56+
<input
57+
required
58+
v-model="customer.address"
59+
type="text"
60+
class="form-control"
61+
placeholder="Enter Full Address"
62+
/>
63+
</div>
64+
<div class="form-group">
65+
<label>City</label>
66+
<input
67+
required
68+
v-model="customer.city"
69+
type="text"
70+
class="form-control"
71+
placeholder="Enter City"
72+
/>
73+
</div>
74+
<div class="form-group">
75+
<label>State</label>
76+
<input
77+
v-model="customer.state"
78+
type="text"
79+
class="form-control"
80+
placeholder="Enter State"
81+
/>
82+
</div>
83+
<div class="text-center">
84+
<button class="btn btn-success">{{ submitted ? 'Loading ...' : 'Submit' }}</button>
85+
</div>
86+
</div>
87+
</form>
88+
</div>
389
</template>
490

591
<script>
692
export default {
793
name: "AppAddPage",
94+
data() {
95+
return {
96+
customer: {
97+
firstName: "",
98+
lastName: "",
99+
email: "",
100+
phone: "",
101+
city: "",
102+
address: "",
103+
state: "",
104+
},
105+
submitted: false,
106+
};
107+
},
108+
methods: {
109+
handleSubmit: async function () {
110+
this.submitted = true;
111+
if (!this.validateEmail(this.customer.email)) {
112+
return this.$store.dispatch("setAlert", {
113+
type: "Error",
114+
msg: "Please enter a valid Email Address",
115+
});
116+
}
117+
const res = await this.$store.dispatch("addCustomer", this.customer);
118+
console.log(res, "FROM COMPONENT");
119+
},
120+
validateEmail(email) {
121+
const reg = new RegExp(
122+
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
123+
);
124+
return reg.test(email);
125+
},
126+
},
8127
};
9128
</script>
10129

vue-noob-4/client/src/main.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Vue from 'vue';
22
import App from './App.vue';
33
import VueRouter from 'vue-router';
44
import routes from './routes';
5+
import store from './store';
56

67
Vue.config.productionTip = false;
78

@@ -14,4 +15,5 @@ const router = new VueRouter({
1415
new Vue({
1516
render: h => h(App),
1617
router,
18+
store,
1719
}).$mount('#app');

vue-noob-4/client/src/store.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Vue from 'vue';
2+
import Vuex from 'vuex';
3+
4+
Vue.use(Vuex);
5+
6+
const sendRequest = async body => {
7+
let reqHeaders = new Headers();
8+
reqHeaders.append('Content-Type', 'application/json');
9+
let requestOptions = {
10+
method: 'POST',
11+
headers: reqHeaders,
12+
body,
13+
redirect: 'follow',
14+
};
15+
let uri = ``;
16+
if (process.env.NODE_ENV !== 'production') {
17+
uri += 'http://localhost:5000';
18+
}
19+
const res = await fetch(`${uri}/api_v1_graphql`, requestOptions);
20+
const JSONData = await res.json();
21+
return JSONData;
22+
};
23+
24+
const store = new Vuex.Store({
25+
state: {
26+
customers: [],
27+
alerts: null,
28+
},
29+
getters: {},
30+
actions: {
31+
addCustomer: async (context, customer) => {
32+
const query = JSON.stringify({
33+
query: `
34+
mutation {
35+
createCustomer(customerInput: {
36+
email:"${customer.email}",
37+
phone:"${customer.phone}",
38+
city:"${customer.city}",
39+
state: "${customer.state}",
40+
address: "${customer.address}",
41+
firstName: "${customer.firstName}",
42+
lastName: "${customer.lastName}"}) {
43+
_id
44+
firstName
45+
lastName
46+
email
47+
}
48+
}
49+
`,
50+
});
51+
const res = await sendRequest(query);
52+
if (res.errors) {
53+
return res.errors;
54+
}
55+
context.commit('ADD_CUSTOMER', res.data.createCustomer);
56+
},
57+
setAlert: async (context, payload) => {
58+
context.commit('SET_ALERT', payload);
59+
setTimeout(() => {
60+
context.commit('CLEAR_ALERT');
61+
}, 3000);
62+
},
63+
},
64+
mutations: {
65+
SET_ALERT(state, payload) {
66+
return (state.alerts = {
67+
...payload,
68+
});
69+
},
70+
CLEAR_ALERT(state) {
71+
return (state.alerts = null);
72+
},
73+
ADD_CUSTOMER(state, payload) {
74+
return (state.customers = [...state.customers, ...payload]);
75+
},
76+
},
77+
});
78+
79+
export default store;

0 commit comments

Comments
 (0)