useSWR + ISR + SSG
lib/tasks.js
export async function getAllTasksData() {
const res = await fetch(
new URL(`${process.env.NEXT_PUBLIC_RESTAPI_URL}api/list-task/`)
);
const tasks = await res.json();
const staticfilterdTasks = tasks.sort(
(a, b) => new Date(b.created_at) - new Date(a.created_at)
);
return staticfilterdTasks;
}
export async function getAllTaskIds() {
const res = await fetch(
new URL(`${process.env.NEXT_PUBLIC_RESTAPI_URL}api/list-task/`)
);
const tasks = await res.json();
return tasks.map((task) => {
return {
params: {
id: String(task.id),
},
};
});
}
export async function getTaskData(id) {
const res = await fetch(
new URL(`${process.env.NEXT_PUBLIC_RESTAPI_URL}api/detail-task/${id}/`)
);
const task = await res.json();
// return {
// task,
// };
return task;
}
components/Task.js
import Link from "next/link";
import Cookie from "universal-cookie";
import { useContext } from "react";
import { StateContext } from "../context/StateContext";
const cookie = new Cookie();
export default function Task({ task, taskDeleted }) {
const { setSelectedTask } = useContext(StateContext);
const deleteTask = async () => {
await fetch(`${process.env.NEXT_PUBLIC_RESTAPI_URL}api/tasks/${task.id}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `JWT ${cookie.get("access_token")}`,
},
}).then((res) => {
if (res.status === 401) {
alert("JWT Token not valid");
}
});
taskDeleted();
};
return (
<div>
<span>{task.id}</span>
{" : "}
<Link href={`/tasks/${task.id}`}>
<span className="cursor-pointer text-white border-b border-gray-500 hover:bg-gray-600">
{task.title}
</span>
</Link>
<div className="float-right ml-20">
<svg
onClick={() => setSelectedTask(task)}
className="w-6 h-6 float-left cursor-pointer"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
<svg
onClick={deleteTask}
className="w-6 h-6 mr-2 cursor-pointer"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
/>
</svg>
</div>
</div>
);
}
pages/Utask-page.js
import { useEffect } from "react";
import Layout from "../components/Layout";
import Link from "next/link";
import { getAllTasksData } from "../lib/tasks";
import Task from "../components/Task";
import useSWR from "swr";
import StateContextProvider from "../context/StateContext";
import TaskForm from "../components/TaskForm";
const fetcher = (url) => fetch(url).then((res) => res.json());
const apiUrl = `${process.env.NEXT_PUBLIC_RESTAPI_URL}api/list-task/`;
export default function TaskPage({ staticfilterdTasks }) {
const { data: tasks, mutate } = useSWR(apiUrl, fetcher, {
fallbackData: staticfilterdTasks,
});
const filteredTasks = tasks?.sort(
(a, b) => new Date(b.created_at) - new Date(a.created_at)
);
useEffect(() => {
mutate();
}, []);
return (
<StateContextProvider>
<Layout title="Task page">
<TaskForm taskCreated={mutate} />
<ul>
{filteredTasks &&
filteredTasks.map((task) => (
<Task key={task.id} task={task} taskDeleted={mutate} />
))}
</ul>
<Link href="/main-page">
<div className="flex cursor-pointer mt-12">
<svg
className="w-6 h-6 mr-3"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M11 19l-7-7 7-7m8 14l-7-7 7-7"
/>
</svg>
<span>Back to main page</span>
</div>
</Link>
</Layout>
</StateContextProvider>
);
}
export async function getStaticProps() {
const staticfilterdTasks = await getAllTasksData();
return {
props: { staticfilterdTasks },
revalidate: 3,
};
}