diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index fcbc27b5..fdc15023 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -5,15 +5,15 @@ on: - master jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-latest strategy: matrix: - node-version: [ 16.x ] + node-version: [20.x] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - name: Create env file diff --git a/__tests__/pages/home/components/RightSection/renderingCodeFlowUnitTest.test.tsx b/__tests__/pages/home/components/RightSection/renderingCodeFlowUnitTest.test.tsx index bc8d4777..f2739732 100644 --- a/__tests__/pages/home/components/RightSection/renderingCodeFlowUnitTest.test.tsx +++ b/__tests__/pages/home/components/RightSection/renderingCodeFlowUnitTest.test.tsx @@ -1,21 +1,26 @@ import { ReactNode } from "react"; import { render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; -import { renderingCodeFlow } from "@/pages/Home/components/RightSection/renderingCodeFlow.tsx"; -import { ForItem } from "@/pages/Home/types/forItem"; +import { renderingCodeFlow } from "@/pages/Visualization/components/RightSection/renderingCodeFlow"; +import { ForItem } from "@/pages/Visualization/types/codeFlow/forItem"; type Props = { children: ReactNode; forItem: ForItem; }; // ForBox 컴포넌트 모킹 // ForBox의 실제 경로에서 forItem과 children인자만 가지고와서 사용한다 -jest.mock("@/pages/Home/components/RightSection/components/ForBox/ForBox", () => ({ forItem, children }: Props) => ( - // 실제 ForBox의 컴포넌트를 가지고 오는 것이 아닌 가짜로 만들어서 사용 -
- For Box: {forItem.id} -
{children}
-
-)); +jest.mock( + "@/pages/Visualization/components/RightSection/components/ForBox/ForBox", + () => + ({ forItem, children }: Props) => + ( + // 실제 ForBox의 컴포넌트를 가지고 오는 것이 아닌 가짜로 만들어서 사용 +
+ For Box: {forItem.id} +
{children}
+
+ ) +); describe("renderingCodeFlow 함수", () => { it("forBox 컴포넌트 하나만 출력하는 테스트", () => { diff --git a/__tests__/pages/home/homeUnitTest.test.tsx b/__tests__/pages/home/homeUnitTest.test.tsx index 59bb58fe..8edb5793 100644 --- a/__tests__/pages/home/homeUnitTest.test.tsx +++ b/__tests__/pages/home/homeUnitTest.test.tsx @@ -3,8 +3,8 @@ import React from "react"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import forPrintMockData from "./samples/successForAndPrintResponseBody.json"; -import Home from "../../../src/pages/Home/Home"; - +import Home from "../../../src/pages/Visualization/Visualization"; +import { MemoryRouter } from "react-router-dom"; // 브라우저API 모킹 (window as any).fetch = jest.fn(); window.alert = jest.fn(); @@ -12,7 +12,11 @@ window.alert = jest.fn(); // reactQuery를 사용하는 컴포넌트를 테스트하기 위해 컴포넌트를 렌더링 하는 함수 const renderWithQueryClient = (component: React.ReactElement) => { const queryClient = new QueryClient(); - return render({component}); + return render( + + {component} + + ); }; describe("백엔드로 부터 Object 외에 다른 response body(code) 를 받았을 때", () => { diff --git a/package-lock.json b/package-lock.json index 819b58fd..5924eb6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "framer-motion": "^11.2.12", "lodash": "^4.17.21", "react": "^18.2.0", + "react-cookie": "^7.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.23.1", "react-split": "^2.0.14", @@ -47,6 +48,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", + "jose": "^5.8.0", "msw": "^2.3.1", "ts-jest": "^29.2.4", "ts-node": "^10.9.2", @@ -3925,8 +3927,7 @@ "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" }, "node_modules/@types/estree": { "version": "1.0.5", @@ -3943,6 +3944,16 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -4016,14 +4027,12 @@ "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "devOptional": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -5047,8 +5056,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/data-urls": { "version": "3.0.2", @@ -6066,6 +6074,21 @@ "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", "dev": true }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -7034,6 +7057,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jose": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.8.0.tgz", + "integrity": "sha512-E7CqYpL/t7MMnfGnK/eg416OsFCVUrU/Y3Vwe7QjKhu/BkS1Ms455+2xsqZQVN57/U2MHMBvEb5SrmAZWAIntA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8009,6 +8042,20 @@ "node": ">=0.10.0" } }, + "node_modules/react-cookie": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-7.2.0.tgz", + "integrity": "sha512-mqhPERUyfOljq5yJ4woDFI33bjEtigsl8JDJdPPeNhr0eSVZmBc/2Vdf8mFxOUktQxhxTR1T+uF0/FRTZyBEgw==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.5", + "hoist-non-react-statics": "^3.3.2", + "universal-cookie": "^7.0.0" + }, + "peerDependencies": { + "react": ">= 16.3.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -8883,6 +8930,25 @@ "node": ">=4" } }, + "node_modules/universal-cookie": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-7.2.0.tgz", + "integrity": "sha512-PvcyflJAYACJKr28HABxkGemML5vafHmiL4ICe3e+BEKXRMt0GaFLZhAwgv637kFFnnfiSJ8e6jknrKkMrU+PQ==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0" + } + }, + "node_modules/universal-cookie/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", diff --git a/package.json b/package.json index 5399f412..7e5b3dc2 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "framer-motion": "^11.2.12", "lodash": "^4.17.21", "react": "^18.2.0", + "react-cookie": "^7.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.23.1", "react-split": "^2.0.14", @@ -50,6 +51,7 @@ "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-fetch-mock": "^3.0.3", + "jose": "^5.8.0", "msw": "^2.3.1", "ts-jest": "^29.2.4", "ts-node": "^10.9.2", diff --git a/public/image/icon_copy.svg b/public/image/icon_copy.svg new file mode 100644 index 00000000..fec0ba88 --- /dev/null +++ b/public/image/icon_copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/image/icon_delete.svg b/public/image/icon_delete.svg new file mode 100644 index 00000000..156b05a0 --- /dev/null +++ b/public/image/icon_delete.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/image/icon_group.svg b/public/image/icon_group.svg new file mode 100644 index 00000000..4cd7d3a9 --- /dev/null +++ b/public/image/icon_group.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/image/icon_left_arrow.svg b/public/image/icon_left_arrow.svg new file mode 100644 index 00000000..6b1aa302 --- /dev/null +++ b/public/image/icon_left_arrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/image/icon_link.svg b/public/image/icon_link.svg new file mode 100644 index 00000000..1dc26902 --- /dev/null +++ b/public/image/icon_link.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/image/icon_right_arrow.svg b/public/image/icon_right_arrow.svg new file mode 100644 index 00000000..4e03136a --- /dev/null +++ b/public/image/icon_right_arrow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/image/icon_right_arrow2.svg b/public/image/icon_right_arrow2.svg new file mode 100644 index 00000000..2bbe76ff --- /dev/null +++ b/public/image/icon_right_arrow2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/image/icon_search.svg b/public/image/icon_search.svg new file mode 100644 index 00000000..5991c197 --- /dev/null +++ b/public/image/icon_search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/image/img_copywriting.png b/public/image/img_copywriting.png new file mode 100644 index 00000000..015f8cc6 Binary files /dev/null and b/public/image/img_copywriting.png differ diff --git a/public/image/img_data02_nodata.png b/public/image/img_data02_nodata.png new file mode 100644 index 00000000..54620f0a Binary files /dev/null and b/public/image/img_data02_nodata.png differ diff --git a/public/image/img_data02_test01.png b/public/image/img_data02_test01.png new file mode 100644 index 00000000..0cf724f5 Binary files /dev/null and b/public/image/img_data02_test01.png differ diff --git a/public/image/img_data02_test02.png b/public/image/img_data02_test02.png new file mode 100644 index 00000000..3adf9d3c Binary files /dev/null and b/public/image/img_data02_test02.png differ diff --git a/public/image/img_data02_test03.png b/public/image/img_data02_test03.png new file mode 100644 index 00000000..0b5b315a Binary files /dev/null and b/public/image/img_data02_test03.png differ diff --git a/public/image/img_logo.png b/public/image/img_logo.png index ac21590d..780e4579 100644 Binary files a/public/image/img_logo.png and b/public/image/img_logo.png differ diff --git a/public/image/img_logo2.png b/public/image/img_logo2.png index f760c11d..f34ccaad 100644 Binary files a/public/image/img_logo2.png and b/public/image/img_logo2.png differ diff --git a/public/image/progress01.svg b/public/image/progress01.svg new file mode 100644 index 00000000..41d5514b --- /dev/null +++ b/public/image/progress01.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/image/progress02.svg b/public/image/progress02.svg new file mode 100644 index 00000000..31ac1c88 --- /dev/null +++ b/public/image/progress02.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/image/progress03.svg b/public/image/progress03.svg new file mode 100644 index 00000000..00993250 --- /dev/null +++ b/public/image/progress03.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/public/image/progress04.svg b/public/image/progress04.svg new file mode 100644 index 00000000..29731b8f --- /dev/null +++ b/public/image/progress04.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/App.css b/src/App.css index d985be09..c73a9115 100644 --- a/src/App.css +++ b/src/App.css @@ -1,5 +1,6 @@ .bg-gray { background-color: var(--bg02); + height: auto; } .color-blue { color: var(--blue); @@ -24,16 +25,18 @@ button:hover { display: flex; align-items: center; flex-direction: column; - margin-top: 150px; - height: 100vh; + margin-top: 50px; +} +.login-wrap > img { + height: 200px; } .login-box { - padding: 24px; padding: 24px; border-radius: 16px; background-color: #fff; display: flex; flex-direction: column; + margin-bottom: 100px; } .login-box input, .login-box button { @@ -149,6 +152,229 @@ input[type="checkbox"] { width: auto; text-decoration: underline; } +.view-section2-1 > .gutter.gutter-vertical { + border-top: 1px solid var(--gray01); + border-bottom: none; + background-image: none; + background-color: #fdfdfe; + height: 10px !important; +} +.view-section2-1 .view-data, +.view-section2-2 .view-data { + box-sizing: border-box; /* 패딩과 보더를 포함하여 너비 계산 */ + background-color: #fdfdfe; + padding: 16px; +} + +.view-section-title { + width: 100%; + padding: 13px 24px; + background-color: #fcfcfc; + border-bottom: 1px solid var(--gray01); + font-weight: 600; +} +.data-name { + font-weight: 600; + display: inline-block; + padding: 3px 8px; + border-radius: 4px; + background-color: #fff; + border: 1px solid #f4f4f4; + font-size: 14px; + margin-bottom: 24px; +} +.view-data { + position: relative; + height: 100%; + overflow-y: auto; + height: calc(100% - 51px); +} +.view-section2-2 .view-data { + height: 100%; +} +.split-contatiner { + border-top: 1px solid var(--gray01); + border-bottom: none; + background-image: none; + background-color: #fdfdfe; + height: 10px !important; +} +var-list { + display: flex; + align-items: center; + gap: 24px; + margin-left: 8px; +} +.var-list li { + display: flex; + align-items: center; + flex-direction: column; +} + +.code-flow { + border: 1px solid var(--gray01); + border-radius: 8px; + padding: 24px; + display: inline-block; + position: relative; + margin-top: 40px; + margin-left: 20px; +} +.code-flow + .code-flow { + margin-top: 60px !important; +} +.highlight-border { + border-color: #364fce !important; +} +.highlight-number { + background-color: #364fce !important; +} +.highlight-text { + color: #364fce !important; +} + +.code-flow-var { + display: flex; + align-items: center; +} +.code-flow-var div { + display: flex; + align-items: center; + flex-direction: column; + position: relative; +} +.code-flow-var div span:not(.code-var-title) { + background-color: #565656; + border-radius: 4px; + background-color: #565656; + color: #fff; + padding: 8px 15px; + min-width: 10px; + position: relative; +} +.code-flow-var div span.code-var-title { + margin-bottom: 3px; + font-size: 14px; +} +.code-flow-title-wrap { + display: flex; + align-items: flex-end; + position: absolute; + top: -22px; + left: 12px; +} +.code-flow-title { + font-size: 20px; + font-family: "GmarketSans"; + font-weight: 500; + padding: 0 6px; + min-width: 38px; + text-align: center; + margin-bottom: 6px; + margin-right: 12px; + position: relative; +} +.code-flow { + min-width: 560px; + background-color: #fff; +} +.code-flow .code-flow { + min-width: 480px; + background-color: #fdfdfe; +} +.code-flow .code-flow .code-flow { + min-width: 400px; + background-color: #fbfbfe; +} +.code-flow .code-flow .code-flow .code-flow { + min-width: 320px; + background-color: #f9f9fd; +} +.code-flow .code-flow .code-flow .code-flow .code-flow { + min-width: 240px; + background-color: #f5f5fc; +} +.code-flow-title::before { + position: absolute; + content: ""; + bottom: 0; + width: 100%; + height: 22px; + left: 0; +} +.code-flow-title span { + position: relative; +} +.code-flow .code-flow-title-wrap > .code-flow-title::before { + background-color: #fff; +} +.code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { + background-color: #fdfdfe; +} +.code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { + background-color: #fbfbfe; +} +.code-flow .code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { + background-color: #f9f9fd; +} +.code-flow .code-flow .code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { + background-color: #f5f5fc; +} + +.code-flow-for.code-flow { + margin-top: 60px; +} +.code-flow-for.code-flow .code-flow-for { + margin-top: 48px; +} +.code-flow-for > .code-flow-title-wrap { + top: -46px; +} +.code-flow-for > .code-flow-title-wrap > .code-flow-var { + gap: 4px; +} +.code-flow-for > .code-flow-title-wrap > .code-flow-var > div:nth-child(1) { + margin-right: 20px; +} +.code-flow { + margin-top: 40px; +} +.code-flow-text > .code-flow-title-wrap { + top: -15px; +} +.code-flow.code-flow-text { + margin-top: 32px; +} +.view-section2-2 .view-data > div { + display: flex; + position: relative; + flex-direction: column; +} +.code-flow > .code-flow-data:nth-child(2) { + margin-top: 12px; +} +.code-flow-text > .code-flow-data:nth-child(2) { + margin-top: 0; +} +.code-flow-for > .code-flow-data:nth-child(2) { + margin-top: 12px; +} +.var-data span.on_active, +.code-flow-var span.on_active { + background-color: #364fce !important; + color: #fff !important; +} +.code-target { + display: flex; + align-items: flex-start; + position: absolute; + transition: all 0.3s; +} +.code-target img { + margin-top: 11px; + margin-right: 8px; +} + /* popup */ @-webkit-keyframes fade { 0% { @@ -336,6 +562,534 @@ input[type="checkbox"] { margin-right: 8px; } /* 코드 흐름 시각화의 자료구조 왼쪽 정렬 */ + +.group-wrap { + padding: 13px 32px; + background: linear-gradient(to top, #4866ff, #607aff); + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 40px; + height: 77px; +} +.group-title { + font-size: 24px; + font-weight: 700; + color: #fff; +} +.group-left { + display: flex; + gap: 12px; + align-items: center; +} +.title-left h3 { + font-size: 24px; + font-weight: 700; +} +.section-title { + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid var(--gray01); + padding: 16px 0; + margin-bottom: 24px; +} +.progress-info { + border: 1px solid #f0f0f0; + background-color: #f9fafb; + border-radius: 8px; + padding: 32px; + margin-bottom: 40px; +} +.progress-date-data { + display: flex; + align-items: center; + justify-content: center; + gap: 16px; +} +.progress-date-data input[type="date"] { + border: none; + background: #f9fafb; + font-size: 20px; + width: 118px; + padding-left: 0; + padding-right: 0; +} +.progress-date-data input[type="date"]::-webkit-calendar-picker-indicator { + width: 100%; + opacity: 0; +} +.progress-date { + position: relative; + display: inline-block; +} +.date-label { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + cursor: pointer; + display: inline-flex; + align-items: center; + justify-content: center; + pointer-events: none; + font-size: 20px; + font-weight: 500; +} +.progress-data { + display: flex; + align-items: center; + justify-content: center; + gap: 20px; + margin-top: 20px; +} +.progress-data li { + display: flex; + align-items: center; + justify-content: space-between; + gap: 40px; + padding: 18px; + border-radius: 8px; + background-color: #fff; + filter: drop-shadow(0 4px 16px rgba(0, 70, 155, 0.05)); +} +.progress-data li div { + display: flex; + gap: 24px; + align-items: center; +} +.progress-data li div p:nth-child(1) { + font-size: 14px; + font-weight: 500; +} +.progress-data li div p:nth-child(2) { + font-size: 24px; + font-weight: 700; +} +.section-data { + display: grid; + gap: 20px; + margin-bottom: 40px; +} +.section-data01 { + grid-template-columns: 1fr 1fr 1fr 1fr; +} +.section-data01 li a { + padding: 30px 24px; + border-radius: 8px; + border: 1px solid var(--gray01); + display: flex; + align-items: center; + justify-content: space-between; +} +.section-data01 li div:nth-child(1) p { + font-size: 18px; + font-weight: 600; + margin-bottom: 8px; +} +.section-data01 li div:nth-child(1) span { + font-weight: 400; + color: #c2c2c2; +} +.section-data01 li div:nth-child(2) { + display: flex; + align-items: center; + width: 106px; + border-radius: 12px; +} +.section-data01 li div:nth-child(2)::before { + content: ""; + display: block; + width: 40px; + height: 40px; +} +.section-data01 li div:nth-child(2) p { + font-weight: 600; + font-size: 16px; + flex: 1; + text-align: center; + margin-right: 16px; +} +.progress-success { + background-color: #ebf4ff; +} +.progress-success:before { + background: url(/image/progress03.svg); +} +.progress-success p { + color: #308dff; +} +.progress-fail { + background-color: #ffedeb; +} +.progress-fail:before { + background: url(/image/progress04.svg); +} + +.progress-fail p { + color: #ff5b49; +} + +.progress-not { + background-color: #f3f3f3; +} +.progress-not:before { + background: url(/image/progress02.svg); +} + +.progress-not p { + color: #848484; +} + +/* 과제 */ +.bg { + background: #f9fafb; + height: 100%; +} +.title-right button { + padding: 9.5px 24px; + border-radius: 6px; + background-color: var(--blue); + color: #fff; + font-size: 16px; + border-width: 700px; + margin-left: 4px; +} +.section-data02 { + grid-template-columns: 1fr 1fr 1fr 1fr; +} +@media screen and (max-width: 1212px) { + .section-data02 { + grid-template-columns: 1fr 1fr 1fr; + } +} +.section-data02 > li { + background-color: #fff; + border-radius: 8px; + overflow: hidden; + border: 1px solid var(--gray02); + min-width: 258px; +} +.section-data02-img-wrap { + height: 190px; + overflow: hidden; + position: relative; +} +.section-data02-img-wrap img { + width: 100%; + position: absolute; + transition: all 0.6s; +} +.section-data02 li:hover .section-data02-img-wrap img { + transform: scale(1.05); +} +.data02-name { + padding: 22px 24px 34px 24px; +} +.data02-name > p { + padding-bottom: 22px; + margin-bottom: 22px; + border-bottom: 1px solid var(--gray02); + font-size: 18px; + font-weight: 600; +} +.data02-name div { + display: flex; + align-items: center; + justify-content: space-between; +} +.data02-name div p:nth-child(1) { + font-size: 14px; + font-weight: 400; +} +.data02-name div p:nth-child(2) { + color: var(--blue); + font-size: 18px; + font-weight: 600; +} +.data02-name div + div { + margin-top: 8px; +} +.timeover .section-data02-img-wrap::before { + content: "제출만료"; + display: block; + position: absolute; + left: 12px; + top: 12px; + z-index: 9; + background-color: #f3f3f3; + color: #848484; + border: 1px solid var(--gray01); + border-radius: 4px; + padding: 6px 15px; +} +.timeover .data02-name div p, +.timeover .data02-name > p { + color: #dddee4; +} + +/* 설정 */ +.section-data03 { + grid-template-columns: 1fr 1fr 1fr 1fr; +} +.section-data03 li { + border-radius: 8px; + overflow: hidden; + border: 1px solid var(--gray02); + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + background-color: #fff; +} +.section-data03 li div { + display: flex; + flex-direction: column; +} +.data03-name p { + font-size: 20px; + font-weight: 600; + margin-bottom: 8px; +} +.data03-name span { + font-weight: 300; + color: #98a8b8; +} +.data03-btns { + height: 100%; + justify-content: flex-end; + gap: 8px; +} +.data03-btns button { + width: 60px; + height: 37px; + font-weight: 600; + border-radius: 4px; +} +.data03-btns .blue { + color: #308dff; + background-color: #ebf4ff; +} +.data03-btns .red { + color: #ff5b49; + background-color: #ffedeb; +} +.search-wrap { + background-color: #fff; + display: flex; + align-items: center; + border-radius: 4px; + border: 1px solid var(--gray01); + width: 300px; +} +.search-wrap * { + border: none !important; + background-color: initial !important; +} +.search-wrap input { + flex: 1; + height: 41px; + padding: 4px 16px 4px 16px; +} +.search-wrap button { + width: 24px; + height: 24px; + padding: 0; + margin-right: 8px; +} +.right-btns { + display: flex; + justify-content: flex-end; +} +.right-btns button { + height: 43px; + padding: 10px 16px; + border-radius: 4px; + display: flex; + align-items: center; + gap: 8px; +} +.right-btns .red { + background-color: #ff5b49; + color: #fff; + font-weight: 600; +} +.group-link { + display: flex; + align-items: center; + background-color: #fff; + border-radius: 8px; + overflow: hidden; +} +.link-name { + display: flex; + align-items: center; + justify-content: center; + background-color: #ebf4ff; + color: var(--blue); + gap: 6px; + height: 51px; + width: 170px; +} +.link-data { + padding: 0 12px 0 24px; +} +.group-link button { + margin-right: 16px; +} + +/* 그룹 */ +header .group-btn { + border-radius: 4px; + background-color: var(--blue); + color: #fff; + font-weight: 600; + margin-right: 24px; + padding: 8px 16px; +} +.group-copywriting { + position: relative; + display: flex; + flex-direction: column; + padding: 74px 0 83px 0; + background: linear-gradient(to right, #4866ff, #738aff); +} +.group-copywriting img { + position: absolute; + right: 171px; + bottom: -81px; +} +.group-copywriting * { + color: #fff; +} +.group-copywriting p { + font-size: 15px; + font-weight: 800; + margin-bottom: 5px; +} +.group-copywriting h2 { + font-weight: 800; + font-size: 32px; + margin-bottom: 5px; +} +.group-copywriting span { + font-size: 15px; + font-weight: 400; +} +.group-data-wrap { + display: flex; + z-index: 1; + position: relative; +} +.group-data-left { + width: 570px; + border-right: 1px solid var(--gray02); + min-height: calc(100vh - 329px); + background-color: #fff; + padding: 60px 40px; + display: flex; + justify-content: flex-end; +} +.user-info { + width: 320px; +} +.user-info > p { + font-weight: 800; + font-size: 24px; +} +.user-info > span { + display: block; + padding-bottom: 34px; + font-weight: 300; + font-size: 16px; + color: #98a8b8; + border-bottom: 1px solid var(--gray02); +} +.user-group-data { + display: grid; + grid-template-columns: 1fr 1fr; +} +.user-group-data p:nth-child(1) { + margin-top: 24px; + font-weight: 300; + color: #98a8b8; + margin-bottom: 10px; +} +.user-group-data p:nth-child(2) { + font-size: 32px; + font-weight: 700; + padding-bottom: 24px; + border-bottom: 1px solid var(--gray02); + margin-bottom: 32px; +} +.user-info > label { + font-size: 13px; + color: #98a8b8; + display: block; + margin-bottom: 8px; +} + +.user-info > div { + display: flex; + align-items: center; + gap: 8px; +} +.user-info input { + width: 236px; +} +.user-info > div button { + border-radius: 6px; + background-color: var(--blue); + color: #fff; + padding: 12px 24px; + height: 51px; +} +.group-right { + padding: 40px 0 0 36px; +} +.section-data04 { + grid-template-columns: 1fr 1fr 1fr; +} +@media screen and (max-width: 1740px) { + .section-data04 { + grid-template-columns: 1fr 1fr; + } +} + +.section-data04 li a { + border-radius: 8px; + overflow: hidden; + border: 1px solid var(--gray02); + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + background-color: #fff; + height: 100%; +} +.section-data04 li a div { + display: flex; + flex-direction: column; + width: 274px; +} +.data04-name p { + font-size: 20px; + font-weight: 600; + margin-bottom: 8px; +} +.data04-name span { + font-weight: 300; + color: #98a8b8; +} +.bg2 { + background: #fbfcff; +} +.bg2 .section-title, +.bg .section-title { + border-bottom: 1px solid var(--gray02); +} + .align-left { margin-top: 30px; width: 100%; diff --git a/src/App.tsx b/src/App.tsx index 59037d8e..113dd5e0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,24 +1,80 @@ +import { useEffect, useState } from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; -import Home from "./pages/Home/Home"; +import { useQuery } from "@tanstack/react-query"; +import Visualization from "./pages/Visualization/Visualization"; import Signup from "./pages/Signup/Signup"; import Login from "./pages/Login/Login"; +import Home from "./pages/Home/Home"; +import Modify from "./pages/Modify/Modify"; +import Group from "./pages/Group/Group"; +import Assginment from "./pages/Assignment/Assignment"; +import Progress from "./pages/Progress/Progress"; +import { useUserStore } from "./store/user"; import "./App.css"; -import { worker } from "./mocks/browser"; +import { setupMSW } from "./mocks/setup"; -if (typeof window !== "undefined") { - if (import.meta.env.VITE_APP_NODE_ENV === "development") { - worker.start(); - } +interface User { + email: string; + name: string; + role: string; } +//zustand +// 새로고침 이후 get요청을 보내면 msw가 실행되기 전에 보내지는 버그 수정 +// if (typeof window !== "undefined") { +// if (import.meta.env.VITE_APP_NODE_ENV === "development") { +// worker.start(); +// } +// } +// msw 버그로 인해 fetchUser는 따로 확인 불가능 백엔드 서버 연결해서 확인해야함 +const fetchUser = async (): Promise => { + const response = await fetch("http://localhost:8080/edupi_user/v1/member/login/info", { + method: "GET", + credentials: "include", + headers: { + "Content-Type": "application/json", + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + const data = await response.json(); + return data; +}; function App() { + const [isMswReady, setIsMswReady] = useState(false); + + useEffect(() => { + if (import.meta.env.VITE_APP_NODE_ENV === "development") { + setupMSW().then(() => setIsMswReady(true)); + } else { + setIsMswReady(true); + } + }, []); + const { data } = useQuery({ queryKey: ["user"], queryFn: fetchUser, enabled: isMswReady }); + const setLoggedInUserEmail = useUserStore((state) => state.setLoggedInUserEmail); + const setLoggedInUserName = useUserStore((state) => state.setLoggedInUserName); + const setLoggedInUserRole = useUserStore((state) => state.setLoggedInUserRole); + + useEffect(() => { + if (data) { + setLoggedInUserEmail(data.email); + setLoggedInUserName(data.name); + setLoggedInUserRole(data.role); + } + }, [data]); return ( } /> + } /> } /> } /> + } /> + } /> + } /> + } /> ); diff --git a/src/index.css b/src/index.css index 818a7d0a..27a06731 100644 --- a/src/index.css +++ b/src/index.css @@ -39,6 +39,9 @@ html, body { margin: 0; /* 기본 마진 제거 */ } +#root { + height: auto; +} section { width: 100%; } @@ -219,7 +222,7 @@ ol { /* 스크롤 */ .s__container { - height: inherit; + height: auto; max-width: 1200px; width: 100%; margin: 0 auto; @@ -227,12 +230,17 @@ ol { .s__row { padding: 0 16px; } +.modify-s__row { + padding: 0 16px; + min-height: 80vh; +} :root { --black: #181818; --white: #fff; --blue: #4866ff; --gray01: #dddee4; + --gray02: #eaeaea; --bg01: #fcfcfc; --bg02: #f7f7f7; } diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts index 5c7f5137..28b43954 100644 --- a/src/mocks/handlers.ts +++ b/src/mocks/handlers.ts @@ -1,9 +1,22 @@ import { http, HttpResponse } from "msw"; +import * as jose from "jose"; import testResponseBody from "./samples/testResponseBody.json"; +const JWT_SECRET = new TextEncoder().encode("your_jwt_secret_key"); + +async function generateToken(userId: string) { + const jwt = await new jose.SignJWT({ userId }) + .setProtectedHeader({ alg: "HS256" }) + .setIssuedAt() + .setExpirationTime("1h") + .sign(JWT_SECRET); + + return jwt; +} + interface User { - userId: string; - userPassword: string; + email: string; + password: string; } interface SignupUser { @@ -12,36 +25,96 @@ interface SignupUser { password: string; confirmPassword: string; } + export const handlers = [ http.post("/edupi_visualize/v1/python", () => { return HttpResponse.json(testResponseBody); }), - http.post("/login", async ({ request }) => { - const { userId, userPassword } = (await request.json()) as User; - // 간단한 인증 로직을 구현 - if (userId === "test" && userPassword === "test") { + http.get("/edupi_user/v1/member/login/info", async () => { + // Get the token from the cookies + + // 쿠키에서 토큰을 확인 + // const cookies = request.headers.get("Cookie"); + // const hasToken = cookies && cookies.includes("token="); + const hasToken = true; + if (hasToken) { return HttpResponse.json( { success: true, - message: "로그인 성공", - user: { id: userId, name: "테스트 사용자" }, + user: { id: "test@test.com", name: "테스트 사용자" }, }, - { status: 200 } + { + status: 200, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": "true", + }, + } ); } else { return HttpResponse.json( { success: false, - message: "아이디 또는 비밀번호가 잘못되었습니다", + message: "인증되지 않은 사용자", + }, + { + status: 401, + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Credentials": "true", + }, + } + ); + } + }), + + http.post("/edupi_user/v1/member/login", async ({ request }) => { + try { + const { email, password } = (await request.json()) as User; + + if (email === "test@test.com" && password === "test") { + // JWT 토큰 생성을 기다립니다. + const token = await generateToken(email); + + const expirationDate = new Date(new Date().getTime() + 60 * 60 * 1000); + + return HttpResponse.json( + { + success: true, + message: "로그인 성공", + }, + { + status: 200, + headers: { + "Set-Cookie": `token=${token}; Secure;SameSite=Strict; Expires=${expirationDate.toUTCString()}`, + }, + } + ); + } else { + return HttpResponse.json( + { + success: false, + message: "아이디 또는 비밀번호가 잘못되었습니다", + }, + { status: 401 } + ); + } + } catch (error) { + console.error("Login error:", error); + return HttpResponse.json( + { + success: false, + message: "서버 오류가 발생했습니다.", }, - { status: 401 } + { status: 500 } ); } }), - http.post("/signup", async ({ request }) => { + + http.post("/edupi_user/v1/member/signup", async ({ request }) => { const { username } = (await request.json()) as SignupUser; - if (username === "error") return HttpResponse.json({ success: "false", message: "회원가입 실패" }, { status: 500 }); + if (username === "error") return HttpResponse.json({ success: false, message: "회원가입 실패" }, { status: 500 }); return HttpResponse.json( { success: true, diff --git a/src/mocks/setup.ts b/src/mocks/setup.ts new file mode 100644 index 00000000..eead3370 --- /dev/null +++ b/src/mocks/setup.ts @@ -0,0 +1,14 @@ +// src/mocks/setup.ts +import { worker } from "./browser"; + +export const setupMSW = async () => { + if (import.meta.env.VITE_APP_NODE_ENV === "development") { + return worker.start({ + onUnhandledRequest: "bypass", + serviceWorker: { + url: "/mockServiceWorker.js", + }, + }); + } + return Promise.resolve(); +}; diff --git a/src/pages/Assignment/Assignment.tsx b/src/pages/Assignment/Assignment.tsx new file mode 100644 index 00000000..30a0b7a8 --- /dev/null +++ b/src/pages/Assignment/Assignment.tsx @@ -0,0 +1,126 @@ +import LoggedInHeader from "../components/LoggedInHeader"; +import AssginmentSection from "./components/AssignmentSection"; +const Assignment = () => { + return ( +
+ +
+
+ 그룹 +

파이썬 기초 1반

+
+
+
+ +
+
+ ); +}; +export default Assignment; diff --git a/src/pages/Assignment/components/AssignmentSection.tsx b/src/pages/Assignment/components/AssignmentSection.tsx new file mode 100644 index 00000000..beb442ee --- /dev/null +++ b/src/pages/Assignment/components/AssignmentSection.tsx @@ -0,0 +1,23 @@ +const AssginmentSection = () => { + return ( +
  • + +
    + +
    +
    +

    구구단 출력

    +
    +

    제출시작

    +

    2023.01.01 11:59

    +
    +
    +

    제출마감

    +

    2023.01.01 11:59

    +
    +
    +
    +
  • + ); +}; +export default AssginmentSection; diff --git a/src/pages/Group/Group.tsx b/src/pages/Group/Group.tsx new file mode 100644 index 00000000..bcaf7309 --- /dev/null +++ b/src/pages/Group/Group.tsx @@ -0,0 +1,101 @@ +import LoggedInHeader from "../components/LoggedInHeader"; +import Room from "./components/Room"; +const Group: React.FC = () => { + return ( +
    + +
    +
    +
    +

    GROUP

    +

    함께 배우고, 더 빨리 성장하세요!

    + 혼자보다 함께할 때 더 많이, 더 빨리 배울 수 있습니다. +
    +
    + 그룹이미지 +
    +
    +
    +
    +

    김철수님

    + kim0000@naver.com +
      +
    • +

      생성된 그룹 수

      +

      8

      +
    • +
    • +

      전체 학생 수

      +

      400

      +
    • +
    + +
    + + +
    +
    +
    + +
    +
    + ); +}; +export default Group; diff --git a/src/pages/Group/components/Room.tsx b/src/pages/Group/components/Room.tsx new file mode 100644 index 00000000..48d518f4 --- /dev/null +++ b/src/pages/Group/components/Room.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from "react"; + +const Room = (): ReactNode => { + return ( +
  • + +
    +

    파이썬 기초 1반

    + 인원 : 23명 + 초대 대기 : 1명 +
    + +
    +
  • + ); +}; +export default Room; diff --git a/src/pages/Home/Home.tsx b/src/pages/Home/Home.tsx index 62e727c4..a01f5726 100644 --- a/src/pages/Home/Home.tsx +++ b/src/pages/Home/Home.tsx @@ -1,185 +1,13 @@ -import { createContext, useState, Dispatch, SetStateAction, useCallback, useEffect, useRef } from "react"; - -import { useMutation } from "@tanstack/react-query"; -import styles from "./Home.module.css"; -import "./gutter.css"; +import PublicHeader from "../components/PublicHeader"; import LoggedInHeader from "../components/LoggedInHeader"; -import LeftSection from "./components/LeftSection/LeftSection"; -import RightSection from "./components/RightSection/RightSection"; - -import Split from "react-split"; -import { ValidTypeDto, isValidTypeDtoArray } from "@/pages/Home/types/dto/ValidTypeDto"; - -//zustand store -import { useConsoleStore, useCodeFlowLengthStore } from "@/store/console"; -import { useArrowStore } from "@/store/arrow"; -// 원본 코드 타입 정의 -interface CodeContextType { - code: string; - setCode: Dispatch>; -} -// 전처리한 코드 타입 정의 -interface PreprocessedCodeContextType { - preprocessedCodes: ValidTypeDto[]; - setPreprocessedCodes: Dispatch>; -} -// Create contexts -export const CodeContext = createContext({ - code: "", - setCode: () => {}, -}); - -export const PreprocessedCodesContext = createContext({ - preprocessedCodes: [], - setPreprocessedCodes: () => {}, -}); - -export default function Home() { - const [code, setCode] = useState( - ["a = 3", "for i in range(a):", " print(' ' * ((a - 1) - i), end = '')", " print('*' * (2 * i + 1))"].join("\n") - ); - const [preprocessedCodes, setPreprocessedCodes] = useState([]); - // zustand store - const consoleIdx = useConsoleStore((state) => state.consoleIdx); - const resetConsole = useConsoleStore((state) => state.resetConsole); - const incrementConsoleIdx = useConsoleStore((state) => state.incrementConsoleIdx); - const decrementConsoleIdx = useConsoleStore((state) => state.decrementConsoleIdx); - const codeFlowLength = useCodeFlowLengthStore((state) => state.codeFlowLength); - const setDisplayNone = useArrowStore((state) => state.setDisplayNone); - const [isPlaying, setIsPlaying] = useState(false); - - const mutation = useMutation({ - mutationFn: async (code: string) => { - return fetch("http://localhost:8080/edupi_visualize/v1/python", { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ source_code: code }), - }); - }, - async onSuccess(data) { - try { - const jsonData = await data.json(); - // 타입 체크 함수 - if (isValidTypeDtoArray(jsonData)) { - setPreprocessedCodes(jsonData); - setDisplayNone(false); - } else { - throw new Error("받은 데이터가 올바르지 않습니다"); - } - } catch (error) { - console.error("Data processing error:", error); - alert("받은 데이터의 형식이 올바르지 않습니다."); - } - }, - onError(error) { - console.error("Submit Error:", error); - alert("코드 처리 중 에러가 발생했습니다."); - }, - }); - const handleSubmit = (event: React.FormEvent) => { - event.preventDefault(); - resetConsole(); - mutation.mutate(code); - setIsPlaying(() => true); - }; - - const onPlay = () => { - if (codeFlowLength === 0) return; - setIsPlaying((prev) => !prev); - }; - - const onForward = useCallback(() => { - if (consoleIdx < codeFlowLength - 1) { - incrementConsoleIdx(); - } - }, [consoleIdx, codeFlowLength]); - - const onBack = useCallback(() => { - if (consoleIdx > 0) { - decrementConsoleIdx(); - } - }, [consoleIdx]); - const intervalRef = useRef(null); - useEffect(() => { - if (isPlaying) { - intervalRef.current = setInterval(onForward, 1000); - } else { - if (intervalRef.current) { - clearInterval(intervalRef.current); - } - } - return () => { - if (intervalRef.current) { - clearInterval(intervalRef.current); - } - }; - }, [isPlaying, consoleIdx, codeFlowLength]); - +import { useUserStore } from "@/store/user"; +const Home = () => { + const loggedInUserName = useUserStore((state) => state.loggedInUserName); return ( - - - - -
    -
    -
    - -
    -
    -
    - -
    -
    - - - -

    - ({consoleIdx}/{codeFlowLength - 1 == -1 ? 0 : codeFlowLength - 1}) -

    -

    Play Speed

    - -
    -
    -
    - - - - - -
    -
    -
    + <> + {loggedInUserName === "" ? : } +

    메인페이지버전2 입니다

    + ); -} +}; +export default Home; diff --git a/src/pages/Home/components/RightSection/RightSection.css b/src/pages/Home/components/RightSection/RightSection.css deleted file mode 100644 index 8805e82e..00000000 --- a/src/pages/Home/components/RightSection/RightSection.css +++ /dev/null @@ -1,222 +0,0 @@ -.view-section2-1 > .gutter.gutter-vertical { - border-top: 1px solid var(--gray01); - border-bottom: none; - background-image: none; - background-color: #fdfdfe; - height: 10px !important; -} -.view-section2-1 .view-data, -.view-section2-2 .view-data { - box-sizing: border-box; /* 패딩과 보더를 포함하여 너비 계산 */ - background-color: #fdfdfe; - padding: 16px; -} - -.view-section-title { - width: 100%; - padding: 13px 24px; - background-color: #fcfcfc; - border-bottom: 1px solid var(--gray01); - font-weight: 600; -} -.data-name { - font-weight: 600; - display: inline-block; - padding: 3px 8px; - border-radius: 4px; - background-color: #fff; - border: 1px solid #f4f4f4; - font-size: 14px; - margin-bottom: 24px; -} -.view-data { - position: relative; - height: 100%; - overflow-y: auto; - height: calc(100% - 51px); -} -.view-section2-2 .view-data { - height: 100%; -} -.split-contatiner { - border-top: 1px solid var(--gray01); - border-bottom: none; - background-image: none; - background-color: #fdfdfe; - height: 10px !important; -} -var-list { - display: flex; - align-items: center; - gap: 24px; - margin-left: 8px; -} -.var-list li { - display: flex; - align-items: center; - flex-direction: column; -} - -.code-flow { - border: 1px solid var(--gray01); - border-radius: 8px; - padding: 24px; - display: inline-block; - position: relative; - margin-top: 40px; - margin-left: 20px; -} -.code-flow + .code-flow { - margin-top: 60px !important; -} -.highlight-border { - border-color: #364fce !important; -} -.highlight-number { - background-color: #364fce !important; -} -.highlight-text { - color: #364fce !important; -} - -.code-flow-var { - display: flex; - align-items: center; -} -.code-flow-var div { - display: flex; - align-items: center; - flex-direction: column; - position: relative; -} -.code-flow-var div span:not(.code-var-title) { - background-color: #565656; - border-radius: 4px; - background-color: #565656; - color: #fff; - padding: 8px 15px; - min-width: 10px; - position: relative; -} -.code-flow-var div span.code-var-title { - margin-bottom: 3px; - font-size: 14px; -} -.code-flow-title-wrap { - display: flex; - align-items: flex-end; - position: absolute; - top: -22px; - left: 12px; -} -.code-flow-title { - font-size: 20px; - font-family: "GmarketSans"; - font-weight: 500; - padding: 0 6px; - min-width: 38px; - text-align: center; - margin-bottom: 6px; - margin-right: 12px; - position: relative; -} -.code-flow { - min-width: 560px; - background-color: #fff; -} -.code-flow .code-flow { - min-width: 480px; - background-color: #fdfdfe; -} -.code-flow .code-flow .code-flow { - min-width: 400px; - background-color: #fbfbfe; -} -.code-flow .code-flow .code-flow .code-flow { - min-width: 320px; - background-color: #f9f9fd; -} -.code-flow .code-flow .code-flow .code-flow .code-flow { - min-width: 240px; - background-color: #f5f5fc; -} -.code-flow-title::before { - position: absolute; - content: ""; - bottom: 0; - width: 100%; - height: 22px; - left: 0; -} -.code-flow-title span { - position: relative; -} -.code-flow .code-flow-title-wrap > .code-flow-title::before { - background-color: #fff; -} -.code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { - background-color: #fdfdfe; -} -.code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { - background-color: #fbfbfe; -} -.code-flow .code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { - background-color: #f9f9fd; -} -.code-flow .code-flow .code-flow .code-flow .code-flow .code-flow-title-wrap > .code-flow-title::before { - background-color: #f5f5fc; -} - -.code-flow-for.code-flow { - margin-top: 60px; -} -.code-flow-for.code-flow .code-flow-for { - margin-top: 48px; -} -.code-flow-for > .code-flow-title-wrap { - top: -46px; -} -.code-flow-for > .code-flow-title-wrap > .code-flow-var { - gap: 4px; -} -.code-flow-for > .code-flow-title-wrap > .code-flow-var > div:nth-child(1) { - margin-right: 20px; -} -.code-flow { - margin-top: 40px; -} -.code-flow-text > .code-flow-title-wrap { - top: -15px; -} -.code-flow.code-flow-text { - margin-top: 32px; -} -.view-section2-2 .view-data > div { - display: flex; - position: relative; - flex-direction: column; -} -.code-flow > .code-flow-data:nth-child(2) { - margin-top: 12px; -} -.code-flow-text > .code-flow-data:nth-child(2) { - margin-top: 0; -} -.code-flow-for > .code-flow-data:nth-child(2) { - margin-top: 12px; -} -.var-data span.on_active, -.code-flow-var span.on_active { - background-color: #364fce !important; - color: #fff !important; -} -.code-target { - display: flex; - align-items: flex-start; - position: absolute; - transition: all 0.3s; -} -.code-target img { - margin-top: 11px; - margin-right: 8px; -} diff --git a/src/pages/Login/Login.tsx b/src/pages/Login/Login.tsx index 27f6e3ac..996bad6f 100644 --- a/src/pages/Login/Login.tsx +++ b/src/pages/Login/Login.tsx @@ -2,27 +2,21 @@ import { useState, FormEvent, ChangeEvent, Fragment } from "react"; import axios from "axios"; import PublicHeader from "../components/PublicHeader"; import { useMutation } from "@tanstack/react-query"; -import { useUserStore } from "@/store/user"; - +import { useNavigate } from "react-router-dom"; const Login = () => { const [userId, setUserId] = useState(""); const [userPassword, setUserPassword] = useState(""); - const setLoggedInUserId = useUserStore((state) => state.setLoggedInUserId); - const setLoggedInUserPassword = useUserStore((state) => state.setLoggedInUserPassword); - + const navigate = useNavigate(); const mutation = useMutation({ mutationFn: async ({ userId, userPassword }: { userId: string; userPassword: string }) => { - return axios.post( - "http://localhost:8000/login", - { userId, userPassword }, - { headers: { "Content-Type": "application/json" }, withCredentials: true } - ); + const req = { email: userId, password: userPassword }; + return axios.post("http://localhost:8080/edupi_user/v1/member/login", req, { + headers: { "Content-Type": "application/json" }, + withCredentials: true, + }); }, - onSuccess(data) { - const jsonData = data.data; - - setLoggedInUserId(jsonData.user.id); - setLoggedInUserPassword(jsonData.user.name); + onSuccess() { + navigate("/"); }, onError(error) { alert("아이디 또는 비밀번호가 틀렸습니다."); diff --git a/src/pages/Modify/Modify.module.css b/src/pages/Modify/Modify.module.css new file mode 100644 index 00000000..83875645 --- /dev/null +++ b/src/pages/Modify/Modify.module.css @@ -0,0 +1,3 @@ +body { + background: #f9fafb; +} diff --git a/src/pages/Modify/Modify.tsx b/src/pages/Modify/Modify.tsx new file mode 100644 index 00000000..d88e3f00 --- /dev/null +++ b/src/pages/Modify/Modify.tsx @@ -0,0 +1,120 @@ +import LoggedInHeader from "../components/LoggedInHeader"; +const Modify = () => { + return ( +
    + +
    +
    +
    + 그룹 +

    파이썬 기초 1반

    +
    +
    +

    + 링크 + 그룹 초대 링크 +

    +

    https://www.google.com/webhp?hl=ko&sa=

    + +
    +
    +
    +
    +
    +
    +

    초대 대기

    +
    +
    +
      +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + + +
      +
    • +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + + +
      +
    • +
    +
    +
    +

    가입된 학생

    +
    +
    +
    + + +
    +
    +
    +
      +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + +
      +
    • +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + +
      +
    • +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + +
      +
    • +
    • +
      +

      홍길동

      + hong@naver.com + 학번 : 20003204 +
      +
      + +
      +
    • +
    +
    + +
    +
    +
    +
    + ); +}; +export default Modify; diff --git a/src/pages/Progress/Progress.tsx b/src/pages/Progress/Progress.tsx new file mode 100644 index 00000000..d9c0b49f --- /dev/null +++ b/src/pages/Progress/Progress.tsx @@ -0,0 +1,156 @@ +import { useState } from "react"; +import LoggedInHeader from "../components/LoggedInHeader"; +const Progress = () => { + const [date, setDate] = useState("2024-01-01"); + + const handleDateChange = (e: React.ChangeEvent) => { + setDate(e.target.value); + }; + + const formatDate = (dateString: string) => { + return dateString.replace(/-/g, ". "); + }; + return ( +
    + +
    +
    + 그룹 +

    파이썬 기초 1반

    +
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +
      +
    • + 전체 +
      +

      전체

      +

      23

      +
      +
    • +
    • + 미제출 +
      +

      미제출

      +

      9

      +
      +
    • +
    • + 성공 +
      +

      성공

      +

      8

      +
      +
    • +
    • + 실패 +
      +

      실패

      +

      0

      +
      +
    • +
    +
    +
    +
    +

    제출현황

    +
    +
    + +
    +
    + +
    +
    + +
    + ); +}; +export default Progress; diff --git a/src/pages/Signup/Signup.tsx b/src/pages/Signup/Signup.tsx index ae0beff2..db3b4139 100644 --- a/src/pages/Signup/Signup.tsx +++ b/src/pages/Signup/Signup.tsx @@ -3,6 +3,7 @@ import { useMutation } from "@tanstack/react-query"; import PublicHeader from "../components/PublicHeader"; import styles from "./Signup.module.css"; import axios from "axios"; +import { Link, useNavigate } from "react-router-dom"; interface FormData { username: string; @@ -29,7 +30,7 @@ const Signup = () => { confirmPassword: "", }); const [errors, setErrors] = useState({}); - + const navigate = useNavigate(); const handleChange = (e: ChangeEvent) => { const { name, value } = e.target; const trimmedValue = value.replace(/\s/g, ""); @@ -38,32 +39,48 @@ const Signup = () => { const validateForm = (): boolean => { let newErrors: FormErrors = {}; - if (!formData.username.trim()) newErrors.username = "사용자 이름은 필수입니다."; - if (!formData.email.trim()) newErrors.email = "이메일은 필수입니다."; - else if (!/\S+@\S+\.\S+/.test(formData.email)) newErrors.email = "유효한 이메일 주소를 입력하세요."; - if (!formData.phoneNumber) newErrors.phoneNumber = "핸드폰 번호는 필수입니다."; - else if (!/^010-\d{3,4}-\d{4}$/.test(formData.phoneNumber)) + if (!formData.username.trim()) { + newErrors.username = "사용자 이름은 필수입니다."; + } + if (!formData.email.trim()) { + newErrors.email = "이메일은 필수입니다."; + } else if (!/\S+@\S+\.\S+/.test(formData.email)) { + newErrors.email = "유효한 이메일 주소를 입력하세요."; + } + if (!formData.phoneNumber) { + newErrors.phoneNumber = "핸드폰 번호는 필수입니다."; + } else if (!/^010-\d{3,4}-\d{4}$/.test(formData.phoneNumber)) { newErrors.phoneNumber = "유효한 핸드폰 번호를 입력하세요."; - if (!formData.password) newErrors.password = "비밀번호는 필수입니다."; - else if (formData.password.length < 6 || formData.confirmPassword.length > 20) + } + if (!formData.password) { + newErrors.password = "비밀번호는 필수입니다."; + } else if (formData.password.length < 6 || formData.confirmPassword.length > 20) { newErrors.password = "비밀번호는 최소 8자 이상 20자 이하여야 합니다."; - else if (!/^(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>/?]).*$/.test(formData.password)) + } else if (!/^(?=.*[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>/?]).*$/.test(formData.password)) { newErrors.password = "비밀번호는 최소 1개의 특수 문자를 포함해야 합니다"; - if (formData.password !== formData.confirmPassword) newErrors.confirmPassword = "비밀번호가 일치하지 않습니다."; + } + if (formData.password !== formData.confirmPassword) { + newErrors.confirmPassword = "비밀번호가 일치하지 않습니다."; + } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const mutation = useMutation({ mutationFn: async (formData: FormData) => { - return axios.post("http://localhost:8000/signup", formData, { + const req = { + email: formData.email, + password: formData.password, + name: formData.username, + phoneNumber: formData.phoneNumber, + }; + return axios.post("http://localhost:8080/edupi_user/v1/member/signup", req, { headers: { "Content-Type": "application/json" }, withCredentials: true, }); }, onSuccess() { - alert("회원가입이 완료되었습니다."); - // 랜딩 페이지로 접근하는 코드가 들어가야 할 곳 + navigate("/login"); }, onError(error) { console.error("회원가입 에러", error); @@ -84,9 +101,9 @@ const Signup = () => { 로고

    이미 계정이 있으신가요? - + 로그인 - +

    diff --git a/src/pages/Home/Home.module.css b/src/pages/Visualization/Visualization.module.css similarity index 100% rename from src/pages/Home/Home.module.css rename to src/pages/Visualization/Visualization.module.css diff --git a/src/pages/Visualization/Visualization.tsx b/src/pages/Visualization/Visualization.tsx new file mode 100644 index 00000000..b8075792 --- /dev/null +++ b/src/pages/Visualization/Visualization.tsx @@ -0,0 +1,188 @@ +import { createContext, useState, Dispatch, SetStateAction, useCallback, useEffect, useRef } from "react"; + +import { useMutation } from "@tanstack/react-query"; +import styles from "./Visualization.module.css"; +import "./gutter.css"; +import PublicHeader from "../components/PublicHeader"; +import LoggedInHeader from "../components/LoggedInHeader"; +import LeftSection from "./components/LeftSection/LeftSection"; +import RightSection from "./components/RightSection/RightSection"; + +import Split from "react-split"; +import { ValidTypeDto, isValidTypeDtoArray } from "@/pages/Visualization/types/dto/ValidTypeDto"; + +//zustand store +import { useConsoleStore, useCodeFlowLengthStore } from "@/store/console"; +import { useArrowStore } from "@/store/arrow"; +import { useUserStore } from "@/store/user"; +// 원본 코드 타입 정의 +interface CodeContextType { + code: string; + setCode: Dispatch>; +} +// 전처리한 코드 타입 정의 +interface PreprocessedCodeContextType { + preprocessedCodes: ValidTypeDto[]; + setPreprocessedCodes: Dispatch>; +} +// Create contexts +export const CodeContext = createContext({ + code: "", + setCode: () => {}, +}); + +export const PreprocessedCodesContext = createContext({ + preprocessedCodes: [], + setPreprocessedCodes: () => {}, +}); + +export default function Visualization() { + const [code, setCode] = useState( + ["a = 3", "for i in range(a):", " print(' ' * ((a - 1) - i), end = '')", " print('*' * (2 * i + 1))"].join("\n") + ); + const [preprocessedCodes, setPreprocessedCodes] = useState([]); + // zustand store + const consoleIdx = useConsoleStore((state) => state.consoleIdx); + const resetConsole = useConsoleStore((state) => state.resetConsole); + const incrementConsoleIdx = useConsoleStore((state) => state.incrementConsoleIdx); + const decrementConsoleIdx = useConsoleStore((state) => state.decrementConsoleIdx); + const codeFlowLength = useCodeFlowLengthStore((state) => state.codeFlowLength); + const setDisplayNone = useArrowStore((state) => state.setDisplayNone); + const loggedInUserName = useUserStore((state) => state.loggedInUserName); + const [isPlaying, setIsPlaying] = useState(false); + + const mutation = useMutation({ + mutationFn: async (code: string) => { + return fetch("http://localhost:8080/edupi_visualize/v1/python", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ source_code: code }), + }); + }, + async onSuccess(data) { + try { + const jsonData = await data.json(); + // 타입 체크 함수 + if (isValidTypeDtoArray(jsonData)) { + setPreprocessedCodes(jsonData); + setDisplayNone(false); + } else { + throw new Error("데이터 형식이 올바르지 않습니다"); + } + } catch (error) { + console.error("Data processing error:", error); + alert("데이터의 형식이 올바르지 않습니다."); + } + }, + onError(error) { + console.error("Submit Error:", error); + alert("코드 처리 중 에러가 발생했습니다."); + }, + }); + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + resetConsole(); + mutation.mutate(code); + setIsPlaying(() => true); + }; + + const onPlay = () => { + if (codeFlowLength === 0) return; + setIsPlaying((prev) => !prev); + }; + + const onForward = useCallback(() => { + if (consoleIdx < codeFlowLength - 1) { + incrementConsoleIdx(); + } + }, [consoleIdx, codeFlowLength]); + + const onBack = useCallback(() => { + if (consoleIdx > 0) { + decrementConsoleIdx(); + } + }, [consoleIdx]); + const intervalRef = useRef(null); + useEffect(() => { + if (isPlaying) { + intervalRef.current = setInterval(onForward, 1000); + } else { + if (intervalRef.current) { + clearInterval(intervalRef.current); + } + } + return () => { + if (intervalRef.current) { + clearInterval(intervalRef.current); + } + }; + }, [isPlaying, consoleIdx, codeFlowLength]); + + return ( + + + {loggedInUserName === "" ? : } + +
    +
    +
    + +
    +
    + + + +
    + + + +

    + ({consoleIdx}/{codeFlowLength - 1 == -1 ? 0 : codeFlowLength - 1}) +

    +

    Play Speed

    + +
    +
    +
    + + + + + +
    +
    +
    + ); +} diff --git a/src/pages/Home/components/LeftSection/LeftSection.module.css b/src/pages/Visualization/components/LeftSection/LeftSection.module.css similarity index 100% rename from src/pages/Home/components/LeftSection/LeftSection.module.css rename to src/pages/Visualization/components/LeftSection/LeftSection.module.css diff --git a/src/pages/Home/components/LeftSection/LeftSection.tsx b/src/pages/Visualization/components/LeftSection/LeftSection.tsx similarity index 100% rename from src/pages/Home/components/LeftSection/LeftSection.tsx rename to src/pages/Visualization/components/LeftSection/LeftSection.tsx diff --git a/src/pages/Home/components/LeftSection/components/CodeEditor.module.css b/src/pages/Visualization/components/LeftSection/components/CodeEditor.module.css similarity index 100% rename from src/pages/Home/components/LeftSection/components/CodeEditor.module.css rename to src/pages/Visualization/components/LeftSection/components/CodeEditor.module.css diff --git a/src/pages/Home/components/LeftSection/components/CodeEditor.tsx b/src/pages/Visualization/components/LeftSection/components/CodeEditor.tsx similarity index 97% rename from src/pages/Home/components/LeftSection/components/CodeEditor.tsx rename to src/pages/Visualization/components/LeftSection/components/CodeEditor.tsx index 43932f3b..75623294 100644 --- a/src/pages/Home/components/LeftSection/components/CodeEditor.tsx +++ b/src/pages/Visualization/components/LeftSection/components/CodeEditor.tsx @@ -1,7 +1,7 @@ import { useContext, Fragment, useRef, useEffect, useState } from "react"; import Editor, { OnMount } from "@monaco-editor/react"; import * as monaco from "monaco-editor"; -import { CodeContext } from "../../../Home"; +import { CodeContext } from "../../../Visualization"; // Zustand import { useEditorStore } from "@/store/editor"; diff --git a/src/pages/Home/components/LeftSection/components/Console.module.css b/src/pages/Visualization/components/LeftSection/components/Console.module.css similarity index 100% rename from src/pages/Home/components/LeftSection/components/Console.module.css rename to src/pages/Visualization/components/LeftSection/components/Console.module.css diff --git a/src/pages/Home/components/LeftSection/components/Console.tsx b/src/pages/Visualization/components/LeftSection/components/Console.tsx similarity index 100% rename from src/pages/Home/components/LeftSection/components/Console.tsx rename to src/pages/Visualization/components/LeftSection/components/Console.tsx diff --git a/src/pages/Home/components/RightSection/RightSection.tsx b/src/pages/Visualization/components/RightSection/RightSection.tsx similarity index 93% rename from src/pages/Home/components/RightSection/RightSection.tsx rename to src/pages/Visualization/components/RightSection/RightSection.tsx index e709d377..7e9c6fed 100644 --- a/src/pages/Home/components/RightSection/RightSection.tsx +++ b/src/pages/Visualization/components/RightSection/RightSection.tsx @@ -1,6 +1,5 @@ import { useState, useContext, useEffect, useRef } from "react"; -import { PreprocessedCodesContext } from "../../Home"; -import "./RightSection.css"; +import { PreprocessedCodesContext } from "../../Visualization"; import Split from "react-split"; import _ from "lodash"; import ResizeObserver from "resize-observer-polyfill"; @@ -8,17 +7,17 @@ import ResizeObserver from "resize-observer-polyfill"; import Arrow from "./components/Arrow/Arrow"; // 타입 정의 -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; -import { ActivateItem } from "@/pages/Home/types/activateItem"; -import { VariablesDto } from "@/pages/Home/types/dto/variablesDto"; -import { ForDto } from "@/pages/Home/types/dto/forDto"; -import { PrintDto } from "@/pages/Home/types/dto/printDto"; -import { IfElseDto } from "@/pages/Home/types/dto/ifElseDto"; -import { CodeFlowVariableDto } from "@/pages/Home/types/dto/codeFlowVariableDto"; -import { PrintItem } from "@/pages/Home/types/codeFlow/printItem"; -import { VariableDto } from "@/pages/Home/types/dto/variableDto"; -import { WhileDto } from "@/pages/Home/types/dto/whileDto"; -import { AllDataStructureItem } from "@/pages/Home/types/dataStructuresItem/allDataStructureItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; +import { ActivateItem } from "@/pages/Visualization/types/activateItem"; +import { VariablesDto } from "@/pages/Visualization/types/dto/variablesDto"; +import { ForDto } from "@/pages/Visualization/types/dto/forDto"; +import { PrintDto } from "@/pages/Visualization/types/dto/printDto"; +import { IfElseDto } from "@/pages/Visualization/types/dto/ifElseDto"; +import { CodeFlowVariableDto } from "@/pages/Visualization/types/dto/codeFlowVariableDto"; +import { PrintItem } from "@/pages/Visualization/types/codeFlow/printItem"; +import { VariableDto } from "@/pages/Visualization/types/dto/variableDto"; +import { WhileDto } from "@/pages/Visualization/types/dto/whileDto"; +import { AllDataStructureItem } from "@/pages/Visualization/types/dataStructuresItem/allDataStructureItem"; // services폴더에서 가져온 함수 import { addCodeFlow } from "./services/addCodeFlow"; import { insertIntoDepth } from "./services/insertIntoDepth"; @@ -35,7 +34,7 @@ import { findDeleteUsedId } from "./services/findDeleteUsedId"; //rendUtils에서 가져온 함수 import { renderingStructure } from "./renderingStructure"; import { renderingCodeFlow } from "./renderingCodeFlow"; -import { IfElseChangeDto } from "@/pages/Home/types/dto/ifElseChangeDto"; +import { IfElseChangeDto } from "@/pages/Visualization/types/dto/ifElseChangeDto"; import { refreshCodeFlow } from "./services/refreshCodeFlow"; import { deleteCodeFlow } from "./services/deleteCodeFlow"; diff --git a/src/pages/Home/components/RightSection/components/Arrow/Arrow.tsx b/src/pages/Visualization/components/RightSection/components/Arrow/Arrow.tsx similarity index 100% rename from src/pages/Home/components/RightSection/components/Arrow/Arrow.tsx rename to src/pages/Visualization/components/RightSection/components/Arrow/Arrow.tsx diff --git a/src/pages/Home/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.module.css b/src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.module.css rename to src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.module.css diff --git a/src/pages/Home/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx b/src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx similarity index 94% rename from src/pages/Home/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx rename to src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx index 2816b91c..f9816c0d 100644 --- a/src/pages/Home/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx +++ b/src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/CodeFlowListWrapper.tsx @@ -4,7 +4,7 @@ import styles from "./CodeFlowListWrapper.module.css"; //components import CodeFlowListBlock from "./components/CodeFlowListBlock"; //type -import { CodeFlowListItem } from "@/pages/Home/types/codeFlow/codeFlowListItem"; +import { CodeFlowListItem } from "@/pages/Visualization/types/codeFlow/codeFlowListItem"; //zustand import { useArrowStore } from "@/store/arrow"; interface CodeFlowWrapperItemProps { diff --git a/src/pages/Home/components/RightSection/components/CodeFlowListWrapper/components/CodeFlowListBlock.tsx b/src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/components/CodeFlowListBlock.tsx similarity index 100% rename from src/pages/Home/components/RightSection/components/CodeFlowListWrapper/components/CodeFlowListBlock.tsx rename to src/pages/Visualization/components/RightSection/components/CodeFlowListWrapper/components/CodeFlowListBlock.tsx diff --git a/src/pages/Home/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.module.css b/src/pages/Visualization/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.module.css rename to src/pages/Visualization/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.module.css diff --git a/src/pages/Home/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx b/src/pages/Visualization/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx similarity index 94% rename from src/pages/Home/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx rename to src/pages/Visualization/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx index 2f34840d..859ede97 100644 --- a/src/pages/Home/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/CodeFlowVariableBox/CodeFlowVariableBox.tsx @@ -3,7 +3,7 @@ import styles from "./CodeFlowVariableBox.module.css"; import cx from "classnames"; //type -import { CodeFlowVariableItem } from "@/pages/Home/types/codeFlow/codeFlowVariableItem"; +import { CodeFlowVariableItem } from "@/pages/Visualization/types/codeFlow/codeFlowVariableItem"; //zustand import { useArrowStore } from "@/store/arrow"; diff --git a/src/pages/Home/components/RightSection/components/ElifBox/ElifBox.module.css b/src/pages/Visualization/components/RightSection/components/ElifBox/ElifBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/ElifBox/ElifBox.module.css rename to src/pages/Visualization/components/RightSection/components/ElifBox/ElifBox.module.css diff --git a/src/pages/Home/components/RightSection/components/ElifBox/ElifBox.tsx b/src/pages/Visualization/components/RightSection/components/ElifBox/ElifBox.tsx similarity index 94% rename from src/pages/Home/components/RightSection/components/ElifBox/ElifBox.tsx rename to src/pages/Visualization/components/RightSection/components/ElifBox/ElifBox.tsx index 97a1baf8..b10bcac0 100644 --- a/src/pages/Home/components/RightSection/components/ElifBox/ElifBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/ElifBox/ElifBox.tsx @@ -2,7 +2,7 @@ import { ReactNode } from "react"; import styles from "./ElifBox.module.css"; import cx from "classnames"; import { AnimatePresence, motion } from "framer-motion"; -import { ConditionItem } from "@/pages/Home/types/conditionItem"; +import { ConditionItem } from "@/pages/Visualization/types/codeFlow/conditionItem"; type Props = { children: ReactNode; diff --git a/src/pages/Home/components/RightSection/components/ElseBox/ElseBox.module.css b/src/pages/Visualization/components/RightSection/components/ElseBox/ElseBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/ElseBox/ElseBox.module.css rename to src/pages/Visualization/components/RightSection/components/ElseBox/ElseBox.module.css diff --git a/src/pages/Home/components/RightSection/components/ElseBox/ElseBox.tsx b/src/pages/Visualization/components/RightSection/components/ElseBox/ElseBox.tsx similarity index 94% rename from src/pages/Home/components/RightSection/components/ElseBox/ElseBox.tsx rename to src/pages/Visualization/components/RightSection/components/ElseBox/ElseBox.tsx index e9e13f41..c5a1648b 100644 --- a/src/pages/Home/components/RightSection/components/ElseBox/ElseBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/ElseBox/ElseBox.tsx @@ -1,7 +1,7 @@ import { ReactNode } from "react"; import cx from "classnames"; import { AnimatePresence, motion } from "framer-motion"; -import { ConditionItem } from "@/pages/Home/types/conditionItem"; +import { ConditionItem } from "@/pages/Visualization/types/codeFlow/conditionItem"; type Props = { children?: ReactNode; isLight: boolean; diff --git a/src/pages/Home/components/RightSection/components/ForBox/ForBox.module.css b/src/pages/Visualization/components/RightSection/components/ForBox/ForBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/ForBox/ForBox.module.css rename to src/pages/Visualization/components/RightSection/components/ForBox/ForBox.module.css diff --git a/src/pages/Home/components/RightSection/components/ForBox/ForBox.tsx b/src/pages/Visualization/components/RightSection/components/ForBox/ForBox.tsx similarity index 97% rename from src/pages/Home/components/RightSection/components/ForBox/ForBox.tsx rename to src/pages/Visualization/components/RightSection/components/ForBox/ForBox.tsx index ae4867c1..fdbd616d 100644 --- a/src/pages/Home/components/RightSection/components/ForBox/ForBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/ForBox/ForBox.tsx @@ -4,7 +4,7 @@ import cx from "classnames"; import { AnimatePresence, motion } from "framer-motion"; //type -import { ForItem } from "@/pages/Home/types/forItem"; +import { ForItem } from "@/pages/Visualization/types/codeFlow/forItem"; //zustand import { useArrowStore } from "@/store/arrow"; interface ForItemProps { diff --git a/src/pages/Home/components/RightSection/components/IfBox/IfBox.module.css b/src/pages/Visualization/components/RightSection/components/IfBox/IfBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/IfBox/IfBox.module.css rename to src/pages/Visualization/components/RightSection/components/IfBox/IfBox.module.css diff --git a/src/pages/Home/components/RightSection/components/IfBox/IfBox.tsx b/src/pages/Visualization/components/RightSection/components/IfBox/IfBox.tsx similarity index 94% rename from src/pages/Home/components/RightSection/components/IfBox/IfBox.tsx rename to src/pages/Visualization/components/RightSection/components/IfBox/IfBox.tsx index cfcb6426..aebbb84a 100644 --- a/src/pages/Home/components/RightSection/components/IfBox/IfBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/IfBox/IfBox.tsx @@ -3,7 +3,7 @@ import { ReactNode } from "react"; import styles from "./IfBox.module.css"; import cx from "classnames"; import { AnimatePresence, motion } from "framer-motion"; -import { ConditionItem } from "@/pages/Home/types/conditionItem"; +import { ConditionItem } from "@/pages/Visualization/types/codeFlow/conditionItem"; type Props = { children?: ReactNode; isLight: boolean; ifItem: ConditionItem }; function IfBox({ children, isLight, ifItem }: Props) { diff --git a/src/pages/Home/components/RightSection/components/ListWrapper/ListWrapper.module.css b/src/pages/Visualization/components/RightSection/components/ListWrapper/ListWrapper.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/ListWrapper/ListWrapper.module.css rename to src/pages/Visualization/components/RightSection/components/ListWrapper/ListWrapper.module.css diff --git a/src/pages/Home/components/RightSection/components/ListWrapper/ListWrapper.tsx b/src/pages/Visualization/components/RightSection/components/ListWrapper/ListWrapper.tsx similarity index 84% rename from src/pages/Home/components/RightSection/components/ListWrapper/ListWrapper.tsx rename to src/pages/Visualization/components/RightSection/components/ListWrapper/ListWrapper.tsx index b5840106..f1aedbf8 100644 --- a/src/pages/Home/components/RightSection/components/ListWrapper/ListWrapper.tsx +++ b/src/pages/Visualization/components/RightSection/components/ListWrapper/ListWrapper.tsx @@ -1,6 +1,6 @@ import styles from "./ListWrapper.module.css"; import { ListBlock } from "./components/ListBlock"; -import { DataStructureListItem } from "@/pages/Home/types/dataStructureListItem"; +import { DataStructureListItem } from "@/pages/Visualization/types/dataStructuresItem/dataStructureListItem"; type Props = { listItem: DataStructureListItem; }; diff --git a/src/pages/Home/components/RightSection/components/ListWrapper/components/ListBlock.tsx b/src/pages/Visualization/components/RightSection/components/ListWrapper/components/ListBlock.tsx similarity index 96% rename from src/pages/Home/components/RightSection/components/ListWrapper/components/ListBlock.tsx rename to src/pages/Visualization/components/RightSection/components/ListWrapper/components/ListBlock.tsx index cf0fcfbd..739eb17d 100644 --- a/src/pages/Home/components/RightSection/components/ListWrapper/components/ListBlock.tsx +++ b/src/pages/Visualization/components/RightSection/components/ListWrapper/components/ListBlock.tsx @@ -3,7 +3,7 @@ import cx from "classnames"; type Props = { exprItem: string; - isLight: boolean; + isLight?: boolean; index: number; }; export const ListBlock = ({ exprItem, isLight, index }: Props) => { diff --git a/src/pages/Home/components/RightSection/components/PrintBox/PrintBox.module.css b/src/pages/Visualization/components/RightSection/components/PrintBox/PrintBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/PrintBox/PrintBox.module.css rename to src/pages/Visualization/components/RightSection/components/PrintBox/PrintBox.module.css diff --git a/src/pages/Home/components/RightSection/components/PrintBox/PrintBox.tsx b/src/pages/Visualization/components/RightSection/components/PrintBox/PrintBox.tsx similarity index 96% rename from src/pages/Home/components/RightSection/components/PrintBox/PrintBox.tsx rename to src/pages/Visualization/components/RightSection/components/PrintBox/PrintBox.tsx index 6e0ec29c..5184d3d7 100644 --- a/src/pages/Home/components/RightSection/components/PrintBox/PrintBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/PrintBox/PrintBox.tsx @@ -1,6 +1,6 @@ import cx from "classnames"; import styles from "./PrintBox.module.css"; -import { PrintItem } from "@/pages/Home/types/printItem"; +import { PrintItem } from "@/pages/Visualization/types/codeFlow/printItem"; import { AnimatePresence, motion } from "framer-motion"; type Props = { diff --git a/src/pages/Home/components/RightSection/components/VariableBox/VariableBox.module.css b/src/pages/Visualization/components/RightSection/components/VariableBox/VariableBox.module.css similarity index 100% rename from src/pages/Home/components/RightSection/components/VariableBox/VariableBox.module.css rename to src/pages/Visualization/components/RightSection/components/VariableBox/VariableBox.module.css diff --git a/src/pages/Home/components/RightSection/components/VariableBox/VariableBox.tsx b/src/pages/Visualization/components/RightSection/components/VariableBox/VariableBox.tsx similarity index 100% rename from src/pages/Home/components/RightSection/components/VariableBox/VariableBox.tsx rename to src/pages/Visualization/components/RightSection/components/VariableBox/VariableBox.tsx diff --git a/src/pages/Home/components/RightSection/components/WhileBox/WhileBox.tsx b/src/pages/Visualization/components/RightSection/components/WhileBox/WhileBox.tsx similarity index 95% rename from src/pages/Home/components/RightSection/components/WhileBox/WhileBox.tsx rename to src/pages/Visualization/components/RightSection/components/WhileBox/WhileBox.tsx index 922738e4..2ed769eb 100644 --- a/src/pages/Home/components/RightSection/components/WhileBox/WhileBox.tsx +++ b/src/pages/Visualization/components/RightSection/components/WhileBox/WhileBox.tsx @@ -1,7 +1,7 @@ import { ReactNode } from "react"; import cx from "classnames"; -import { WhileItem } from "@/pages/Home/types/codeFlow/whileItem"; +import { WhileItem } from "@/pages/Visualization/types/codeFlow/whileItem"; import { AnimatePresence, motion } from "framer-motion"; type Props = { diff --git a/src/pages/Home/components/RightSection/renderingCodeFlow.tsx b/src/pages/Visualization/components/RightSection/renderingCodeFlow.tsx similarity index 89% rename from src/pages/Home/components/RightSection/renderingCodeFlow.tsx rename to src/pages/Visualization/components/RightSection/renderingCodeFlow.tsx index 0fa1d567..c1b9f4cc 100644 --- a/src/pages/Home/components/RightSection/renderingCodeFlow.tsx +++ b/src/pages/Visualization/components/RightSection/renderingCodeFlow.tsx @@ -1,5 +1,5 @@ import { useRef, useEffect, ReactNode } from "react"; -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; import { AnimatePresence, motion } from "framer-motion"; import { ReactElement } from "react"; import PrintBox from "./components/PrintBox/PrintBox"; @@ -12,13 +12,13 @@ import CodeFlowListWrapper from "./components/CodeFlowListWrapper/CodeFlowListWr import WhileBox from "./components/WhileBox/WhileBox"; // type import -import { ElseItem } from "@/pages/Home/types/codeFlow/elseItem"; -import { ForItem } from "@/pages/Home/types/codeFlow/forItem"; -import { PrintItem } from "@/pages/Home/types/codeFlow/printItem"; -import { ConditionItem } from "@/pages/Home/types/codeFlow/conditionItem"; -import { CodeFlowVariableItem } from "@/pages/Home/types/codeFlow/codeFlowVariableItem"; -import { CodeFlowListItem } from "@/pages/Home/types/codeFlow/codeFlowListItem"; -import { WhileItem } from "@/pages/Home/types/codeFlow/whileItem"; +import { ElseItem } from "@/pages/Visualization/types/codeFlow/elseItem"; +import { ForItem } from "@/pages/Visualization/types/codeFlow/forItem"; +import { PrintItem } from "@/pages/Visualization/types/codeFlow/printItem"; +import { ConditionItem } from "@/pages/Visualization/types/codeFlow/conditionItem"; +import { CodeFlowVariableItem } from "@/pages/Visualization/types/codeFlow/codeFlowVariableItem"; +import { CodeFlowListItem } from "@/pages/Visualization/types/codeFlow/codeFlowListItem"; +import { WhileItem } from "@/pages/Visualization/types/codeFlow/whileItem"; //zustand import { useArrowStore } from "@/store/arrow"; @@ -35,7 +35,6 @@ const CodeFlowItem = ({ codeFlow, width, height, children }: Props) => { const setRight = useArrowStore((state) => state.setRight); useEffect(() => { - console.log("codeFlow", codeFlow); if (ref.current && codeFlow.isLight) { const rect = ref.current.getBoundingClientRect(); setTop(rect.top); diff --git a/src/pages/Home/components/RightSection/renderingStructure.tsx b/src/pages/Visualization/components/RightSection/renderingStructure.tsx similarity index 93% rename from src/pages/Home/components/RightSection/renderingStructure.tsx rename to src/pages/Visualization/components/RightSection/renderingStructure.tsx index 9f805552..fec9f5f2 100644 --- a/src/pages/Home/components/RightSection/renderingStructure.tsx +++ b/src/pages/Visualization/components/RightSection/renderingStructure.tsx @@ -6,8 +6,8 @@ import { ReactElement } from "react"; import VariableBox from "./components/VariableBox/VariableBox"; import ListWrapper from "./components/ListWrapper/ListWrapper"; //type -import { DataStructureVarItem } from "@/pages/Home/types/dataStructureVarItem"; -import { DataStructureListItem } from "@/pages/Home/types/dataStructureListItem"; +import { DataStructureVarItem } from "@/pages/Visualization/types/dataStructuresItem/dataStructureVarItem"; +import { DataStructureListItem } from "@/pages/Visualization/types/dataStructuresItem/dataStructureListItem"; //zustand import { useArrowStore } from "@/store/arrow"; diff --git a/src/pages/Home/components/RightSection/services/addCodeFlow.ts b/src/pages/Visualization/components/RightSection/services/addCodeFlow.ts similarity index 91% rename from src/pages/Home/components/RightSection/services/addCodeFlow.ts rename to src/pages/Visualization/components/RightSection/services/addCodeFlow.ts index 5785d53b..00435c87 100644 --- a/src/pages/Home/components/RightSection/services/addCodeFlow.ts +++ b/src/pages/Visualization/components/RightSection/services/addCodeFlow.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; // 새로운 객체를 CodeFlow에 추가하는 함수 export const addCodeFlow = ( diff --git a/src/pages/Home/components/RightSection/services/createObjectToAdd.ts b/src/pages/Visualization/components/RightSection/services/createObjectToAdd.ts similarity index 76% rename from src/pages/Home/components/RightSection/services/createObjectToAdd.ts rename to src/pages/Visualization/components/RightSection/services/createObjectToAdd.ts index 894213f6..0b4a9665 100644 --- a/src/pages/Home/components/RightSection/services/createObjectToAdd.ts +++ b/src/pages/Visualization/components/RightSection/services/createObjectToAdd.ts @@ -1,14 +1,14 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; -import { ForItem } from "@/pages/Home/types/forItem"; -import { ConditionItem } from "@/pages/Home/types/conditionItem"; -import { PrintItem } from "@/pages/Home/types/printItem"; -import { ForDataToAdd } from "@/pages/Home/types/dataToAdd/forDataToAdd"; -import { PrintDataToAdd } from "@/pages/Home/types/dataToAdd/printDataToAdd"; -import { IfElseDataToAdd } from "@/pages/Home/types/dataToAdd/ifElseDataToAdd"; -import { IfElseChangeDataToAdd } from "@/pages/Home/types/dataToAdd/ifElseChangeDataToAdd"; -import { CodeFlowVariableDtoToAdd } from "@/pages/Home/types/dataToAdd/codeFlowVariableDataToAdd"; -import { WhileDto } from "@/pages/Home/types/dto/whileDto"; -import { CodeFlowListDto } from "@/pages/Home/types/dto/codeFlowListDto"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; +import { ForItem } from "@/pages/Visualization/types/codeFlow/forItem"; +import { ConditionItem } from "@/pages/Visualization/types/codeFlow/conditionItem"; +import { PrintItem } from "@/pages/Visualization/types/codeFlow/printItem"; +import { ForDataToAdd } from "@/pages/Visualization/types/dataToAdd/forDataToAdd"; +import { PrintDataToAdd } from "@/pages/Visualization/types/dataToAdd/printDataToAdd"; +import { IfElseDataToAdd } from "@/pages/Visualization/types/dataToAdd/ifElseDataToAdd"; +import { IfElseChangeDataToAdd } from "@/pages/Visualization/types/dataToAdd/ifElseChangeDataToAdd"; +import { CodeFlowVariableDtoToAdd } from "@/pages/Visualization/types/dataToAdd/codeFlowVariableDataToAdd"; +import { WhileDto } from "@/pages/Visualization/types/dto/whileDto"; +import { CodeFlowListDto } from "@/pages/Visualization/types/dto/codeFlowListDto"; // 스택에 넣을 객체를 생성하는 함수 export const createObjectToAdd = ( preprocessedCode: PrintDataToAdd | ForDataToAdd | IfElseDataToAdd | WhileDto diff --git a/src/pages/Home/components/RightSection/services/deleteCodeFlow.ts b/src/pages/Visualization/components/RightSection/services/deleteCodeFlow.ts similarity index 86% rename from src/pages/Home/components/RightSection/services/deleteCodeFlow.ts rename to src/pages/Visualization/components/RightSection/services/deleteCodeFlow.ts index 9926521f..ce5f74f2 100644 --- a/src/pages/Home/components/RightSection/services/deleteCodeFlow.ts +++ b/src/pages/Visualization/components/RightSection/services/deleteCodeFlow.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const deleteCodeFlow = (codeFlows: AllObjectItem[], toDeleteId: number): AllObjectItem[] => { return codeFlows diff --git a/src/pages/Home/components/RightSection/services/findDeleteUsedId.ts b/src/pages/Visualization/components/RightSection/services/findDeleteUsedId.ts similarity index 80% rename from src/pages/Home/components/RightSection/services/findDeleteUsedId.ts rename to src/pages/Visualization/components/RightSection/services/findDeleteUsedId.ts index d8075808..982c9648 100644 --- a/src/pages/Home/components/RightSection/services/findDeleteUsedId.ts +++ b/src/pages/Visualization/components/RightSection/services/findDeleteUsedId.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const findDeleteUsedId = (targetChild: AllObjectItem[]): number[] => { let idsToDelete: number[] = []; diff --git a/src/pages/Home/components/RightSection/services/findTargetChild.ts b/src/pages/Visualization/components/RightSection/services/findTargetChild.ts similarity index 85% rename from src/pages/Home/components/RightSection/services/findTargetChild.ts rename to src/pages/Visualization/components/RightSection/services/findTargetChild.ts index bdb3fc21..47306433 100644 --- a/src/pages/Home/components/RightSection/services/findTargetChild.ts +++ b/src/pages/Visualization/components/RightSection/services/findTargetChild.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const findTargetChild = (codeFlows: AllObjectItem[], toAddObject: AllObjectItem): AllObjectItem[] => { let targetChild: AllObjectItem[] = []; diff --git a/src/pages/Home/components/RightSection/services/insertEqualToDepth.ts b/src/pages/Visualization/components/RightSection/services/insertEqualToDepth.ts similarity index 85% rename from src/pages/Home/components/RightSection/services/insertEqualToDepth.ts rename to src/pages/Visualization/components/RightSection/services/insertEqualToDepth.ts index d43306ec..ab75edce 100644 --- a/src/pages/Home/components/RightSection/services/insertEqualToDepth.ts +++ b/src/pages/Visualization/components/RightSection/services/insertEqualToDepth.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const insertEqualToDepth = ( codeFlows: AllObjectItem[], diff --git a/src/pages/Home/components/RightSection/services/insertIntoDepth.ts b/src/pages/Visualization/components/RightSection/services/insertIntoDepth.ts similarity index 86% rename from src/pages/Home/components/RightSection/services/insertIntoDepth.ts rename to src/pages/Visualization/components/RightSection/services/insertIntoDepth.ts index 2434eda6..1162f79f 100644 --- a/src/pages/Home/components/RightSection/services/insertIntoDepth.ts +++ b/src/pages/Visualization/components/RightSection/services/insertIntoDepth.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const insertIntoDepth = ( codeFlows: AllObjectItem[], toAddObject: AllObjectItem, diff --git a/src/pages/Home/components/RightSection/services/refreshCodeFlow.ts b/src/pages/Visualization/components/RightSection/services/refreshCodeFlow.ts similarity index 92% rename from src/pages/Home/components/RightSection/services/refreshCodeFlow.ts rename to src/pages/Visualization/components/RightSection/services/refreshCodeFlow.ts index ab7f7082..99611a29 100644 --- a/src/pages/Home/components/RightSection/services/refreshCodeFlow.ts +++ b/src/pages/Visualization/components/RightSection/services/refreshCodeFlow.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const refreshCodeFlow = ( codeFlows: AllObjectItem[], //현제 코드흐름 시각화 정보를 담고 있는 리스트 diff --git a/src/pages/Home/components/RightSection/services/turnLight.ts b/src/pages/Visualization/components/RightSection/services/turnLight.ts similarity index 83% rename from src/pages/Home/components/RightSection/services/turnLight.ts rename to src/pages/Visualization/components/RightSection/services/turnLight.ts index 85d73610..117df4cd 100644 --- a/src/pages/Home/components/RightSection/services/turnLight.ts +++ b/src/pages/Visualization/components/RightSection/services/turnLight.ts @@ -1,5 +1,5 @@ -import { ActivateItem } from "@/pages/Home/types/activateItem"; -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { ActivateItem } from "@/pages/Visualization/types/activateItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; // 하이라이트 효과를 줘야하는 부분을 표시해주는 함수 export const turnLight = ( diff --git a/src/pages/Home/components/RightSection/services/turnOffAllNodeLight.ts b/src/pages/Visualization/components/RightSection/services/turnOffAllNodeLight.ts similarity index 74% rename from src/pages/Home/components/RightSection/services/turnOffAllNodeLight.ts rename to src/pages/Visualization/components/RightSection/services/turnOffAllNodeLight.ts index 0d222b71..3f3a3865 100644 --- a/src/pages/Home/components/RightSection/services/turnOffAllNodeLight.ts +++ b/src/pages/Visualization/components/RightSection/services/turnOffAllNodeLight.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; export const turnOffAllNodeLight = (codeFlows: AllObjectItem[]): AllObjectItem[] => { return codeFlows.map((codeFlow) => { diff --git a/src/pages/Home/components/RightSection/services/updateActivate.ts b/src/pages/Visualization/components/RightSection/services/updateActivate.ts similarity index 85% rename from src/pages/Home/components/RightSection/services/updateActivate.ts rename to src/pages/Visualization/components/RightSection/services/updateActivate.ts index 5e3b9314..31dcca27 100644 --- a/src/pages/Home/components/RightSection/services/updateActivate.ts +++ b/src/pages/Visualization/components/RightSection/services/updateActivate.ts @@ -1,5 +1,5 @@ -import { ActivateItem } from "@/pages/Home/types/activateItem"; -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { ActivateItem } from "@/pages/Visualization/types/activateItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; // 현재 불이 켜져야하는 부분을 표시해주는 함수 export const updateActivate = ( diff --git a/src/pages/Home/components/RightSection/services/updateCodeFlow.ts b/src/pages/Visualization/components/RightSection/services/updateCodeFlow.ts similarity index 93% rename from src/pages/Home/components/RightSection/services/updateCodeFlow.ts rename to src/pages/Visualization/components/RightSection/services/updateCodeFlow.ts index 16e6139b..a3481c28 100644 --- a/src/pages/Home/components/RightSection/services/updateCodeFlow.ts +++ b/src/pages/Visualization/components/RightSection/services/updateCodeFlow.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "@/pages/Home/types/codeFlow/allObjectItem"; +import { AllObjectItem } from "@/pages/Visualization/types/codeFlow/allObjectItem"; // 객체를 수정해야하는 경우에 실행하는 함수 export const updateCodeFlow = ( diff --git a/src/pages/Home/components/RightSection/services/updateDataStructure.ts b/src/pages/Visualization/components/RightSection/services/updateDataStructure.ts similarity index 81% rename from src/pages/Home/components/RightSection/services/updateDataStructure.ts rename to src/pages/Visualization/components/RightSection/services/updateDataStructure.ts index 65822dc5..0f476839 100644 --- a/src/pages/Home/components/RightSection/services/updateDataStructure.ts +++ b/src/pages/Visualization/components/RightSection/services/updateDataStructure.ts @@ -1,4 +1,4 @@ -import { AllDataStructureItem } from "@/pages/Home/types/dataStructuresItem/allDataStructureItem"; +import { AllDataStructureItem } from "@/pages/Visualization/types/dataStructuresItem/allDataStructureItem"; // 자료구조 부분을 수정할때 실행하는 함수 export const updateDataStructure = ( targetName: string, diff --git a/src/pages/Home/gutter.css b/src/pages/Visualization/gutter.css similarity index 100% rename from src/pages/Home/gutter.css rename to src/pages/Visualization/gutter.css diff --git a/src/pages/Home/types/activateItem.ts b/src/pages/Visualization/types/activateItem.ts similarity index 100% rename from src/pages/Home/types/activateItem.ts rename to src/pages/Visualization/types/activateItem.ts diff --git a/src/pages/Home/types/codeFlow/allObjectItem.ts b/src/pages/Visualization/types/codeFlow/allObjectItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/allObjectItem.ts rename to src/pages/Visualization/types/codeFlow/allObjectItem.ts diff --git a/src/pages/Home/types/codeFlow/assignVizItem.ts b/src/pages/Visualization/types/codeFlow/assignVizItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/assignVizItem.ts rename to src/pages/Visualization/types/codeFlow/assignVizItem.ts diff --git a/src/pages/Home/types/codeFlow/codeFlowListItem.ts b/src/pages/Visualization/types/codeFlow/codeFlowListItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/codeFlowListItem.ts rename to src/pages/Visualization/types/codeFlow/codeFlowListItem.ts diff --git a/src/pages/Home/types/codeFlow/codeFlowVariableItem.ts b/src/pages/Visualization/types/codeFlow/codeFlowVariableItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/codeFlowVariableItem.ts rename to src/pages/Visualization/types/codeFlow/codeFlowVariableItem.ts diff --git a/src/pages/Home/types/codeFlow/conditionItem.ts b/src/pages/Visualization/types/codeFlow/conditionItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/conditionItem.ts rename to src/pages/Visualization/types/codeFlow/conditionItem.ts diff --git a/src/pages/Home/types/codeFlow/elseItem.ts b/src/pages/Visualization/types/codeFlow/elseItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/elseItem.ts rename to src/pages/Visualization/types/codeFlow/elseItem.ts diff --git a/src/pages/Home/types/codeFlow/forItem.ts b/src/pages/Visualization/types/codeFlow/forItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/forItem.ts rename to src/pages/Visualization/types/codeFlow/forItem.ts diff --git a/src/pages/Home/types/codeFlow/listItem.ts b/src/pages/Visualization/types/codeFlow/listItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/listItem.ts rename to src/pages/Visualization/types/codeFlow/listItem.ts diff --git a/src/pages/Home/types/codeFlow/printItem.ts b/src/pages/Visualization/types/codeFlow/printItem.ts similarity index 76% rename from src/pages/Home/types/codeFlow/printItem.ts rename to src/pages/Visualization/types/codeFlow/printItem.ts index 87284ed8..49d93556 100644 --- a/src/pages/Home/types/codeFlow/printItem.ts +++ b/src/pages/Visualization/types/codeFlow/printItem.ts @@ -1,4 +1,4 @@ -import { AllObjectItem } from "./codeFlow/allObjectItem"; +import { AllObjectItem } from "./allObjectItem"; export interface PrintItem { id: number; diff --git a/src/pages/Home/types/codeFlow/whileItem.ts b/src/pages/Visualization/types/codeFlow/whileItem.ts similarity index 100% rename from src/pages/Home/types/codeFlow/whileItem.ts rename to src/pages/Visualization/types/codeFlow/whileItem.ts diff --git a/src/pages/Home/types/dataStructuresItem/allDataStructureItem.ts b/src/pages/Visualization/types/dataStructuresItem/allDataStructureItem.ts similarity index 100% rename from src/pages/Home/types/dataStructuresItem/allDataStructureItem.ts rename to src/pages/Visualization/types/dataStructuresItem/allDataStructureItem.ts diff --git a/src/pages/Home/types/dataStructuresItem/dataStructureListItem.ts b/src/pages/Visualization/types/dataStructuresItem/dataStructureListItem.ts similarity index 100% rename from src/pages/Home/types/dataStructuresItem/dataStructureListItem.ts rename to src/pages/Visualization/types/dataStructuresItem/dataStructureListItem.ts diff --git a/src/pages/Home/types/dataStructuresItem/dataStructureVarItem.ts b/src/pages/Visualization/types/dataStructuresItem/dataStructureVarItem.ts similarity index 100% rename from src/pages/Home/types/dataStructuresItem/dataStructureVarItem.ts rename to src/pages/Visualization/types/dataStructuresItem/dataStructureVarItem.ts diff --git a/src/pages/Home/types/dataToAdd/codeFlowVariableDataToAdd.ts b/src/pages/Visualization/types/dataToAdd/codeFlowVariableDataToAdd.ts similarity index 100% rename from src/pages/Home/types/dataToAdd/codeFlowVariableDataToAdd.ts rename to src/pages/Visualization/types/dataToAdd/codeFlowVariableDataToAdd.ts diff --git a/src/pages/Home/types/dataToAdd/forDataToAdd.ts b/src/pages/Visualization/types/dataToAdd/forDataToAdd.ts similarity index 100% rename from src/pages/Home/types/dataToAdd/forDataToAdd.ts rename to src/pages/Visualization/types/dataToAdd/forDataToAdd.ts diff --git a/src/pages/Home/types/dataToAdd/ifElseChangeDataToAdd.ts b/src/pages/Visualization/types/dataToAdd/ifElseChangeDataToAdd.ts similarity index 100% rename from src/pages/Home/types/dataToAdd/ifElseChangeDataToAdd.ts rename to src/pages/Visualization/types/dataToAdd/ifElseChangeDataToAdd.ts diff --git a/src/pages/Home/types/dataToAdd/ifElseDataToAdd.ts b/src/pages/Visualization/types/dataToAdd/ifElseDataToAdd.ts similarity index 100% rename from src/pages/Home/types/dataToAdd/ifElseDataToAdd.ts rename to src/pages/Visualization/types/dataToAdd/ifElseDataToAdd.ts diff --git a/src/pages/Home/types/dataToAdd/printDataToAdd.ts b/src/pages/Visualization/types/dataToAdd/printDataToAdd.ts similarity index 100% rename from src/pages/Home/types/dataToAdd/printDataToAdd.ts rename to src/pages/Visualization/types/dataToAdd/printDataToAdd.ts diff --git a/src/pages/Home/types/dto/ValidTypeDto.ts b/src/pages/Visualization/types/dto/ValidTypeDto.ts similarity index 100% rename from src/pages/Home/types/dto/ValidTypeDto.ts rename to src/pages/Visualization/types/dto/ValidTypeDto.ts diff --git a/src/pages/Home/types/dto/codeFlowListDto.ts b/src/pages/Visualization/types/dto/codeFlowListDto.ts similarity index 100% rename from src/pages/Home/types/dto/codeFlowListDto.ts rename to src/pages/Visualization/types/dto/codeFlowListDto.ts diff --git a/src/pages/Home/types/dto/codeFlowVariableDto.ts b/src/pages/Visualization/types/dto/codeFlowVariableDto.ts similarity index 100% rename from src/pages/Home/types/dto/codeFlowVariableDto.ts rename to src/pages/Visualization/types/dto/codeFlowVariableDto.ts diff --git a/src/pages/Home/types/dto/forDto.ts b/src/pages/Visualization/types/dto/forDto.ts similarity index 100% rename from src/pages/Home/types/dto/forDto.ts rename to src/pages/Visualization/types/dto/forDto.ts diff --git a/src/pages/Home/types/dto/ifElseChangeDto.ts b/src/pages/Visualization/types/dto/ifElseChangeDto.ts similarity index 100% rename from src/pages/Home/types/dto/ifElseChangeDto.ts rename to src/pages/Visualization/types/dto/ifElseChangeDto.ts diff --git a/src/pages/Home/types/dto/ifElseDto.ts b/src/pages/Visualization/types/dto/ifElseDto.ts similarity index 100% rename from src/pages/Home/types/dto/ifElseDto.ts rename to src/pages/Visualization/types/dto/ifElseDto.ts diff --git a/src/pages/Home/types/dto/printDto.ts b/src/pages/Visualization/types/dto/printDto.ts similarity index 100% rename from src/pages/Home/types/dto/printDto.ts rename to src/pages/Visualization/types/dto/printDto.ts diff --git a/src/pages/Home/types/dto/variableDto.ts b/src/pages/Visualization/types/dto/variableDto.ts similarity index 100% rename from src/pages/Home/types/dto/variableDto.ts rename to src/pages/Visualization/types/dto/variableDto.ts diff --git a/src/pages/Home/types/dto/variablesDto.ts b/src/pages/Visualization/types/dto/variablesDto.ts similarity index 100% rename from src/pages/Home/types/dto/variablesDto.ts rename to src/pages/Visualization/types/dto/variablesDto.ts diff --git a/src/pages/Home/types/dto/whileDto.ts b/src/pages/Visualization/types/dto/whileDto.ts similarity index 100% rename from src/pages/Home/types/dto/whileDto.ts rename to src/pages/Visualization/types/dto/whileDto.ts diff --git a/src/pages/components/LoggedInHeader.module.css b/src/pages/components/LoggedInHeader.module.css index 2d52065b..ae08e58b 100644 --- a/src/pages/components/LoggedInHeader.module.css +++ b/src/pages/components/LoggedInHeader.module.css @@ -7,6 +7,9 @@ header { border-bottom: 1px solid var(--gray01); background-color: #fff; } +.header-logo img { + height: 32px; +} .bg-blue { background-color: #f8f9ff; } @@ -35,4 +38,5 @@ header { .logout { color: #5a5a5a; + cursor: pointer; } diff --git a/src/pages/components/LoggedInHeader.tsx b/src/pages/components/LoggedInHeader.tsx index cad6fafd..093cf5a5 100644 --- a/src/pages/components/LoggedInHeader.tsx +++ b/src/pages/components/LoggedInHeader.tsx @@ -1,24 +1,44 @@ import styles from "./LoggedInHeader.module.css"; - +import { useUserStore } from "@/store/user"; +import { Cookies } from "react-cookie"; +import { Link, NavLink } from "react-router-dom"; const LoggedInHeader = () => { + const cookies = new Cookies(); + const loggedInUserName = useUserStore((state) => state.loggedInUserName); + const resetUser = useUserStore((state) => state.resetUser); + const logout = () => { + resetUser(); + cookies.remove("token"); + }; + console.log(NavLink); return (
    - + 로고 - + {/* */} - 학생목록 - + (isActive ? styles["on_active"] : "")}> + 학생목록 + + + (isActive ? styles["on_active"] : "")}> 시각화 - - 과제 - 설정 + + + (isActive ? styles["on_active"] : "")}> + 과제 + + (isActive ? styles["on_active"] : "")}> + 설정 +
    +
    - - 로그아웃 - + {loggedInUserName === "" ? null : {loggedInUserName}님} + + 로그아웃 +
    ); diff --git a/src/pages/components/PublicHeader.module.css b/src/pages/components/PublicHeader.module.css index fc9c984f..9b9152d4 100644 --- a/src/pages/components/PublicHeader.module.css +++ b/src/pages/components/PublicHeader.module.css @@ -7,6 +7,9 @@ header { border-bottom: 1px solid var(--gray01); background-color: #fff; } +.header-logo img { + height: 32px; +} .bg-blue { background-color: #f8f9ff; } diff --git a/src/pages/components/PublicHeader.tsx b/src/pages/components/PublicHeader.tsx index bb447001..b54ea481 100644 --- a/src/pages/components/PublicHeader.tsx +++ b/src/pages/components/PublicHeader.tsx @@ -1,23 +1,27 @@ +import { Link } from "react-router-dom"; import styles from "./PublicHeader.module.css"; const PublicHeader = () => { return (
    - + 로고 - + {/* */} - 시각화 + + 시각화 + 가격
    +
    ); diff --git a/src/store/user.ts b/src/store/user.ts index 3ca0d418..7f8ae4f2 100644 --- a/src/store/user.ts +++ b/src/store/user.ts @@ -1,16 +1,22 @@ import { create } from "zustand"; import { devtools } from "zustand/middleware"; interface UserState { - loggedInUserId: string; - loggedInUserPassword: string; - setLoggedInUserId: (user: string) => void; - setLoggedInUserPassword: (password: string) => void; + loggedInUserEmail: string; + loggedInUserName: string; + loggedInUserRole: string; + setLoggedInUserEmail: (user: string) => void; + setLoggedInUserName: (username: string) => void; + setLoggedInUserRole: (role: string) => void; + resetUser: () => void; } export const useUserStore = create( devtools((set) => ({ - loggedInUserId: "", - loggedInUserPassword: "", - setLoggedInUserId: (loggedInUserId) => set({ loggedInUserId }), - setLoggedInUserPassword: (loggedInUserPassword) => set({ loggedInUserPassword }), + loggedInUserEmail: "", + loggedInUserName: "", + loggedInUserRole: "", + setLoggedInUserEmail: (loggedInUserEmail) => set({ loggedInUserEmail }), + setLoggedInUserName: (loggedInUserName) => set({ loggedInUserName }), + setLoggedInUserRole: (loggedInUserRole) => set({ loggedInUserRole }), + resetUser: () => set({ loggedInUserEmail: "", loggedInUserName: "", loggedInUserRole: "" }), })) );