diff --git a/.gitignore b/.gitignore index 8f322f0d..73db4c0e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# vscode +/.vscode diff --git a/assets/icons/check.svg b/assets/icons/check.svg new file mode 100644 index 00000000..cd2bd830 --- /dev/null +++ b/assets/icons/check.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/checkbox_checked.svg b/assets/icons/checkbox_checked.svg new file mode 100644 index 00000000..62bc5549 --- /dev/null +++ b/assets/icons/checkbox_checked.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/checkbox_empty.svg b/assets/icons/checkbox_empty.svg new file mode 100644 index 00000000..0e06cb40 --- /dev/null +++ b/assets/icons/checkbox_empty.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/cross.svg b/assets/icons/cross.svg new file mode 100644 index 00000000..4dcdd074 --- /dev/null +++ b/assets/icons/cross.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/edit.svg b/assets/icons/edit.svg new file mode 100644 index 00000000..36b8ce83 --- /dev/null +++ b/assets/icons/edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/plus_big.svg b/assets/icons/plus_big.svg new file mode 100644 index 00000000..1c0ff1a9 --- /dev/null +++ b/assets/icons/plus_big.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/plus_black.svg b/assets/icons/plus_black.svg new file mode 100644 index 00000000..935663bd --- /dev/null +++ b/assets/icons/plus_black.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/icons/plus_white.svg b/assets/icons/plus_white.svg new file mode 100644 index 00000000..604eb17b --- /dev/null +++ b/assets/icons/plus_white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/done.png b/assets/images/done.png new file mode 100644 index 00000000..709538c1 Binary files /dev/null and b/assets/images/done.png differ diff --git a/assets/images/empty_done.png b/assets/images/empty_done.png new file mode 100644 index 00000000..fc0b115c Binary files /dev/null and b/assets/images/empty_done.png differ diff --git a/assets/images/empty_todo.png b/assets/images/empty_todo.png new file mode 100644 index 00000000..d0d5faed Binary files /dev/null and b/assets/images/empty_todo.png differ diff --git a/assets/images/img.png b/assets/images/img.png new file mode 100644 index 00000000..d945c73e Binary files /dev/null and b/assets/images/img.png differ diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 00000000..d9062cbc Binary files /dev/null and b/assets/images/logo.png differ diff --git a/assets/images/logo_text.png b/assets/images/logo_text.png new file mode 100644 index 00000000..b08a104b Binary files /dev/null and b/assets/images/logo_text.png differ diff --git a/assets/images/memo.png b/assets/images/memo.png new file mode 100644 index 00000000..6fdebdc2 Binary files /dev/null and b/assets/images/memo.png differ diff --git a/assets/images/todo.png b/assets/images/todo.png new file mode 100644 index 00000000..c7f995bf Binary files /dev/null and b/assets/images/todo.png differ diff --git a/components/Btn.module.css b/components/Btn.module.css new file mode 100644 index 00000000..e331d3d6 --- /dev/null +++ b/components/Btn.module.css @@ -0,0 +1,77 @@ +button.btn { + position: relative; + height: 56px; +} + +button.btn.large { + width: 168px; +} + +button.btn.small { + width: 56px; +} + +button.btn div { + position: absolute; + height: 52px; + border: 2px solid var(--slate900); + border-radius: 24px; +} + +button.btn.large div { + width: 164.35px; +} + +button.btn.small div { + width: 54.78px; +} + +button.btn div.content { + top: 0; + left: 0; + display: flex; + background-color: var(--slate200); + color: var(--slate900); + line-height: 18px; + font-size: 16px; + font-weight: 700; +} + +button.btn div.content.delete { + background-color: var(--rose500); + color: white; +} + +button.btn:hover div.content.add { + background-color: var(--violet600); + color: white; +} + +button.btn:hover div.content.edit { + background-color: var(--lime300); +} + +button.btn.large div.content { + align-items: center; + gap: 4px; + justify-content: center; +} + +button.btn.small div.content { + padding: 16px; +} + +button.btn div.content.add img#light, +button.btn:hover div.content.add img#dark { + display: none; +} + +button.btn:hover div.content.add img#light { + display: initial; +} + +button.btn div.shadow { + bottom: 0; + right: 0; + background-color: var(--slate900); +} diff --git a/components/Btn.tsx b/components/Btn.tsx new file mode 100644 index 00000000..524bc2f9 --- /dev/null +++ b/components/Btn.tsx @@ -0,0 +1,55 @@ +import { ButtonHTMLAttributes, useMemo } from "react"; +import Image from "next/image"; +import ic_plus_black from "@/assets/icons/plus_black.svg"; +import ic_plus_white from "@/assets/icons/plus_white.svg"; +import ic_cross from "@/assets/icons/cross.svg"; +import ic_check from "@/assets/icons/check.svg"; +import styles from "./Btn.module.css"; + +interface Props extends ButtonHTMLAttributes { + size?: "large" | "small"; + mode: "add" | "delete" | "edit"; +} + +const CONTENT: Record = { + add: "추가하기", + delete: "삭제하기", + edit: "수정 완료", +}; + +export default function Btn({ + className = "", + size = "large", + mode, + ...props +}: Props) { + const img = useMemo(() => { + switch (mode) { + case "add": + return { alt: "plus", src: ic_plus_black }; + case "delete": + return { alt: "cross", src: ic_cross }; + case "edit": + return { alt: "check", src: ic_check }; + } + }, [mode]); + + return ( + + ); +} diff --git a/components/CheckList.module.css b/components/CheckList.module.css new file mode 100644 index 00000000..db48118c --- /dev/null +++ b/components/CheckList.module.css @@ -0,0 +1,26 @@ +.check-list { + display: flex; + align-items: center; + gap: 16px; + height: 50px; + padding: 0 12px; + border: 2px solid var(--slate900); + border-radius: 9999px; + color: var(--slate800); + line-height: 18px; + font-size: 16px; + font-weight: 400; +} + +.check-list.true { + background-color: var(--violet100); + text-decoration: line-through 1px; +} + +.check-list.false { + background-color: white; +} + +.check-list button { + line-height: 0; +} diff --git a/components/CheckList.tsx b/components/CheckList.tsx new file mode 100644 index 00000000..62b7b100 --- /dev/null +++ b/components/CheckList.tsx @@ -0,0 +1,32 @@ +import { HTMLAttributes, MouseEventHandler } from "react"; +import Image from "next/image"; +import ic_checked from "@/assets/icons/checkbox_checked.svg"; +import ic_empty from "@/assets/icons//checkbox_empty.svg"; +import styles from "./CheckList.module.css"; + +interface Props extends HTMLAttributes { + isChecked: boolean; + onButtonClick: MouseEventHandler; +} + +export default function CheckList({ + className = "", + children, + isChecked, + onButtonClick, + ...props +}: Props) { + return ( +
+ + {children} +
+ ); +} diff --git a/components/Gnb.module.css b/components/Gnb.module.css new file mode 100644 index 00000000..f196405f --- /dev/null +++ b/components/Gnb.module.css @@ -0,0 +1,22 @@ +nav.gnb { + z-index: 20; + position: sticky; + top: 0; + left: 0; + right: 0; + height: 60px; + border-bottom: 1px solid var(--slate200); + background-color: white; +} + +nav.gnb > div { + max-width: 1200px; + margin: 0 auto; + padding: 10px 24px 9px; + line-height: 0; +} + +nav.gnb > div a { + display: inline-block; + line-height: 0; +} diff --git a/components/Gnb.tsx b/components/Gnb.tsx new file mode 100644 index 00000000..79af1c3c --- /dev/null +++ b/components/Gnb.tsx @@ -0,0 +1,16 @@ +import Link from "next/link"; +import Image from "next/image"; +import logo from "@/assets/images/logo_text.png"; +import styles from "./Gnb.module.css"; + +export default function Gnb() { + return ( + + ); +} diff --git a/components/Search.module.css b/components/Search.module.css new file mode 100644 index 00000000..cae1b934 --- /dev/null +++ b/components/Search.module.css @@ -0,0 +1,35 @@ +.search { + position: relative; + display: block; + height: 56px; +} + +.search > * { + width: calc(100% - 4px); + height: 52.5px; + border: 2px solid var(--slate900); + border-radius: 24px; +} + +.search > input { + position: absolute; + top: 0; + left: 0; + padding: 15px 22px; + background-color: var(--slate100); + color: var(--slate900); + line-height: 18px; + font-size: 16px; + font-weight: 400; +} + +.search > input::placeholder { + color: var(--slate500); +} + +.search > div { + position: absolute; + bottom: 0; + right: 0; + background-color: var(--slate900); +} diff --git a/components/Search.tsx b/components/Search.tsx new file mode 100644 index 00000000..70120faa --- /dev/null +++ b/components/Search.tsx @@ -0,0 +1,15 @@ +import { InputHTMLAttributes, Ref } from "react"; +import styles from "./Search.module.css"; + +interface Props extends InputHTMLAttributes { + ref?: Ref; +} + +export default function Search({ className = "", style, ...props }: Props) { + return ( +