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

Completed tasks #11

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the use of .gitignore to prevent commiting unwanted files

"typescript.tsdk": "node_modules/typescript/lib"
}
27 changes: 21 additions & 6 deletions components/addTask.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<label for="add task" class="flex-1">
<input
type="text"
v-model="taskadded"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read about using the right name convention for Javascript

name="add task"
class="
todo-add-task-input
Expand Down Expand Up @@ -46,15 +47,29 @@
import { defineComponent } from '@nuxtjs/composition-api'

export default defineComponent({
data() {
return{
taskadded: ""
}
},
emits: ['newTask'],
methods: {
addTask() {
/**
* @todo Complete this function.
* @todo 1. Send the request to add the task to the backend server.
* @todo 2. Add the task in the dom.
* @hint use emit to make a event that parent can observe
*/
if (this.taskadded == "" ){
this.$toast.error("Empty tasks can't be added")
}
else if (this.taskadded.length > 255 ){
this.$toast.error("Maximum length of task should be 255")
}
else{
const task = {
title: this.taskadded
}
this.$axios.post('todo/create/', task , {headers: { Authorization: 'Token ' + this.$store.getters.token}})
this.$toast.success("Task added successfully.")
this.$emit('newTask')
}
this.taskadded = ""
},
},
})
Expand Down
2 changes: 2 additions & 0 deletions components/navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export default defineComponent({
logout() {
this.$store.commit('setToken', null)
this.$router.replace('/login')
this.$toast.success("Logged out successfully.")

},
},
})
Expand Down
12 changes: 12 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,16 @@ export default defineComponent({
.todo-task {
max-width: 260px;
}

.slide-fade-enter-active {
transition: all 0.3s ease;
}
.slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter-from, .slide-fade-leave-to{
transform: translateX(10px);
opacity: 0;
}

</style>
10 changes: 10 additions & 0 deletions middleware/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ export default defineNuxtMiddleware((context) => {
* @todo Redirect the user to main page if token is present in store
* @hints check what propeties context has
*/

const location = context.route.fullPath
const token = context.store.getters.token
console.log(location)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove all console.log() after done debugging

console.log(token===null)
if (token === null && location !== '/login') {
context.redirect('/login')
} else if (token !== null && location !== '/') {
context.redirect('/')
}
})
124 changes: 75 additions & 49 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<main class="max-w-lg mx-auto px-6">
<add-task @newTask="getTasks" />
<transition>
<transition name="slide-fade">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use transition groups to apply the effect to each list element

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have now applied transition to individual todos but it works only when todo is deleted. When todo is added this transition is not applied because getTask function is called for getting the entire list of todos.

<span v-if="loading">Fetching Tasks....</span>
<ul v-else class="flex-col mt-9 mx-auto">
<li
Expand All @@ -22,18 +22,18 @@
<label :for="todo.id">
<input
:id="todo.id"
v-model="altTitle"
type="text"
:class="[
'hideme appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring todo-edit-task-input',
{ hideme: !(hideitem === todo.id) }, 'appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:ring todo-edit-task-input',
]"
:name="todo.title"
placeholder="Edit The Task"
/>
</label>
<div class="">
<div :class="[{ hideme: !(hideitem === todo.id) }]">
<button
class="
hideme
bg-transparent
hover:bg-gray-500
text-gray-700 text-sm
Expand All @@ -51,10 +51,10 @@
Done
</button>
</div>
<div :class="['todo-task text-gray-600']">
<div :class="[{ hideme: hideitem === todo.id }, 'todo-task text-gray-600']">
{{ todo.title }}
</div>
<span class="">
<span :class="[{ hideme: hideitem === todo.id }]">
<button
style="margin-right: 5px"
type="button"
Expand Down Expand Up @@ -104,26 +104,18 @@
</template>

<script lang>
import { defineComponent } from '@nuxtjs/composition-api'
import { defineComponent, ref } from '@nuxtjs/composition-api'
import addTask from '~/components/addTask.vue'

export default defineComponent({
middleware: 'auth',
components: { addTask },
data() {
return {
hideitem: null,
altTitle: "",
hello: 'hello world!',
todos: [
{
title: 'Henlo',
id: 1,
editing: false,
},
{
title: 'Frens',
id: 2,
editing: false,
},
],
todos: [],
loading: false,
}
},
Expand All @@ -132,40 +124,74 @@ export default defineComponent({
},
methods: {
async getTasks() {
/***
* @todo Fetch the tasks created by the user and display them.
* @todo also the function to display a single new task added
* @hints use store and set loading true
* @caution you have to assign new value to todos for it to update
*/

this.loading = true
try {
const res = await this.$axios.get('todo/', {headers: { Authorization: 'Token ' + this.$store.getters.token}})
this.todos = res.data
console.log(res)
this.todos.forEach((index) => {
index.editing = false
})
this.loading = false
} catch (err) {
console.log(err)
this.loading = false
}
},

updateTask(_index, _id) {

this.todos[_index].editing = !this.todos[_index].editing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better way to edit would have been to fill edit space with the pre-existing task

//Checking if the updated value already exists within the todo list
var check = false
this.todos.forEach((todo) => {
if( todo.title === this.altTitle ){
check = true
return
}
})

if( this.altTitle === "" ){
this.$toast.error("Todo not edited.")
}
else if (check){
this.$toast.error("The entered todo alreay exists in the list.")
}
else{
const dataforAPI ={
id: _id,
title: this.altTitle
}
this.$axios.patch('todo/'+ _id +'/', dataforAPI , {headers: { Authorization: 'Token ' + this.$store.getters.token}})
.then(() => {
this.$toast.success("Todo edited successfully")
})
this.todos[_index].title = dataforAPI.title
}
this.altTitle = ""
this.hideitem = null
},
/**
* Function to update a single todo
* @argument {number} _index - index of element to update in todos array
* @argument {number} _id - id of todo obtained from API
* @todo Complete this function.
* @todo 1. Send the request to update the task to the backend server.
* @todo 2. Update the task in the dom.
*/
updateTask(_index, _id) {},
/**
* toggle visibility of input and buttons for a single todo
* @argument {number} index - index of element to toggle
* @todo add in bindings in dom so that 'hideme' class is dynamic or use conditional rendering
* @hint read about class bindings in vue
*/

editTask(index) {
this.todos[index].editing = !this.todos[index].editing
console.log(this.todos[index].editing)
this.hideitem = this.todos[index].id
},

deleteTask(_index, _id) {
const dataforAPI = {
id: _id
}
console.log(dataforAPI.id)
this.$axios.delete('todo/'+ _id +'/', {headers: { Authorization: 'Token ' + this.$store.getters.token}})
.then((response) =>{
this.todos = this.todos.filter((todo) => todo.id !== _id)
}).catch((err) => {
console.log(err)
})
this.$toast.info("Todo deleted successfully.")
},
/**
* Function to delete a single todo
* @argument {number} _index - index of element to update in todos array
* @argument {number} _id - id of todo obtained from API
* @todo Complete this function.
* @todo 1. Send the request to delete the task to the backend server.
* @todo 2. Remove the task from the dom.
*/
deleteTask(_index, _id) {},
},
})
</script>
56 changes: 45 additions & 11 deletions pages/login/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<label for="inputUsername">
<input
id="inputUsername"
v-model="username"
type="text"
class="block border border-grey-light w-full p-3 rounded mb-4"
name="inputUsername"
Expand All @@ -15,6 +16,7 @@
<label for="password">
<input
id="inputPassword"
v-model="password"
type="password"
class="block border border-grey-light w-full p-3 rounded mb-4"
name="inputPassword"
Expand Down Expand Up @@ -46,24 +48,56 @@
</template>

<script>
import { useContext } from '@nuxtjs/composition-api'
import { defineComponent } from '@vue/composition-api'
import { useContext, reactive } from '@nuxtjs/composition-api'
import { defineComponent, toRefs } from '@vue/composition-api'

export default defineComponent({
middleware: 'auth',
setup() {
const { $toast } = useContext()
const { redirect, $toast, $axios, store } = useContext()

const state = reactive({
username: '',
password: ''
})

const validateField = () => {
if (
state.username === '' ||
state.password === ''
) {
$toast.error('Please enter correct login credentials.')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Providing feedback to user about error will be better ie username/password cannot be empty

console.log("shit")
return false
}
return true
}

function login() {
$toast.info('Complete Me!')
/***
* @todo Complete this function.
* @todo 1. Write code for form validation.
* @todo 2. Fetch the auth token from backend and login the user.
* @todo 3. Commit token to Vuex Store
* @hints checkout register/index.vue
*/

if (!validateField()) return

const data = {
username: state.username,
password: state.password
}

$toast.info('Please wait...')

$axios
.$post('auth/login/', data)
.then(({ token }) => {
store.commit('setToken', token)
redirect('/')
$toast.success("Logged in successfully")
})
.catch(() => {
$toast.error('Please enter correct login credentials.')
})
}

return {
...toRefs(state),
login,
}
},
Expand Down
Loading