import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { NextPage } from "next"; import { useRouter } from "next/router"; import { TodoClient, Todos } from "../util/TodoClient"; import styles from "../styles/Todo.module.css"; import { SessionExpiredModal } from "../components/SessionExpiredModal"; import { Hanko } from "@teamhanko/hanko-elements"; const hankoAPI = process.env.NEXT_PUBLIC_HANKO_API!; const todoAPI = process.env.NEXT_PUBLIC_TODO_API!; const Todo: NextPage = () => { const router = useRouter(); const todoClient = useMemo(() => new TodoClient(todoAPI), []); const [hankoClient, setHankoClient] = useState(); const [todos, setTodos] = useState([]); const [description, setDescription] = useState(""); const [error, setError] = useState(null); const modalRef = useRef(null); useEffect(() => { import("@teamhanko/hanko-elements").then(({ Hanko }) => setHankoClient(new Hanko(hankoAPI))); }, []); const redirectToProfile = () => { router.push("/profile").catch(setError) } const redirectToLogin = useCallback(() => { router.push("/").catch(setError) }, [router]); const addTodo = (event: React.FormEvent) => { event.preventDefault(); const todo = {description, checked: false}; todoClient .addTodo(todo) .then((res) => { if (res.status === 401) { modalRef.current?.showModal(); return; } setDescription(""); listTodos(); return; }) .catch((e) => { setError(e); }); }; const listTodos = useCallback(() => { todoClient .listTodos() .then((res) => { if (res.status === 401) { modalRef.current?.showModal(); return; } return res.json(); }) .then((todo) => { if (todo) { setTodos(todo); } }) .catch((e) => { setError(e); }); }, [todoClient]); const patchTodo = (id: string, checked: boolean) => { todoClient .patchTodo(id, checked) .then((res) => { if (res.status === 401) { modalRef.current?.showModal(); return; } listTodos(); return; }) .catch((e) => { setError(e); }); }; const deleteTodo = (id: string) => { todoClient .deleteTodo(id) .then((res) => { if (res.status === 401) { modalRef.current?.showModal(); return; } listTodos(); return; }) .catch((e) => { setError(e); }); }; const logout = () => { hankoClient?.user .logout() .catch((e) => { setError(e); }); }; const changeDescription = (event: React.ChangeEvent) => { setDescription(event.currentTarget.value); }; const changeCheckbox = (event: React.ChangeEvent) => { const {currentTarget} = event; patchTodo(currentTarget.value, currentTarget.checked); }; useEffect(() => { if (!hankoClient) { return; } if (hankoClient.session.isValid()) { listTodos(); } else { redirectToLogin(); } }, [hankoClient, listTodos, redirectToLogin]); useEffect(() => hankoClient?.onUserLoggedOut(() => { redirectToLogin(); }), [hankoClient, redirectToLogin]); useEffect(() => hankoClient?.onSessionExpired(() => { modalRef.current?.showModal(); }), [hankoClient]); return ( <>

Todos

{error?.message}
{todos.map((todo, index) => (
))}
); }; export default Todo;