Basic login and date updates

This commit is contained in:
jableader 2024-04-28 12:13:49 +10:00
parent dbeec48da8
commit 32630a502c
7 changed files with 111 additions and 9 deletions

View file

@ -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>

View file

@ -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);

View 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>

View file

@ -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: {

View file

@ -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' }],

View file

@ -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;
}
} }

View file

@ -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 },