Skip to content

Commit

Permalink
FINISH
Browse files Browse the repository at this point in the history
  • Loading branch information
deipanema committed Oct 18, 2024
2 parents 7d3b9a1 + 9b67eb3 commit 30babab
Show file tree
Hide file tree
Showing 24 changed files with 841 additions and 827 deletions.
80 changes: 40 additions & 40 deletions cypress/e2e/spec.cy.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
// describe("로그인 페이지 테스트", () => {
// it("로그인 성공.", () => {
// cy.intercept("/dashboard*").as("dashboard");

// cy.visit("http://localhost:3000/login");

// cy.get('input[placeholder="이메일"]').type("[email protected]");
// cy.get('input[placeholder="비밀번호"]').type("012345678");
// cy.contains("로그인").click();

// cy.wait("@dashboard").then((_) => {
// cy.contains("대시보드");
// });
// });
// it.only("로그인 실패.", () => {
// cy.visit("http://localhost:3000/login");

// cy.get('input[placeholder="이메일"]').type("[email protected]");
// cy.get('input[placeholder="비밀번호"]').type("wrongnumber");
// cy.contains("로그인").click();

// cy.wait("@dashboard").then(() => {
// cy.contains("대시보드");
// });
// });

// it("로그인 실패.", () => {
// cy.intercept("/login").as("login");

// cy.visit("http://localhost:3000/login");

// cy.get('input[placeholder="이메일"]').type("[email protected]");
// cy.get('input[placeholder="비밀번호"]').type("wrongnumber");
// cy.contains("로그인").click();

// cy.wait("@login").then(() => {
// cy.contains("로그인에 실패했습니다. 다시 시도해 주세요.").should("be.visible");
// });
// });
// });
describe("로그인 페이지 테스트", () => {
it("로그인 성공.", () => {
cy.intercept("/dashboard*").as("dashboard");

cy.visit("http://localhost:3000/login");

cy.get('input[placeholder="이메일"]').type("[email protected]");
cy.get('input[placeholder="비밀번호"]').type("012345678");
cy.contains("로그인").click();

cy.wait("@dashboard").then((_) => {
cy.contains("대시보드");
});
});
// it.only("로그인 실패.", () => {
// cy.visit("http://localhost:3000/login");

// cy.get('input[placeholder="이메일"]').type("[email protected]");
// cy.get('input[placeholder="비밀번호"]').type("wrongnumber");
// cy.contains("로그인").click();

// cy.wait("@dashboard").then(() => {
// cy.contains("대시보드");
// });
// });

// it("로그인 실패.", () => {
// cy.intercept("/login").as("login");

// cy.visit("http://localhost:3000/login");

// cy.get('input[placeholder="이메일"]').type("[email protected]");
// cy.get('input[placeholder="비밀번호"]').type("wrongnumber");
// cy.contains("로그인").click();

// cy.wait("@login").then(() => {
// cy.contains("로그인에 실패했습니다. 다시 시도해 주세요.").should("be.visible");
// });
// });
});
Binary file added public/note-header.webp
Binary file not shown.
Binary file added public/note-kebab.webp
Binary file not shown.
2 changes: 2 additions & 0 deletions src/api/goalAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ErrorType {
export const getGoals = async () => {
try {
const response = await api.get(`/goals`);
// console.log(response);
return response.data;
} catch (error) {
console.error("Goals fetch error:", error);
Expand All @@ -43,6 +44,7 @@ export const PostGoal = async (title: string) => {
export const getGoal = async (id: number) => {
try {
const response = await api.get(`/goals/${id}`);
//console.log(response.data);
return response.data;
} catch (error) {
console.error("Goal fetch error:", error);
Expand Down
36 changes: 29 additions & 7 deletions src/api/noteAPI.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
import { AxiosError } from "axios";
import { toast } from "react-toastify";

import api from "@/lib/api";

import { ErrorType } from "./goalAPI";

// 노트 목록 가져오기 (GET)
export const getNotes = async (id: number) => {
// 노트 리스트 가져오기 (GET)
export const getNotes = async (goalId: number) => {
try {
const response = await api.get(`/notes/${id}`);
const response = await api.get(`/notes/${goalId}`);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
toast.error(axiosError.message);
console.error(axiosError.message);
}
};

// 단일 노트 조회
export async function getNote(noteId: number) {
try {
const response = await api.get(`/notes/${noteId}`);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
console.error(axiosError.message);
}
}

export async function postNotes(todoId: number, title: string, content: string, linkUrl?: string | null) {
try {
const payload: {
Expand All @@ -37,7 +47,7 @@ export async function postNotes(todoId: number, title: string, content: string,
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
toast.error(axiosError.message);
console.error(axiosError.message);
}
}

Expand All @@ -64,6 +74,18 @@ export async function patchNotes(noteId: number, title: string, content: string,
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
toast.error(axiosError.message);
console.error(axiosError.message);
}
}

export default async function deleteNote(noteId: number) {
try {
const response = await api.delete(`notes/${noteId}`);
console.log(response);
console.log(response.data);
return response.data;
} catch (e) {
const error = e as ErrorType;
console.log(error);
}
}
39 changes: 29 additions & 10 deletions src/api/todoAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import api from "@/lib/api";
import { ErrorType } from "./goalAPI";

export type TodoType = {
noteId?: number | null;
noteId: number | null;
done: boolean;
linkUrl?: string | null;
fileUrl?: string | null;
Expand All @@ -31,7 +31,6 @@ export type GoalType = {
export const getAllTodos = async () => {
try {
const response = await api.get(`/todos`);

return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
Expand All @@ -40,9 +39,12 @@ export const getAllTodos = async () => {
}
};

export const getTodos = async (id: number) => {
export const getTodos = async (id: number, done?: boolean, size?: number) => {
try {
const response = await api.get(`/todos?goalId=${id}`);
const response = await api.get(
`/todos?goalId=${id}&${done ? `done=${done}&` : done === false ? "done=false&" : ""}${size ? `size=${size}` : "size=27"}`,
);
//console.log(response.data);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
Expand All @@ -58,7 +60,7 @@ export const postFile = async (file: File) => {
const response = await api.post(`/files`, formData, {
headers: { "Content-Type": "multipart/form-data" },
});

console.log(response.data);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
Expand All @@ -67,25 +69,30 @@ export const postFile = async (file: File) => {
};

export const createTodo = async (
title: string,
fileUrl: string | null,
linkUrl: string | null,
goalId: number,
title?: string,
goalId?: number,
fileUrl?: string | null,
linkUrl?: string | null,
): Promise<TodoType> => {
try {
const payload = { title, goalId, fileUrl, linkUrl };
console.log(title, goalId);
console.log("😲");
const response = await api.post<TodoType>(`/todos`, payload);
console.log(response);
return response.data;
} catch (error) {
console.log(error);
const axiosError = error as AxiosError<ErrorType>;
toast.error(axiosError.message);
toast.error(axiosError.response?.data.message);
throw error;
}
};

export const updateTodo = async (todoId: number, updates: Partial<TodoType>): Promise<TodoType> => {
try {
const response = await api.patch<TodoType>(`/todos/${todoId}`, updates);
console.log();
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
Expand All @@ -103,3 +110,15 @@ export const deleteTodo = async (id: number): Promise<void> => {
throw error;
}
};

// 할 일 상태 토글 함수
export const toggleTodo = async (todoId: number, updatedTodo: Partial<TodoType>) => {
try {
const response = await api.patch(`/todos/${todoId}`, updatedTodo);
return response.data;
} catch (error) {
const axiosError = error as AxiosError<ErrorType>;
toast.error(axiosError.message);
throw error;
}
};
51 changes: 51 additions & 0 deletions src/app/Types/TodoGoalType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export type InitialTodoType = {
title?: string;
fileUrl?: string | null;
linkUrl?: string | null;
goalId?: number;
};

export type TodoType = {
noteId?: number | null;
done: boolean;
linkUrl?: string | null;
fileUrl?: string | null;
title: string;
id: number;
goal: GoalType;
userId: number;
teamId: string;
updatedAt: string;
createdAt: string;
};

export type GoalType = {
id: number;
teamId: string;
title: string;
userId: number;
createdAt: string;
updatedAt: string;
};

export type NoteType = {
content: string;
createdAt: string;
goal: {
id: number;
title: string;
};
id: number;
linkUrl: string;
teamId: string;
title: string;
todo: {
done: boolean;
fileUrl: string | null;
id: number;
linkUrl: string | null;
title: string;
};
updatedAt: string;
userId: number;
};
80 changes: 80 additions & 0 deletions src/app/dashboard/components/NoteItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { toast } from "react-toastify";

import { NoteType } from "@/app/Types/TodoGoalType";
import deleteNote, { getNote } from "@/api/noteAPI";

import NoteViewer from "./NoteViewer";

export default function NoteItem({ note }: { note: NoteType }) {
const router = useRouter();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [isNoteOpen, setIsNoteOpen] = useState(false);
const [noteContent, setNoteContent] = useState<NoteType>();

const loadNoteItemData = async () => {
const response = await getNote(note.id);
if (response) {
console.log(isNoteOpen);
console.log(noteContent);
setNoteContent(response.data);
}
};

const handleDelete = async () => {
const response = await deleteNote(note.id);
if (response) {
toast.success("삭제되었습니다.");
}
};

useEffect(() => {
loadNoteItemData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<div key={note.id} className="relative rounded-xl bg-white p-[24px]">
<div className="mb-[16px] flex justify-between">
<Image src="/note-header.webp" width={28} height={28} alt="note-header-icon" />
<Image
className="cursor-pointer"
src="/note-kebab.webp"
width={28}
height={28}
alt="note-header-icon"
onClick={() => setIsDropdownOpen((prev) => !prev)}
/>
</div>
<h2 className="cursor-pointer text-lg hover:underline" onClick={() => setIsNoteOpen((prev) => !prev)}>
{note.title}
</h2>
<hr className="my-3" />
<div className="flex gap-2">
<span className="rounded-[4px] bg-[#f1f5f9] px-[3px] py-[2px] text-xs">
{note.todo.done ? "Done" : "To do"}
</span>
<h3>{note.todo.title}</h3>
</div>
{isDropdownOpen && (
<div
className="absolute right-10 top-20 z-10 rounded-lg border bg-white"
onMouseLeave={() => setIsDropdownOpen(false)}
>
<p
className="cursor-pointer p-5 hover:bg-slate-200"
onClick={() => router.push(`/dashboard/note/${note.todo.id}?goalId=${note.goal.id}`)}
>
수정하기
</p>
<p className="cursor-pointer p-5 hover:bg-slate-200" onClick={handleDelete}>
삭제하기
</p>
</div>
)}
<NoteViewer isNoteOpen={isNoteOpen} setIsNoteOpen={setIsNoteOpen} noteContent={noteContent} />
</div>
);
}
Loading

0 comments on commit 30babab

Please sign in to comment.