Skip to content

TODO list done #26

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"extends": ["next/babel", "next/core-web-vitals"]
}
"extends": ["next", "next/core-web-vitals"]
}
45 changes: 37 additions & 8 deletions components/AddTask.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
export default function AddTask() {
import axios from "axios"
import { useState } from "react"
import { useAuth } from "../context/auth"
import { API_URL } from "../utils/constants"

export default function addTask() {
const [Task,settheTask]=useState("")
const {token}=useAuth()
const 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.
*/
}

if(Task.length===0)
{
alert('Please Write some Task!')
}
else
{
axios({
headers : {Authorization : "Token "+token},
url : API_URL + 'todo/',
method : 'get',

}).then((res)=>{
const {data}=res
const apiData = {id : data.length, title : Task}
console.log(Task)
alert('Task added!')
axios({
headers : {Authorization : "Token "+token},
url : API_URL + 'todo/create/',
method: "post",
data : apiData
})
})
}
}
return (
<div className='flex items-center max-w-sm mt-24'>
<input
type='text'
className='todo-add-task-input px-4 py-2 placeholder-blueGray-300 text-blueGray-600 bg-white rounded text-sm border border-blueGray-300 outline-none focus:outline-none focus:ring w-full'
placeholder='Enter Task'
value={Task}
onChange={(e)=>{settheTask(e.target.value)}}
/>
<button
type='button'
Expand All @@ -22,4 +51,4 @@ export default function AddTask() {
</button>
</div>
)
}
}
39 changes: 32 additions & 7 deletions components/LoginForm.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import axios from '../utils/axios'
import React, { useState } from 'react'
import { useAuth } from '../context/auth'
import { useRouter } from 'next/router'
import { API_URL } from '../utils/constants';

export default function RegisterForm() {
// no_auth_required();
const [ipusername,settheName]=useState("")
const [pwd,setpwd]=useState("")
const {setToken,token} = useAuth()
const router = useRouter()

const login = () => {
/***
* @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. Set the token in the context (See context/auth.js)
*/
if(ipusername===''||pwd==='')
{
alert('The fields can`t be left empty!');
}
else{
axios({
url:API_URL+"auth/login/",
method : "post",
data : {username:ipusername,password:pwd}
}).then((res)=>{
const {data,status} = res;
setToken(data.token),
router.push('/')
})
}
}

return (
Expand All @@ -19,6 +40,8 @@ export default function RegisterForm() {
name='inputUsername'
id='inputUsername'
placeholder='Username'
value={ipusername}
onChange={(e)=>{settheName(e.target.value)}}
/>

<input
Expand All @@ -27,6 +50,8 @@ export default function RegisterForm() {
name='inputPassword'
id='inputPassword'
placeholder='Password'
value={pwd}
onChange={(e)=>{setpwd(e.target.value)}}
/>

<button
Expand All @@ -40,4 +65,4 @@ export default function RegisterForm() {
</div>
</div>
)
}
}
10 changes: 6 additions & 4 deletions components/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
/* eslint-disable @next/next/no-img-element */
import Link from 'next/link'
import { useAuth } from '../context/auth'
/**
*
* @todo Condtionally render login/register and Profile name in NavBar
*/
import { useState } from 'react'


export default function Nav() {
const { logout, profileName, avatarImage } = useAuth()
const [mounted,setMounted] = useState(true)

// useEffect(()=>{(token)?setMounted(true):setMounted(false)},[])
// useEffect(()=>{(token)?setMounted(true):setMounted(false)},[token])

return (
<nav className='bg-blue-600'>
Expand Down
77 changes: 45 additions & 32 deletions components/TodoListItem.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,69 @@
/* eslint-disable @next/next/no-img-element */
// /* eslint-disable @next/next/no-img-element */

export default function TodoListItem() {
const editTask = (id) => {
/**
* @todo Complete this function.
* @todo 1. Update the dom accordingly
*/
import axios from "axios"
import { useState } from "react"
import { useAuth } from "../context/auth"
import { API_URL } from "../utils/constants"

export default function TodoListItem(props) {
const {token} = useAuth()
const [edit,setEdit] = useState(false)
const [editstring,setEditString] = useState(props.title)
const editTask = () => {

setEdit(true);

}

const deleteTask = (id) => {
/**
* @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.
*/
const deleteTask = (flag) => {
axios({
headers : {Authorization : "Token " + token},
url : API_URL + 'todo/'+flag + '/',
method : 'delete',
})
alert('Task Deleted!')
}

const updateTask = (id) => {
/**
* @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.
*/
axios(
{
headers: {Authorization: 'Token ' + token},
url: 'todo/'+id + '/',
method: 'patch',
data : {title:editstring}
})

}

return (
<>
<li className='border flex border-gray-500 rounded px-2 py-2 justify-between items-center mb-2'>
<li className=' dark:bg-gray-800 border flex border-gray-500 rounded px-2 py-2 justify-between items-center mb-2'>
<input
id='input-button-1'
id={'input-button-'+props.id+''}
type='text'
className='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'
className={!edit ?'hideme' : 'appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-white leading-tight focus:outline-none focus:ring todo-edit-task-input'}
placeholder='Edit The Task'
value={editstring}
onChange={(e)=>{setEditString(e.target.value)}}
/>
<div id='done-button-1' className='hideme'>
<div id={'done-button-'+props.id+''} className={!edit? 'hideme' : ''}>
<button
className='bg-transparent hover:bg-gray-500 text-gray-700 text-sm hover:text-white py-2 px-3 border border-gray-500 hover:border-transparent rounded todo-update-task'
className='bg-transparent dark:bg-green-800 font-bold hover:bg-gray-500 text-gray-700 dark:text-white text-sm hover:text-white py-2 px-3 border border-gray-500 hover:border-transparent rounded todo-update-task'
type='button'
onClick={updateTask(1)}
onClick={()=>updateTask(props.id)}
>
Done
</button>
</div>
<div id='task-1' className='todo-task text-gray-600'>
Sample Task 1
<div id={'task-'+props.id+''} className={!edit ? 'todo-task dark:text-white' : 'hideme'}>
{props.title}
</div>
<span id='task-actions-1' className=''>
<span id={'task-actions-'+props.id+''} className=''>
<button
style={{ marginRight: '5px' }}
type='button'
onClick={editTask(1)}
className='bg-transparent hover:bg-yellow-500 hover:text-white border border-yellow-500 hover:border-transparent rounded px-2 py-2'
onClick={()=>editTask()}
className={!edit ? ' dark:bg-green-800 hover:bg-yellow-500 hover:text-white border border-yellow-500 hover:border-transparent rounded px-2 py-2' : 'hideme'}
>
<img
src='https://res.cloudinary.com/nishantwrp/image/upload/v1587486663/CSOC/edit.png'
Expand All @@ -61,8 +74,8 @@ export default function TodoListItem() {
</button>
<button
type='button'
className='bg-transparent hover:bg-red-500 hover:text-white border border-red-500 hover:border-transparent rounded px-2 py-2'
onClick={deleteTask(1)}
className={!edit ? 'dark:bg-red-500 dark:hover:bg-yellow-500 hover:bg-red-500 hover:text-white border border-red-500 hover:border-transparent rounded px-2 py-2': 'hideme'}
onClick={()=>deleteTask(props.id)}
>
<img
src='https://res.cloudinary.com/nishantwrp/image/upload/v1587486661/CSOC/delete.svg'
Expand All @@ -75,4 +88,4 @@ export default function TodoListItem() {
</li>
</>
)
}
}
2 changes: 1 addition & 1 deletion context/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const AuthProvider = ({ children }) => {
const deleteToken = () => removeCookies('token')
const logout = () => {
deleteToken()
router.push('/login')
router.reload()
}

useEffect(() => {
Expand Down
17 changes: 14 additions & 3 deletions middlewares/auth_required.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/***
* @todo Redirect the user to login page if token is not present.
*/
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { useAuth } from '../context/auth'
function TokenCheck(){
const {token} = useAuth()
const route = useRouter()
useEffect(()=>{
if(!token){
route.push('/login')
}
},[token])
}

export const auth_required = ()=> {TokenCheck()}
16 changes: 13 additions & 3 deletions middlewares/no_auth_required.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/***
* @todo Redirect the user to main page if token is present.
*/
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { useAuth } from '../context/auth'
function TokenCheck(){
const {token} = useAuth()
const route = useRouter()
useEffect(()=>{
if(token){
route.push('/')
}
},[token])
}
export const no_auth_required = ()=>{TokenCheck()}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"dependencies": {
"autoprefixer": "^10.2.6",
"axios": "^0.21.1",
"axios": "^0.21.4",
"izitoast": "^1.4.0",
"next": "11.0.0",
"postcss": "^8.3.5",
Expand All @@ -23,4 +23,4 @@
"eslint": "7.29.0",
"eslint-config-next": "11.0.0"
}
}
}
42 changes: 31 additions & 11 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,50 @@ import AddTask from '../components/AddTask'
import { useEffect, useState } from 'react'
import axios from '../utils/axios'
import { useAuth } from '../context/auth'
import {auth_required} from '../middlewares/auth_required'
import { API_URL } from '../utils/constants'

export default function Home() {
const { token } = useAuth()
const [tasks, setTasks] = useState([])


auth_required();


function getTasks() {
/***
* @todo Fetch the tasks created by the user.
* @todo Set the tasks state and display them in the using TodoListItem component
* The user token can be accessed from the context using useAuth() from /context/auth.js
*/
axios({
headers : {Authorization : "Token " + token},
url : API_URL + 'todo/',
method : "get"
}).then((res)=>{
const {data,status} = res;
setTasks(data);

}).catch(error=>console.log(error))
}

const [tasks, setTasks] = useState([])

const jsx = tasks.map((task)=> (<TodoListItem key={task.id} {...task} />))

useEffect(()=>{
getTasks()
},[tasks])



return (
<div>
<div >
<center>
<AddTask />
<ul className='flex-col mt-9 max-w-sm mb-3 '>
<span className='inline-block bg-blue-600 py-1 mb-2 px-9 text-sm text-white font-bold rounded-full '>
<ul className=' flex-col mt-9 max-w-sm mb-3 '>
<span className='inline-block bg-blue-600 dark:bg-green-800 py-1 mb-2 px-9 text-sm text-white font-bold rounded-full '>
Available Tasks
</span>
<TodoListItem />
{!tasks.length?<h1 className='dark:text-white text-gray-600 py-2'>No Todos</h1>:
jsx}
</ul>
</center>
</div>
)
}
}
Loading