diff --git a/package-lock.json b/package-lock.json index d61636a..15d4750 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,8 @@ "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", - "ua-parser-js": "^2.0.0" + "ua-parser-js": "^2.0.0", + "swiper": "^11.2.1" }, "devDependencies": { "@eslint/eslintrc": "^3", @@ -6777,6 +6778,24 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/swiper": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.1.tgz", + "integrity": "sha512-62G69+iQRIfUqTmJkWpZDcX891Ra8O9050ckt1/JI2H+0483g+gq0m7gINecDqMtDh2zt5dK+uzBRxGhGOOvQA==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/tailwindcss": { "version": "3.4.17", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", diff --git a/package.json b/package.json index a2e11ad..67e9a70 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "next-themes": "^0.4.4", "react": "^19.0.0", "react-dom": "^19.0.0", - "ua-parser-js": "^2.0.0" + "ua-parser-js": "^2.0.0", + "swiper": "^11.2.1" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/public/images/chat/advanced.png b/public/images/chat/advanced.png new file mode 100644 index 0000000..a23716c Binary files /dev/null and b/public/images/chat/advanced.png differ diff --git a/public/images/chat/beginner.png b/public/images/chat/beginner.png new file mode 100644 index 0000000..a62516c Binary files /dev/null and b/public/images/chat/beginner.png differ diff --git a/public/images/chat/intermediate.png b/public/images/chat/intermediate.png new file mode 100644 index 0000000..46a290f Binary files /dev/null and b/public/images/chat/intermediate.png differ diff --git a/src/app/chat/components/LevelCard/LevelCard.tsx b/src/app/chat/components/LevelCard/LevelCard.tsx new file mode 100644 index 0000000..e2015cf --- /dev/null +++ b/src/app/chat/components/LevelCard/LevelCard.tsx @@ -0,0 +1,32 @@ +import clsx from "clsx"; +import { Level } from "../../data"; +import Image from "next/image"; + +const LevelCard = ({ + level, + isSelected, + onClick, + image, +}: { + level: Level; + isSelected: boolean; + onClick: () => void; + image: string; +}) => { + return ( + + ); +}; + +export default LevelCard; diff --git a/src/app/chat/components/LevelCard/index.ts b/src/app/chat/components/LevelCard/index.ts new file mode 100644 index 0000000..f6b585a --- /dev/null +++ b/src/app/chat/components/LevelCard/index.ts @@ -0,0 +1 @@ +export { default } from "./LevelCard"; \ No newline at end of file diff --git a/src/app/chat/components/Questions/Question.tsx b/src/app/chat/components/Questions/Question.tsx new file mode 100644 index 0000000..fa1aa3b --- /dev/null +++ b/src/app/chat/components/Questions/Question.tsx @@ -0,0 +1,33 @@ +import clsx from "clsx"; +import { QuestionType } from "../../data"; + +interface QuestionProps { + id: number; + type: QuestionType; + question: string; + isActive: boolean; + isPrev: boolean; +} + +const Question = ({ id, type, question, isActive, isPrev }: QuestionProps) => { + return ( +
+ +
+ ); +}; + +export default Question; diff --git a/src/app/chat/components/Questions/Questions.tsx b/src/app/chat/components/Questions/Questions.tsx new file mode 100644 index 0000000..943edcf --- /dev/null +++ b/src/app/chat/components/Questions/Questions.tsx @@ -0,0 +1,32 @@ +import { Navigation } from "swiper/modules"; +import { Swiper, SwiperSlide } from "swiper/react"; +import { questions } from "../../data"; +import Question from "./Question"; +import "swiper/css"; +import "swiper/css/navigation"; + +const Questions = () => { + return ( + <> + + {questions.map((question) => ( + + {({ isActive, isPrev }) => ( + + )} + + ))} + + + ); +}; + +export default Questions; diff --git a/src/app/chat/components/Questions/index.ts b/src/app/chat/components/Questions/index.ts new file mode 100644 index 0000000..f348cbd --- /dev/null +++ b/src/app/chat/components/Questions/index.ts @@ -0,0 +1 @@ +export { default } from "./Questions"; \ No newline at end of file diff --git a/src/app/chat/components/Title/Title.tsx b/src/app/chat/components/Title/Title.tsx new file mode 100644 index 0000000..b1996f9 --- /dev/null +++ b/src/app/chat/components/Title/Title.tsx @@ -0,0 +1,12 @@ +const Title = () => { + return ( +
+

오늘은 어떤 정보를 쌓아볼까요?

+

+ 블록체인에 얼마나 관심을 가지고 계신가요? 적합한 질문을 추천드릴게요! +

+
+ ); +}; + +export default Title; diff --git a/src/app/chat/components/Title/index.ts b/src/app/chat/components/Title/index.ts new file mode 100644 index 0000000..c3ebe86 --- /dev/null +++ b/src/app/chat/components/Title/index.ts @@ -0,0 +1 @@ +export { default } from "./Title"; diff --git a/src/app/chat/data.ts b/src/app/chat/data.ts new file mode 100644 index 0000000..ba380c5 --- /dev/null +++ b/src/app/chat/data.ts @@ -0,0 +1,39 @@ +export enum Level { + BEGINNER = "초급", + INTERMEDIATE = "중급", + ADVANCED = "고급", +} + +export enum QuestionType { + CONCEPT = "개념", + EXAMPLE = "예제", + QUESTION = "질문", +} + +export const questions = [ + { + id: 1, + type: QuestionType.CONCEPT, + question: "블록체인이란 무엇인가요?", + }, + { + id: 2, + type: QuestionType.EXAMPLE, + question: "이더리움의 블록체인 구조 예시를 알려줘.", + }, + { + id: 3, + type: QuestionType.QUESTION, + question: "블록체인은 어떤 문제를 해결하려고 만들어졌어?", + }, + { + id: 4, + type: QuestionType.CONCEPT, + question: "블록체인이 무엇인가요?", + }, + { + id: 5, + type: QuestionType.QUESTION, + question: "블록체인은 어떤 문제를 해결하려고 만들어졌어?", + }, +]; diff --git a/src/app/chat/page.tsx b/src/app/chat/page.tsx new file mode 100644 index 0000000..92b6ed2 --- /dev/null +++ b/src/app/chat/page.tsx @@ -0,0 +1,35 @@ +"use client"; + +import ThemeSwitch from "@/components/ThemeSwitch"; +import { Level } from "./data"; +import LevelCard from "./components/LevelCard/LevelCard"; +import { useState } from "react"; +import Title from "./components/Title"; +import Questions from "./components/Questions"; + +export default function ChatPage() { + const [selectedLevel, setSelectedLevel] = useState(Level.BEGINNER); + + return ( +
+
+ + <div className="flex flex-col items-center gap-[3rem]"> + <div className="flex gap-[1.8rem]"> + {Object.entries(Level).map(([key, value]) => ( + <LevelCard + key={key} + level={value} + isSelected={selectedLevel === value} + onClick={() => setSelectedLevel(value)} + image={`/images/chat/${key.toLowerCase()}.png`} + /> + ))} + </div> + <Questions /> + </div> + <ThemeSwitch /> + </div> + </main> + ); +} diff --git a/src/app/globals.css b/src/app/globals.css index 25eaf0c..db7cf81 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,6 +3,7 @@ @tailwind utilities; :root { + --color-background: #ffffff; --color-gray-100: #f8fafb; --color-gray-200: #f2f4f5; --color-gray-300: #eaeced; @@ -40,6 +41,7 @@ } .dark { + --color-background: #0e0e0e; --color-gray-100: #1d1d1d; --color-gray-200: #28292a; --color-gray-300: #464848; @@ -75,3 +77,9 @@ 0px 1px 4px 0px rgba(152, 154, 155, 0.3), 0px 0px 2px 0px rgba(152, 154, 155, 0.2); } + +html, +body { + font-size: 10px; + color: var(--color-gray-900); +} \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index adb6a21..cafb47c 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -41,6 +41,7 @@ module.exports = { "system-green": "var(--color-system-green)", white: "#FFFFFF", dark: "#0E0E0E", + background: "var(--color-background)", }, fontSize: { // headline