Basic login and date updates
This commit is contained in:
parent
dbeec48da8
commit
32630a502c
7 changed files with 111 additions and 9 deletions
|
|
@ -18,12 +18,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import data from './data.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
computed: {
|
computed: {
|
||||||
currentRoute() {
|
currentRoute() {
|
||||||
return this.$route.path
|
return this.$route.path
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
if (!await data.isLoggedIn()) {
|
||||||
|
this.$router.push('/login')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="fields">
|
<div class="fields">
|
||||||
<date-picker @date-selected="selectDate" :date="meal.date" />
|
<date-picker @date-selected="selectDate" :date="meal.meal_date" />
|
||||||
</div>
|
</div>
|
||||||
<div class="recipes">
|
<div class="recipes">
|
||||||
<h2>Recipes</h2>
|
<h2>Recipes</h2>
|
||||||
|
|
@ -54,11 +54,12 @@ export default {
|
||||||
return {
|
return {
|
||||||
meal: {
|
meal: {
|
||||||
id: 0,
|
id: 0,
|
||||||
date: new Date(),
|
meal_date: new Date(),
|
||||||
recipes: [],
|
recipes: [],
|
||||||
extra_ingredients: [],
|
extra_ingredients: [],
|
||||||
chefs: [],
|
chefs: [],
|
||||||
consumers: [],
|
consumers: [],
|
||||||
|
cleanup: []
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -68,11 +69,23 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectRecipe(recipe) {
|
async selectRecipe(recipe) {
|
||||||
|
// Refetch to get additional details
|
||||||
|
recipe = await data.getRecipe(recipe.id);
|
||||||
|
|
||||||
|
if (recipe.created_by) {
|
||||||
|
this.meal.chefs.push(recipe.created_by);
|
||||||
|
this.meal.consumers.push(recipe.created_by);
|
||||||
|
|
||||||
|
if (this.meal.cleanup.length === 0) {
|
||||||
|
this.meal.cleanup.push(recipe.created_by);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.meal.recipes.push(recipe);
|
this.meal.recipes.push(recipe);
|
||||||
},
|
},
|
||||||
selectDate(date) {
|
selectDate(date) {
|
||||||
this.meal.date = date;
|
this.meal.meal_date = date;
|
||||||
},
|
},
|
||||||
removeRecipe(recipe) {
|
removeRecipe(recipe) {
|
||||||
this.meal.recipes = this.meal.recipes.filter(r => r.id !== recipe.id);
|
this.meal.recipes = this.meal.recipes.filter(r => r.id !== recipe.id);
|
||||||
|
|
|
||||||
50
src/components/LoginPage.vue
Normal file
50
src/components/LoginPage.vue
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
<div class="login">
|
||||||
|
<h1>Login</h1>
|
||||||
|
<form>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input v-model="username" type="text" class="form-control" id="username" placeholder="Username">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-primary" @click="login">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import data from '@/data';
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LoginVue',
|
||||||
|
props: {
|
||||||
|
redirect: {
|
||||||
|
type: String,
|
||||||
|
default: '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
username: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async login() {
|
||||||
|
const person = await data.login(this.username);
|
||||||
|
if (person?.id) {
|
||||||
|
this.$router.push(this.redirect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert('Login failed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
@ -58,10 +58,10 @@ export default {
|
||||||
props: ['meal'],
|
props: ['meal'],
|
||||||
computed: {
|
computed: {
|
||||||
date() {
|
date() {
|
||||||
return this.meal.date.toLocaleDateString('en-au', { month: 'numeric', day: 'numeric' })
|
return this.meal.meal_date.toLocaleDateString('en-au', { month: 'numeric', day: 'numeric' })
|
||||||
},
|
},
|
||||||
dayOfWeek() {
|
dayOfWeek() {
|
||||||
return this.meal.date.toLocaleDateString('en-au', { weekday: 'long' })
|
return this.meal.meal_date.toLocaleDateString('en-au', { weekday: 'long' })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
meal: {
|
meal: {
|
||||||
date: new Date(),
|
meal_date: new Date(),
|
||||||
recipe: { name: 'Sar Tay' },
|
recipe: { name: 'Sar Tay' },
|
||||||
chefs: [{ name: 'Ryan' }],
|
chefs: [{ name: 'Ryan' }],
|
||||||
consumers: [{ name: 'Ryan' }, { name: 'Jacob' }],
|
consumers: [{ name: 'Ryan' }, { name: 'Jacob' }],
|
||||||
|
|
|
||||||
34
src/data.js
34
src/data.js
|
|
@ -1,11 +1,12 @@
|
||||||
const BASE_URL = "http://192.168.68.177:8000"
|
const BASE_URL = "http://localhost:8000"
|
||||||
|
|
||||||
|
let user = null;
|
||||||
export default {
|
export default {
|
||||||
async getMeals(from, to) {
|
async getMeals(from, to) {
|
||||||
const response = await fetch(BASE_URL + "/meals?from=" + from.toISOString() + "&to=" + to.toISOString());
|
const response = await fetch(BASE_URL + "/meals?from=" + from.toISOString() + "&to=" + to.toISOString());
|
||||||
const meals = await response.json();
|
const meals = await response.json();
|
||||||
for (const meal of meals) {
|
for (const meal of meals) {
|
||||||
meal.date = new Date(meal.date);
|
meal.meal_date = new Date(meal.meal_date);
|
||||||
}
|
}
|
||||||
|
|
||||||
return meals;
|
return meals;
|
||||||
|
|
@ -39,6 +40,7 @@ export default {
|
||||||
|
|
||||||
const response = await fetch(BASE_URL + "/products", {
|
const response = await fetch(BASE_URL + "/products", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
|
|
@ -55,6 +57,7 @@ export default {
|
||||||
async saveRecipe(recipe) {
|
async saveRecipe(recipe) {
|
||||||
const response = await fetch(BASE_URL + "/recipes", {
|
const response = await fetch(BASE_URL + "/recipes", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
|
|
@ -66,6 +69,7 @@ export default {
|
||||||
async saveMeal(meal) {
|
async saveMeal(meal) {
|
||||||
const response = await fetch(BASE_URL + "/meals", {
|
const response = await fetch(BASE_URL + "/meals", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
},
|
},
|
||||||
|
|
@ -74,4 +78,30 @@ export default {
|
||||||
|
|
||||||
return await response.json();
|
return await response.json();
|
||||||
},
|
},
|
||||||
|
async isLoggedIn() {
|
||||||
|
var cookie = decodeURIComponent(document.cookie).split(";").find(cookie => cookie.trimStart().startsWith("user_id="));
|
||||||
|
if (cookie) {
|
||||||
|
const response = await fetch(BASE_URL + "/auth/refresh", {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
});
|
||||||
|
|
||||||
|
user = await response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
return user !== null;
|
||||||
|
},
|
||||||
|
async login(username) {
|
||||||
|
const response = await fetch(BASE_URL + "/auth/login", {
|
||||||
|
method: "POST",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ username }),
|
||||||
|
});
|
||||||
|
|
||||||
|
user = await response.json();
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
|
||||||
|
import LoginPage from './components/LoginPage.vue'
|
||||||
import ActionsPage from './components/ActionsPage.vue'
|
import ActionsPage from './components/ActionsPage.vue'
|
||||||
import MealPlanPage from './components/MealPlanPage.vue'
|
import MealPlanPage from './components/MealPlanPage.vue'
|
||||||
import ShoppingPage from './components/ShoppingPage.vue'
|
import ShoppingPage from './components/ShoppingPage.vue'
|
||||||
|
|
@ -14,6 +15,7 @@ import EditRecipePage from './components/EditRecipePage.vue'
|
||||||
// We'll talk about nested routes later.
|
// We'll talk about nested routes later.
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: '/', component: ActionsPage },
|
{ path: '/', component: ActionsPage },
|
||||||
|
{ path: '/login', component: LoginPage },
|
||||||
{ path: '/mealplan', component: MealPlanPage },
|
{ path: '/mealplan', component: MealPlanPage },
|
||||||
{ path: '/shopping', component: ShoppingPage },
|
{ path: '/shopping', component: ShoppingPage },
|
||||||
{ path: '/recipes/add', component: EditRecipePage },
|
{ path: '/recipes/add', component: EditRecipePage },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue