Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Weng Fai - Coding challenge submission #14

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7775cf2
Initial commit
wongwf82 Feb 1, 2024
11080d6
Update broken font-awesome embed link
wongwf82 Feb 1, 2024
e360bf1
Add reusable JoList component
wongwf82 Feb 1, 2024
885c41a
Update UI
wongwf82 Feb 1, 2024
a68d3d1
Remove ListTitle
wongwf82 Feb 1, 2024
537cbc7
Filters it for tags that include kitten and sorts by date
wongwf82 Feb 1, 2024
fb380d3
Fix: update image alt
wongwf82 Feb 1, 2024
af445ab
Refactor: simplify naming
wongwf82 Feb 1, 2024
1d6365c
Fix: change sort order
wongwf82 Feb 1, 2024
77181f0
Fix: kittens get bigger
wongwf82 Feb 1, 2024
207aa36
Make list more reusable without image
wongwf82 Feb 1, 2024
78ac92b
Update checkGroup logic for Rules engine
wongwf82 Feb 2, 2024
4763192
Add Jest unit test for Rules checkGroup
wongwf82 Feb 2, 2024
b3c7acf
Use Vuex store for Layout
wongwf82 Feb 2, 2024
4d50ae7
Migrate Layout vuex to own module
wongwf82 Feb 2, 2024
d84679c
Add vuex to Rules
wongwf82 Feb 2, 2024
4760fe0
Update unit test for Rules
wongwf82 Feb 4, 2024
5f9c45e
Add API testing using Postman
wongwf82 Feb 5, 2024
da21952
Integrate QA submission form with API
wongwf82 Feb 5, 2024
c30cbe3
Fix: file names
wongwf82 Feb 5, 2024
449767f
Remove example unit test spec
wongwf82 Feb 5, 2024
44ca0e5
Add E2E testing for QA page
wongwf82 Feb 5, 2024
8342d3e
Add READMe.md for e2e testing
wongwf82 Feb 5, 2024
d1bf771
Add Lighthouse audits of QA page
wongwf82 Feb 5, 2024
8cffe54
Add future tools improvements
wongwf82 Feb 5, 2024
1cf16ef
Fix: broken file names
wongwf82 Feb 5, 2024
efd5752
Fix: broken link to dev.json
wongwf82 Feb 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions db/dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
"entities": [
{
"id": 1,
"property": "foo"
},
{
"id": 2,
"property": "bar"
"name": "John Doe",
"email": "[email protected]",
"age": 25,
"phone": "123-456-7890"
}
],
"files": [
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<script
async
defer
src="https://kit.fontawesome.com/8282dfbed5.js"
src="https://kit.fontawesome.com/a3b80abd63.js"
crossorigin="anonymous"
></script>
<!-- built files will be auto injected -->
Expand Down
65 changes: 65 additions & 0 deletions src/components/globals/JoList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<div class="list">
<div v-for="item in items" :key="item.id" class="list-item">
<div class="list-item__image">
<slot name="image" :item="item">
<img v-if="item.src" :src="item.src" :alt="item.description" />
</slot>
</div>
<div class="list-item__text">
<slot name="text" :item="item">
<div class="description">{{ item.description }}</div>
<div class="filename">{{ item.filename }}</div>
</slot>
</div>
</div>
</div>
</template>

<script>
export default {
name: "JoList",
props: {
items: {
type: Array,
required: true,
default: () => [],
},
},
};
</script>

<style lang="scss" scoped>
.list {
max-width: 800px;
margin: 0 auto;

.list-item {
display: flex;
align-items: center;
padding: $base-spacing;
border: $base-border;

&__image {
margin-right: $base-spacing;
border-radius: $base-border-radius;
box-shadow: $shadow-base;
}

&__text {
flex: 1;
line-height: $base-line-height;
.description {
font-weight: $weight-bold;
color: $josef-dark-purple;
font-size: 1.2rem;
}

.filename {
font-weight: $weight-normal;
font-size: 1rem;
}
}
}
}
</style>
4 changes: 4 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Vue from "vue";
import Vuex from "vuex";

import user from "./user";
import layout from "./layout";
import rules from "./rules";

Vue.use(Vuex);

Expand All @@ -11,5 +13,7 @@ export default new Vuex.Store({
actions: {},
modules: {
user,
layout,
rules,
},
});
35 changes: 35 additions & 0 deletions src/store/layout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import Vue from "vue";
import actions from "@/store/actions_types";
import mutations from "@/store/mutations_types";
import api from "@/api";

const layout = {
namespaced: true,
state: {
files: [],
},
getters: {
getFiles: (state) => state.files,
getSortedFiles: (state) => {
return state.files.sort((a, b) => new Date(a.date) - new Date(b.date));
},
getSortedFilesByTag: (_, getters) => (tag) => {
const files = getters.getSortedFiles || [];
return files.filter((file) => file.tags && file.tags.includes(tag));
},
},
actions: {
[actions.getAll]({ commit }) {
return api.files.get().then((res) => {
commit(mutations.SET, res);
});
},
},
mutations: {
[mutations.SET](state, payload) {
Vue.set(state, "files", payload);
},
},
};

export default layout;
38 changes: 38 additions & 0 deletions src/store/rules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Vue from "vue";
import actions from "@/store/actions_types";
import mutations from "@/store/mutations_types";
import api from "@/api";

const rules = {
namespaced: true,
state: {
rule_groups: [],
answers: [],
rules: [],
},
getters: {
getRuleGroups: (state) => state.rule_groups,
getAnswers: (state) => state.answers,
getRules: (state) => state.rules,
},
actions: {
async [actions.getAll]({ commit }) {
return Promise.all([
api.rule_groups.get(),
api.answers.get(),
api.rules.get(),
]).then(([rule_groups, answers, rules]) => {
commit(mutations.SET, { key: "rule_groups", value: rule_groups });
commit(mutations.SET, { key: "answers", value: answers });
commit(mutations.SET, { key: "rules", value: rules });
});
},
},
mutations: {
[mutations.SET](state, { key, value }) {
Vue.set(state, key, value);
},
},
};

export default rules;
33 changes: 11 additions & 22 deletions src/views/Layout.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,31 @@
<template>
<div class="container">
<h1>Vue.js layout</h1>
<!-- Render the files data with a resuable component (a list or card up to you!) -->
<pre>// TODO: replace this block 👇 with a resusable component that renders elements from the files array
<code>files:
{{files}}</code>
</pre>
<JoList :items="getSortedFilesByTag('kitten')" />
</div>
</template>

<style lang="scss" scoped>
.container {
max-width: 1024px;
margin: 0 auto;
}

pre,
code {
overflow-x: auto;
white-space: pre-wrap;
white-space: pre-wrap;
line-break: anywhere;
}
</style>

<script>
// @ is an alias to /src
import api from "@/api";
import { mapGetters, mapActions } from "vuex";
import actions from "@/store/actions_types";

export default {
name: "Layout",
data() {
return {
files: [],
};
computed: {
...mapGetters("layout", ["getSortedFilesByTag"]),
},
created() {
api.files.get().then((res) => {
this.files = res;
});
this[actions.getAll]();
},
methods: {
...mapActions("layout", [actions.getAll]),
},
};
</script>
36 changes: 26 additions & 10 deletions src/views/QA.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<p>
Josef provides most of its services via the web. To run web applications,
we use backend and frontend services. With scale, quality assurance and automated
testing become key strategies to keep all the critical functionality
running without regressions.
we use backend and frontend services. With scale, quality assurance and
automated testing become key strategies to keep all the critical
functionality running without regressions.
</p>
<p>
This application was created with
Expand Down Expand Up @@ -37,20 +37,22 @@
<a href="https://vuejs.org/" title="Vue.js">Vue.js</a> for the frontend.
</p>
<h3>API example</h3>
<p><em>GET http://localhost:3000/entites</em> returns:</p>
<p><em>GET http://localhost:3000/entities</em> returns:</p>
<ul class="entities">
<code
>[
<li v-for="entity in entities" v-bind:key="entity.id">
{ "id" : {{ entity.id }}, "property" : "{{ entity.property }}"}
{ "id" : {{ entity.id }}, "name" : {{ entity.name }}, "email" :
{{ entity.email }}, "age" : {{ entity.age }}, "phone" :
{{ entity.phone }} }
</li>
]</code
>
</ul>

<h3>Form example</h3>
<p v-if="submited">
Form submited:
<p v-if="submitted">
Form submitted:
<strong>{{ name }}</strong
>({{ email }}), age of {{ age }}, tel: {{ phone }} ✅
</p>
Expand Down Expand Up @@ -92,14 +94,28 @@ export default {
email: "",
age: "",
phone: "",
submited: false,
submitted: false,
entities: [],
};
},
methods: {
handleSubmit() {
console.log(this.submited);
this.submited = true;
const user = {
name: this.name,
email: this.email,
age: this.age,
phone: this.phone,
};

api.entities
.create(user)
.then((response) => {
console.log("User data submitted successfully:", response);
this.submitted = true;
})
.catch((error) => {
console.error("Error submitting user data:", error);
});
console.log("handle submit");
},
},
Expand Down
Loading