Skip to content

Commit

Permalink
chore: cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
benborla committed Nov 20, 2023
1 parent dd3ada9 commit ff1211f
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 59 deletions.
9 changes: 9 additions & 0 deletions app/src/components/FavoriteIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<template>
<span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star-fill"
viewBox="0 0 16 16">
<path
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" />
</svg>
</span>
</template>
6 changes: 5 additions & 1 deletion app/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ import { createApp } from "vue";

import App from "@/App.vue";
import { router } from "@/router";
import helpers from '@/services/helper';

import "bootstrap/scss/bootstrap.scss";
import "bootstrap-icons/font/bootstrap-icons.css";

const app = createApp(App).use(router);
const app = createApp(App)
.use(helpers)
.use(router)

router.isReady().then(() => app.mount("#app"));
14 changes: 14 additions & 0 deletions app/src/services/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const helpers = {
install(app: any) {
app.config.globalProperties = {
formatDate: (date: string): string => (
new Date(date).toISOString().slice(0, 19).replace("T", " ")
),
translateSource: (type: string): string => (
type === 'FRUITY_VICE_API' ? 'From Fruity Vice API' : 'From Fruity Vice App'
),
}
}
}

export default helpers;
8 changes: 8 additions & 0 deletions app/src/types/Favorite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default interface Favorite {
id: number,
fruit_id: number,
fruit_name: string,
dateAdded: {
date: string
}
}
12 changes: 11 additions & 1 deletion app/src/types/Fruit.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
type Nullable<T> = T | null;

export default interface Fruit {
id: number,
id: Nullable<number>,
name: string,
genus: string,
family: string,
Expand All @@ -9,4 +11,12 @@ export default interface Fruit {
fat: number,
sugar: number,
calories: number,
createdAt: {
date: string
},
updatedAt: {
date: string
},
source: string,
favorite: Nullable<object>
}
10 changes: 5 additions & 5 deletions app/src/views/Favorites.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
<tbody>
<tr v-for="(favorite, index) in favorites" :key="index">
<td>{{ index + 1 }}</td>
<td><router-link :to="'/fruit/' + favorite.fruit_id + '/view'">{{ favorite.fruit_name }}</router-link></td>
<td>{{ getFormattedDate(favorite.dateAdded.date) }}</td>
<td><router-link class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover" :to="'/fruit/' + favorite.fruit_id + '/view'">{{ favorite.fruit_name }}</router-link></td>
<td>{{ formatDate(favorite.dateAdded.date) }}</td>
<td>
<a href="#" @click="removeFavorite(favorite.fruit_id)">Remove</a>
<button type="button" class="btn btn-link text-danger link-offset-2 link-offset-3-hover link-underline-danger link-underline-opacity-0 link-underline-opacity-75-hover" @click="removeFavorite(favorite.fruit_id)">Remove</button>
</td>
</tr>
</tbody>
Expand All @@ -27,12 +27,13 @@
<script lang="ts">
import { defineComponent } from "vue";
import FruitsApi from '@/api/fruits'
import type Favorite from '@/types/Favorite'
export default defineComponent({
name: 'favorites',
data() {
return {
favorites: []
favorites: [] as Favorite[]
}
},
methods: {
Expand All @@ -43,7 +44,6 @@ export default defineComponent({
await FruitsApi.favorites()
.then((response: any) => {
this.favorites = response.data
console.log(response.data)
})
},
async removeFavorite(id: number) {
Expand Down
67 changes: 53 additions & 14 deletions app/src/views/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
<h1 class="display-5 fw-bold mb-3">Fruit Details</h1>
<div class="alert" :class="{ 'alert-danger': !isSuccessful, 'alert-success': isSuccessful }" role="alert"
v-if="message">
{{ message }}
<span v-if="typeof message === 'string'">
{{ message }}
</span>
<span v-if="typeof message === 'object'">
<li v-for="error in message">
{{ error }}
</li>
</span>
</div>
<form method="POST" action="#">
<div class="form-floating mb-3">
Expand Down Expand Up @@ -46,13 +53,15 @@
v-model="fruit.calories">
<label for="calories">Calories</label>
</div>
<button type="button" class="btn btn-success btn-lg float-end" @click="createData" v-if="!this.$route.params.id">
<a href="#" type="button" class="btn btn-success btn-lg float-end" @click="createData"
v-if="!this.$route.params.id">
Create
</button>
</a>

<button type="button" class="btn btn-success btn-lg float-end" @click="updateData" v-if="this.$route.params.id">
<a href="#" type="button" class="btn btn-success btn-lg float-end" @click="updateData"
v-if="this.$route.params.id">
Update
</button>
</a>
</form>
<div class="clearfix"></div>
</div>
Expand All @@ -63,6 +72,12 @@ import { defineComponent } from "vue";
import FruitsApi from '@/api/fruits'
import type Fruit from '@/types/Fruit'
type ErrorMessagesType = {
errors: {
[key: string]: string[];
};
};
export default defineComponent({
name: 'fruit-form',
data() {
Expand All @@ -79,34 +94,59 @@ export default defineComponent({
sugar: 0,
calories: 0
} as Fruit,
message: '' as string,
message: '' as string|object,
isSuccessful: true,
submitted: false,
}
},
methods: {
clearForm() {
this.fruit = {
id: null,
name: '',
genus: '',
family: '',
fruitOrder: '',
carbohydrates: 0,
protein: 0,
fat: 0,
sugar: 0,
calories: 0
}
},
formatErrorMessage(errorMessages: ErrorMessagesType) {
let errors: {} = {};
for (const field in errorMessages.errors) {
const messages = errorMessages.errors[field];
const fieldLabel = field.charAt(0).toUpperCase() + field.slice(1);
messages.forEach((message: string) => {
errors[fieldLabel] = message;
});
}
this.message = errors;
},
async retrieveData(id: number) {
await FruitsApi.get(id)
.then((response: any) => {
console.log(response);
this.fruit = response.data;
})
},
async createData() {
await FruitsApi.new(this.fruit)
.then((response: any) => {
this.message = 'Fruit data has been created'
this.isSuccessful = true
this.submitted = true
this.clearForm()
})
.catch((e: Error) => {
console.error(e);
this.message = 'Something went wrong, please try again'
this.formatErrorMessage(e.response.data)
this.isSuccessful = false
})
},
async updateData() {
await FruitsApi.update(this.fruit.id, this.fruit)
.then((response: any) => {
Expand All @@ -115,8 +155,7 @@ export default defineComponent({
this.submitted = true
})
.catch((e: Error) => {
console.error(e);
this.message = 'Something went wrong, please try again'
this.formatErrorMessage(e.response.data)
this.isSuccessful = false
})
}
Expand All @@ -130,7 +169,7 @@ export default defineComponent({
this.message = ''
},
onUnmounted() {
this.fruit = {}
this.clearForm()
this.message = ''
}
})
Expand Down
38 changes: 21 additions & 17 deletions app/src/views/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,26 @@
<tr v-for="(fruit, index) in fruits" :key="index">
<th scope="row">{{ fruit.id }}</th>
<td>{{ fruit.name }}</td>
<td>
<router-link
class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover"
:to="'/fruit/' + fruit.id + '/view'">{{ fruit.name }}</router-link>&nbsp;
<span class="text-warning" v-if="fruit.favorite">
<FavoriteIcon />
</span>
</td>
<td>{{ fruit.genus }}</td>
<td>{{ fruit.family }}</td>
<td>{{ fruit.fruitOrder }}</td>
<td>{{ getFormattedDate(fruit.createdAt.date) }}</td>
<td>{{ formatDate(fruit.createdAt.date) }}</td>
<td>
<a href="#" @click="addToFavorite(fruit)">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star-fill"
viewBox="0 0 16 16">
<path
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" />
</svg>
</a> |
<router-link :to="'/fruit/' + fruit.id + '/view'">View</router-link> |
<router-link :to="'/fruit/' + fruit.id">Edit</router-link> |
<button class="btn btn-link" @click="deleteFruit(fruit.id)">Delete</button>
<a href="#" @click="addToFavorite(fruit)"><FavoriteIcon /></a> |
<router-link
class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover"
:to="'/fruit/' + fruit.id">Edit</router-link> |
<button type="button"
class="btn btn-link text-danger link-offset-2 link-offset-3-hover link-underline-danger link-underline-opacity-0 link-underline-opacity-75-hover"
@click="deleteFruit(fruit.id)">Delete</button>
</td>
</tr>
</tbody>
Expand All @@ -94,8 +99,10 @@
</div>
</div>
</template>

<script lang="ts">
<script lang="ts" setup>
import FavoriteIcon from '@/components/FavoriteIcon.vue'
</script>
<script lang = "ts" >
import { defineComponent } from "vue";
import FruitsApi from '@/api/fruits'
import type Fruit from '@/types/Fruit'
Expand Down Expand Up @@ -170,10 +177,7 @@ export default defineComponent({
this.message = favorites[0]
this.isSuccessful = false
})
},
getFormattedDate(date: string) {
return new Date(date).toISOString().slice(0, 19).replace("T", " ");
},
}
},
mounted() {
this.retrieveData();
Expand Down
48 changes: 27 additions & 21 deletions app/src/views/View.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,13 @@
<small>Units of energy derived from food, utilized by the body for various functions, including metabolism,
movement, and maintaining physiological processes.</small>
</div>
<span class="text-success">{{ fruit.calories }} kcal</span>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>Total Nutrion</span>
<strong>{{ getTotalNutrition() }}</strong>
<strong>{{ fruit.calories }} kcal</strong>
</li>
</ul>
</div>
<div class="col-md-7 col-lg-8">
<h4 class="mb-3">Fruit Details</h4>
<h4 class="mb-3">Fruit Details <span class="text-muted fs-6 fst-italic">{{ translateSource(fruit.source) }}</span>
</h4>
<div class="row g-3">
<div class="col-sm-6">
<div for="firstName" class="form-label">Name</div>
Expand All @@ -71,7 +68,24 @@
<div class="form-label">Order</div>
<h6 class="font-weight-bold">{{ fruit.fruitOrder }}</h6>
</div>
<hr class="my-4">
<div class="col-sm-6">
<div class="form-label">Created At</div>
<h6 class="font-weight-bold">{{ formatDate(fruit.createdAt?.date) }}</h6>
</div>
<div class="col-sm-6">
<div class="form-label">Updated At</div>
<h6 class="font-weight-bold">{{ formatDate(fruit.updatedAt?.date) }}</h6>
</div>
</div>
<hr class="my-4">

<div class="float-end">
<router-link
class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover"
:to="'/fruit/' + fruit.id">Update</router-link>
</div>
<div class="clearfix"></div>
</div>
</div>
</template>
Expand All @@ -85,24 +99,16 @@ export default defineComponent({
data() {
return {
fruit: {
id: null,
name: '',
genus: '',
family: '',
fruitOrder: '',
carbohydrates: 0,
protein: 0,
fat: 0,
sugar: 0,
calories: 0
createdAt: {
date: '1970-01-01T00:00:00.000Z'
},
updatedAt: {
date: '1970-01-01T00:00:00.000Z'
}
} as Fruit,
}
},
methods: {
getTotalNutrition() {
return parseFloat(this.fruit.carbohydrates + this.fruit.protein +
this.fruit.sugar + this.fruit.fat).toFixed(2);
},
async retrieveData(id: number) {
await FruitsApi.get(id)
.then((response: any) => {
Expand All @@ -112,7 +118,7 @@ export default defineComponent({
},
},
mounted() {
this.retrieveData(this.$route.params.id)
this.retrieveData(parseInt(this.$route.params.id))
}
})
</script>

0 comments on commit ff1211f

Please sign in to comment.