From 3dda0470b4859536d8b90618cc633b21cc96aebb Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 16:52:43 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[build]=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=99=80=20=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=8B=A4=EB=A5=B4=EA=B2=8C=20?= =?UTF-8?q?=EB=B9=8C=EB=93=9C=EB=90=98=EA=B2=8C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin.html | 14 ++++++++ build.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 12 +++---- prerender.js | 26 -------------- vite.config.js | 5 ++- 5 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 admin.html create mode 100644 build.js delete mode 100644 prerender.js diff --git a/admin.html b/admin.html new file mode 100644 index 00000000..ea275476 --- /dev/null +++ b/admin.html @@ -0,0 +1,14 @@ + + + + + + + + Awesome Orange - Admin + + +
+ + + diff --git a/build.js b/build.js new file mode 100644 index 00000000..3c8c084c --- /dev/null +++ b/build.js @@ -0,0 +1,94 @@ +import { build } from "vite"; +import { parse, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { readFile, writeFile, rm } from "node:fs/promises"; +import config from "./vite.config.js"; + +const __dirname = fileURLToPath(new URL('.', import.meta.url)); +const mode = process.argv[2] ?? "main"; +const toAbsolute = (p) => resolve(__dirname, p); + +const buildConfig = { + main: { + clientEntry: "index.html", + sourceDir: "mainPage", + ssgEntry: "main-server.jsx" + }, + admin: { + clientEntry: "admin.html", + sourceDir: "adminPage", + ssgEntry: "main-server.jsx", + url: [ + "index", + "events", + "events/create", + "login", + "events/[id]", + "comments", + "comments/[id]" + ] + }, +} + +async function processBuild(mode) +{ + await Promise.all([buildClient(mode), buildSSG(mode)]); + await injectSSGToHtml(mode); +} + +async function buildClient(mode) +{ + await build({ + ...config, + build: { + rollupOptions: { + input: { + entry: buildConfig[mode].clientEntry + }, + output: { + dir: `dist/${mode}` + } + } + } + }); + await rm(toAbsolute(`dist/${mode}/mockServiceWorker.js`)); +} + +function buildSSG(mode) +{ + return build({ + ...config, + build: { + ssr: true, + rollupOptions: { + input: { + entry: `src/${buildConfig[mode].sourceDir}/${buildConfig[mode].ssgEntry}` + }, + output: { + dir: `dist-ssg/${mode}` + } + } + } + }); +} + +async function injectSSGToHtml(mode) +{ + console.log("--ssg result--"); + const {default: render} = await import(`./dist-ssg/${mode}/entry.js`); + const template = await readFile(`dist/${mode}/${buildConfig[mode].clientEntry}`, "utf-8"); + + const urlEntryPoint = buildConfig[mode].url ?? ["index"]; + + const promises = urlEntryPoint.map( async (path)=>{ + const html = template.replace("", render(path)); + const absolutePath = toAbsolute(`dist/${mode}/${path}.html`); + + await writeFile(absolutePath, html); + console.log(`pre-rendered : ${absolutePath}`); + } ); + await Promise.allSettled(promises); + console.log("--successfully build completed!--"); +} + +processBuild(mode); \ No newline at end of file diff --git a/package.json b/package.json index 53ef909c..2e673418 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,17 @@ { - "name": "vite-project", + "name": "awesome-orange-project", "private": true, - "version": "0.0.0", + "version": "0.5.0", "type": "module", "scripts": { "dev": "vite --host", - "build": "vite build && npm run build:server && node prerender.js && rm dist/mockServiceWorker.js", - "build:client": "vite build", - "build:server": "vite build --ssr src/main-server.jsx --outDir dist-ssg", + "build": "node build.js main", + "build-admin": "node build.js admin", "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,json,css}'", "lint": "eslint . --ext js,jsx --max-warnings 0", "lint-fix": "eslint . --ext js,jsx --fix", - "preview": "vite preview" + "preview": "vite preview --outDir dist/main", + "preview-admin": "vite preview --outDir dist/admin" }, "dependencies": { "react": "^18.3.1", diff --git a/prerender.js b/prerender.js deleted file mode 100644 index c6229910..00000000 --- a/prerender.js +++ /dev/null @@ -1,26 +0,0 @@ -import render from "./dist-ssg/main-server.js"; -import { readdirSync } from "node:fs"; -import { readFile, writeFile } from "node:fs/promises"; -import { dirname, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; - -const __dirName = dirname(fileURLToPath(import.meta.url)); -const toAbsolute = (p) => resolve(__dirName, p); - -console.log("--ssg result--"); - -const htmlPath = readdirSync(toAbsolute("dist")).filter((filePath) => - filePath.endsWith(".html"), -); - -async function injectSSGToHtml(path) { - const absolutePath = toAbsolute("dist/" + path); - - const template = await readFile(absolutePath, "utf-8"); - const html = template.replace("", render(path)); - - await writeFile(absolutePath, html); - console.log(`pre-rendered : ${path}`); -} - -htmlPath.forEach(injectSSGToHtml); diff --git a/vite.config.js b/vite.config.js index 81964c96..120feba1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,8 +1,11 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; -import { resolve } from "path"; +import { resolve } from "node:path"; +import { fileURLToPath } from "node:url"; import svgr from "vite-plugin-svgr"; +const __dirname = fileURLToPath(new URL('.', import.meta.url)); + // https://vitejs.dev/config/ export default defineConfig({ base: "./", From 11e65457c566e2ec4efbccbc6ccc5f6376bb8a95 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 17:23:01 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[fix]=20admin=20=EB=B9=8C=EB=93=9C=EC=8B=9C?= =?UTF-8?q?=20nested=EB=90=9C=20=EA=B1=B0=20=EC=A0=9C=EC=99=B8=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.js | 19 +++++++++++++------ src/adminPage/App.jsx | 9 +++++++++ src/adminPage/index.css | 34 ++++++++++++++++++++++++++++++++++ src/adminPage/main-client.jsx | 28 ++++++++++++++++++++++++++++ src/adminPage/main-server.jsx | 25 +++++++++++++++++++++++++ src/adminPage/mock.js | 6 ++++++ 6 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 src/adminPage/App.jsx create mode 100644 src/adminPage/index.css create mode 100644 src/adminPage/main-client.jsx create mode 100644 src/adminPage/main-server.jsx create mode 100644 src/adminPage/mock.js diff --git a/build.js b/build.js index 3c8c084c..c85f40d9 100644 --- a/build.js +++ b/build.js @@ -1,7 +1,7 @@ import { build } from "vite"; -import { parse, resolve } from "node:path"; +import { parse, resolve, dirname } from "node:path"; import { fileURLToPath } from "node:url"; -import { readFile, writeFile, rm } from "node:fs/promises"; +import { readFile, writeFile, rm, mkdir } from "node:fs/promises"; import config from "./vite.config.js"; const __dirname = fileURLToPath(new URL('.', import.meta.url)); @@ -81,13 +81,20 @@ async function injectSSGToHtml(mode) const urlEntryPoint = buildConfig[mode].url ?? ["index"]; const promises = urlEntryPoint.map( async (path)=>{ - const html = template.replace("", render(path)); const absolutePath = toAbsolute(`dist/${mode}/${path}.html`); + try { + const html = template.replace("", render(path)); - await writeFile(absolutePath, html); - console.log(`pre-rendered : ${absolutePath}`); + const dir = dirname(absolutePath); + await mkdir(dir, { recursive: true }); + await writeFile(absolutePath, html); + console.log(`pre-rendered : ${path}`); + } + catch { + console.log(`pre-rendered failed : ${path}`); + } } ); - await Promise.allSettled(promises); + Promise.allSettled(promises); console.log("--successfully build completed!--"); } diff --git a/src/adminPage/App.jsx b/src/adminPage/App.jsx new file mode 100644 index 00000000..32a6d630 --- /dev/null +++ b/src/adminPage/App.jsx @@ -0,0 +1,9 @@ +function App() { + return ( + <> +
Hello, this is admin page!
+ + ); +} + +export default App; diff --git a/src/adminPage/index.css b/src/adminPage/index.css new file mode 100644 index 00000000..5d8fc6ec --- /dev/null +++ b/src/adminPage/index.css @@ -0,0 +1,34 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@font-face { + font-family: "ds-digital"; + src: url("/font/DS-DIGI.TTF") format("truetype"); + font-display: swap; +} + +@font-face { + font-family: "hdsans"; + src: url("/font/HyundaiSansTextKROTFBold.otf") format("opentype"); + font-weight: bold; + font-display: swap; +} + +@font-face { + font-family: "hdsans"; + src: url("/font/HyundaiSansTextKROTFMedium.otf") format("opentype"); + font-weight: medium; + font-display: swap; +} + +@layer base { + body { + font-family: "hdsans"; + } + body.scrollLocked { + position: fixed; + width: 100%; + overflow-y: scroll; + } +} diff --git a/src/adminPage/main-client.jsx b/src/adminPage/main-client.jsx new file mode 100644 index 00000000..7d182fed --- /dev/null +++ b/src/adminPage/main-client.jsx @@ -0,0 +1,28 @@ +import { StrictMode } from "react"; +import { createRoot, hydrateRoot } from "react-dom/client"; +import App from "./App.jsx"; +import "./index.css"; + +const $root = document.getElementById("root"); +const app = ( + + + +); + +if (import.meta.env.DEV) { + // 개발 시 + const enableMocking = async function () { + // 실서버와 연동시 //return;의 주석 지워서 테스트해주세요 + // return; + const worker = (await import("./mock.js")).default; + await worker.start({ onUnhandledRequest: "bypass" }); + }; + enableMocking().then(() => { + const root = createRoot($root); + root.render(app); + }); +} else { + // 배포 시 + hydrateRoot($root, app); +} diff --git a/src/adminPage/main-server.jsx b/src/adminPage/main-server.jsx new file mode 100644 index 00000000..b085d3ff --- /dev/null +++ b/src/adminPage/main-server.jsx @@ -0,0 +1,25 @@ +import { StrictMode } from "react"; +import { renderToString } from "react-dom/server"; +import App from "./App.jsx"; + +export default function render() { + return renderToString( + + + , + ); +} + +/** + * 우리의 메인 컴포넌트를 문자열로 렌더링하는 함수를 반환합니다. + * + * 향후 페이지가 추가된다면, + * + * import SecondPage from "./SecondPage.jsx"; + * + * export default function render(url) { + * // 여기에서 url에 따라 분기처리를 하면 됩니다. + * } + * + * 현재로서는 단일 페이지이므로 render 함수 내에 분기처리를 하지 않습니다. + */ diff --git a/src/adminPage/mock.js b/src/adminPage/mock.js new file mode 100644 index 00000000..b9188b12 --- /dev/null +++ b/src/adminPage/mock.js @@ -0,0 +1,6 @@ +import { setupWorker } from "msw/browser"; + +// mocking은 기본적으로 각 feature 폴더 내의 mock.js로 정의합니다. +// 새로운 feature의 mocking을 추가하셨으면, mock.js의 setupWorker 내부 함수에 인자를 spread 연산자를 이용해 추가해주세요. +// 예시 : export default setupWorker(...authHandler, ...questionHandler, ...articleHandler); +export default setupWorker(); From 464a489fcb6d09570918974689558cd0d8f78fb2 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 17:50:23 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[build]=20=EC=96=B4=EB=93=9C=EB=AF=BC=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A6=AC=EC=95=A1=ED=8A=B8=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.js | 2 +- package-lock.json | 50 ++++++++++++++++++++++++++++++++--- package.json | 1 + src/adminPage/App.jsx | 7 ++++- src/adminPage/main-client.jsx | 18 ++++++++----- src/adminPage/main-server.jsx | 11 +++++--- vite-devRouter.js | 33 +++++++++++++++++++++++ vite.config.js | 10 ++++++- 8 files changed, 115 insertions(+), 17 deletions(-) create mode 100644 vite-devRouter.js diff --git a/build.js b/build.js index c85f40d9..3e9142c6 100644 --- a/build.js +++ b/build.js @@ -94,7 +94,7 @@ async function injectSSGToHtml(mode) console.log(`pre-rendered failed : ${path}`); } } ); - Promise.allSettled(promises); + await Promise.allSettled(promises); console.log("--successfully build completed!--"); } diff --git a/package-lock.json b/package-lock.json index e73423db..656e1867 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { - "name": "vite-project", - "version": "0.0.0", + "name": "awesome-orange-project", + "version": "0.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "vite-project", - "version": "0.0.0", + "name": "awesome-orange-project", + "version": "0.5.0", "dependencies": { "react": "^18.3.1", "react-dom": "^18.3.1", "react-lottie-player": "^2.1.0", + "react-router-dom": "^6.26.0", "swiper": "^11.1.9", "zustand": "^4.5.4" }, @@ -1280,6 +1281,15 @@ "node": ">=14" } }, + "node_modules/@remix-run/router": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.0.tgz", + "integrity": "sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", @@ -5634,6 +5644,38 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.26.0.tgz", + "integrity": "sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.19.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.0.tgz", + "integrity": "sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.19.0", + "react-router": "6.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/package.json b/package.json index 2e673418..7ffc8ff7 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-lottie-player": "^2.1.0", + "react-router-dom": "^6.26.0", "swiper": "^11.1.9", "zustand": "^4.5.4" }, diff --git a/src/adminPage/App.jsx b/src/adminPage/App.jsx index 32a6d630..2e9ef7e7 100644 --- a/src/adminPage/App.jsx +++ b/src/adminPage/App.jsx @@ -1,7 +1,12 @@ +import { Route, Routes } from "react-router-dom"; + function App() { return ( <> -
Hello, this is admin page!
+ + events} /> + hello} /> + ); } diff --git a/src/adminPage/main-client.jsx b/src/adminPage/main-client.jsx index 7d182fed..54ade981 100644 --- a/src/adminPage/main-client.jsx +++ b/src/adminPage/main-client.jsx @@ -1,14 +1,10 @@ import { StrictMode } from "react"; import { createRoot, hydrateRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; import App from "./App.jsx"; import "./index.css"; const $root = document.getElementById("root"); -const app = ( - - - -); if (import.meta.env.DEV) { // 개발 시 @@ -20,9 +16,17 @@ if (import.meta.env.DEV) { }; enableMocking().then(() => { const root = createRoot($root); - root.render(app); + root.render( + + + + ); }); } else { // 배포 시 - hydrateRoot($root, app); + hydrateRoot($root, + + + + ); } diff --git a/src/adminPage/main-server.jsx b/src/adminPage/main-server.jsx index b085d3ff..55aa0715 100644 --- a/src/adminPage/main-server.jsx +++ b/src/adminPage/main-server.jsx @@ -1,13 +1,18 @@ import { StrictMode } from "react"; import { renderToString } from "react-dom/server"; +import { StaticRouter } from "react-router-dom/server"; import App from "./App.jsx"; -export default function render() { - return renderToString( +export default function render(url) { + const path = url === "index" ? "/" : `/${url}`; + const nye = renderToString( - + + + , ); + return nye; } /** diff --git a/vite-devRouter.js b/vite-devRouter.js new file mode 100644 index 00000000..ab85f5f9 --- /dev/null +++ b/vite-devRouter.js @@ -0,0 +1,33 @@ +// from monument gallery +export default function devRouter(rawRouteList) { + // 문자열로 된 route list를 정규표현식으로 변환하고, 정규표현식이 아닌 것들을 제거합니다. + const routeList = rawRouteList + .map(([route, html]) => { + if (typeof route === "string") { + route = new RegExp(`^${route.replace(/\*/g, ".*").replace(/\?/g, ".")}/?$`); + } + return [route, html]; + }) + .filter(([route]) => route instanceof RegExp); + + // 요청한 패스가 설정된 라우팅 경로에 맞는지 확인합니다. + function foundRoute(path) { + for (let [route, html] of routeList) { + if (route.test(path)) return html; + } + return null; + } + + return { + name: "route-server", + configureServer(server) { + server.middlewares.use((req, res, next) => { + const htmlPath = foundRoute(req.originalUrl); + if (htmlPath === null) return next(); + req.url = htmlPath; + req.originalUrl = htmlPath; + next(); + }); + }, + }; +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 120feba1..34fa7ca0 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,5 +1,6 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import devRouter from "./vite-devRouter.js"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; import svgr from "vite-plugin-svgr"; @@ -9,7 +10,14 @@ const __dirname = fileURLToPath(new URL('.', import.meta.url)); // https://vitejs.dev/config/ export default defineConfig({ base: "./", - plugins: [react(), svgr()], + plugins: [ + devRouter([ + ["/admin", "/admin.html"], + ["/admin/*", "/admin.html"], + ]), + react(), + svgr() + ], resolve: { alias: [ { find: "@", replacement: resolve(__dirname, "src") }, From a43a97ae0788c769668a09c6ead2588a360261f3 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 18:02:59 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[chore]=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/{ => images}/active1.png | Bin public/{ => images}/active2.png | Bin public/{ => images}/active3.png | Bin public/{ => images}/active4.png | Bin public/{ => images}/active5.png | Bin public/{ => images}/carimg1.png | Bin public/{ => images}/carimg2.png | Bin public/{ => images}/carimg3.png | Bin public/{ => images}/carimg4.png | Bin public/{ => images}/carimg5.png | Bin public/{ => images}/gift_car.png | Bin public/{ => images}/gift_jeju.png | Bin public/{ => images}/gift_portable.png | Bin public/{ => images}/inactive1.png | Bin public/{ => images}/inactive2.png | Bin public/{ => images}/inactive3.png | Bin public/{ => images}/inactive4.png | Bin public/{ => images}/inactive5.png | Bin src/mainPage/features/interactions/content.json | 6 +++--- .../interactions/description/InteractionSlide.jsx | 6 +++--- .../features/simpleInformation/content.json | 10 +++++----- 21 files changed, 11 insertions(+), 11 deletions(-) rename public/{ => images}/active1.png (100%) rename public/{ => images}/active2.png (100%) rename public/{ => images}/active3.png (100%) rename public/{ => images}/active4.png (100%) rename public/{ => images}/active5.png (100%) rename public/{ => images}/carimg1.png (100%) rename public/{ => images}/carimg2.png (100%) rename public/{ => images}/carimg3.png (100%) rename public/{ => images}/carimg4.png (100%) rename public/{ => images}/carimg5.png (100%) rename public/{ => images}/gift_car.png (100%) rename public/{ => images}/gift_jeju.png (100%) rename public/{ => images}/gift_portable.png (100%) rename public/{ => images}/inactive1.png (100%) rename public/{ => images}/inactive2.png (100%) rename public/{ => images}/inactive3.png (100%) rename public/{ => images}/inactive4.png (100%) rename public/{ => images}/inactive5.png (100%) diff --git a/public/active1.png b/public/images/active1.png similarity index 100% rename from public/active1.png rename to public/images/active1.png diff --git a/public/active2.png b/public/images/active2.png similarity index 100% rename from public/active2.png rename to public/images/active2.png diff --git a/public/active3.png b/public/images/active3.png similarity index 100% rename from public/active3.png rename to public/images/active3.png diff --git a/public/active4.png b/public/images/active4.png similarity index 100% rename from public/active4.png rename to public/images/active4.png diff --git a/public/active5.png b/public/images/active5.png similarity index 100% rename from public/active5.png rename to public/images/active5.png diff --git a/public/carimg1.png b/public/images/carimg1.png similarity index 100% rename from public/carimg1.png rename to public/images/carimg1.png diff --git a/public/carimg2.png b/public/images/carimg2.png similarity index 100% rename from public/carimg2.png rename to public/images/carimg2.png diff --git a/public/carimg3.png b/public/images/carimg3.png similarity index 100% rename from public/carimg3.png rename to public/images/carimg3.png diff --git a/public/carimg4.png b/public/images/carimg4.png similarity index 100% rename from public/carimg4.png rename to public/images/carimg4.png diff --git a/public/carimg5.png b/public/images/carimg5.png similarity index 100% rename from public/carimg5.png rename to public/images/carimg5.png diff --git a/public/gift_car.png b/public/images/gift_car.png similarity index 100% rename from public/gift_car.png rename to public/images/gift_car.png diff --git a/public/gift_jeju.png b/public/images/gift_jeju.png similarity index 100% rename from public/gift_jeju.png rename to public/images/gift_jeju.png diff --git a/public/gift_portable.png b/public/images/gift_portable.png similarity index 100% rename from public/gift_portable.png rename to public/images/gift_portable.png diff --git a/public/inactive1.png b/public/images/inactive1.png similarity index 100% rename from public/inactive1.png rename to public/images/inactive1.png diff --git a/public/inactive2.png b/public/images/inactive2.png similarity index 100% rename from public/inactive2.png rename to public/images/inactive2.png diff --git a/public/inactive3.png b/public/images/inactive3.png similarity index 100% rename from public/inactive3.png rename to public/images/inactive3.png diff --git a/public/inactive4.png b/public/images/inactive4.png similarity index 100% rename from public/inactive4.png rename to public/images/inactive4.png diff --git a/public/inactive5.png b/public/images/inactive5.png similarity index 100% rename from public/inactive5.png rename to public/images/inactive5.png diff --git a/src/mainPage/features/interactions/content.json b/src/mainPage/features/interactions/content.json index 5548cffc..64020585 100644 --- a/src/mainPage/features/interactions/content.json +++ b/src/mainPage/features/interactions/content.json @@ -46,7 +46,7 @@ }, "gift": [ { - "src": "gift_jeju.png", + "src": "images/gift_jeju.png", "name": "제주 여행 패키지", "num": 10, "desc": "항공권, 숙박비, 아이오닉5 렌터카\n(충전 비용 포함)", @@ -55,7 +55,7 @@ "starTextColor": "#957029" }, { - "src": "gift_car.png", + "src": "images/gift_car.png", "name": "더뉴 아이오닉5 시승권", "num": 50, "desc": "10-12월 중 날짜 선택 가능", @@ -64,7 +64,7 @@ "starTextColor": "#36B1E6" }, { - "src": "gift_portable.png", + "src": "images/gift_portable.png", "name": "포터블 인덕션", "num": 100, "desc": "블랙/화이트 컬러 랜덤 증정", diff --git a/src/mainPage/features/interactions/description/InteractionSlide.jsx b/src/mainPage/features/interactions/description/InteractionSlide.jsx index fb3d2131..a0c8f6ba 100644 --- a/src/mainPage/features/interactions/description/InteractionSlide.jsx +++ b/src/mainPage/features/interactions/description/InteractionSlide.jsx @@ -20,8 +20,8 @@ export default function InteractionSlide({ slideTo, answer, }) { - const activeImgPath = `active${index + 1}.png`; - const inactiveImgPath = `inactive${index + 1}.png`; + const activeImgPath = `images/active${index + 1}.png`; + const inactiveImgPath = `images/inactive${index + 1}.png`; const numberImgPath = `icons/rect${index + 1}.svg`; function onClickExperience() { @@ -43,7 +43,7 @@ export default function InteractionSlide({
- + Date: Mon, 12 Aug 2024 18:17:06 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[scaffold]=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/adminPage/App.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/adminPage/App.jsx b/src/adminPage/App.jsx index 2e9ef7e7..45f81d71 100644 --- a/src/adminPage/App.jsx +++ b/src/adminPage/App.jsx @@ -4,11 +4,16 @@ function App() { return ( <> - events
} /> + event 생성 화면} /> + event 보는 화면} /> + 이벤트 목록 화면} /> + 기대평 화면} /> + 기대평 검색 화면} /> + 로그인 화면} /> hello} /> ); } -export default App; +export default App; \ No newline at end of file From 232a7822bc706ce061d20f583c431623b8ddbfd3 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 18:31:48 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[fix]=20=EB=A9=94=EC=9D=B8=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=86=A0=ED=81=B0/=EC=96=B4=EB=93=9C?= =?UTF-8?q?=EB=AF=BC=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=8B=9C=20?= =?UTF-8?q?=ED=99=98=EC=98=81=ED=95=A9=EB=8B=88=EB=8B=A4=EA=B0=80=20?= =?UTF-8?q?=EC=A6=89=EC=8B=9C=20=EC=97=86=EC=96=B4=EC=A7=80=EB=8D=98=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/constants.js | 3 ++- src/common/dataFetch/tokenSaver.js | 20 ++++++++++---------- src/common/modal/modal.jsx | 17 ++++++++++------- src/mainPage/shared/auth/store.js | 5 +++-- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/common/constants.js b/src/common/constants.js index f8ec92ef..609e51e2 100644 --- a/src/common/constants.js +++ b/src/common/constants.js @@ -1,2 +1,3 @@ export const EVENT_ID = "0"; -export const TOKEN_ID = "AWESOME_ORANGE_ACCESS_TOKEN"; \ No newline at end of file +export const SERVICE_TOKEN_ID = "AWESOME_ORANGE_ACCESS_TOKEN"; +export const ADMIN_TOKEN_ID = "AWESOME_ORANGE_ADMIN_ACCESS_TOKEN"; \ No newline at end of file diff --git a/src/common/dataFetch/tokenSaver.js b/src/common/dataFetch/tokenSaver.js index 67eea568..8bd9ae3d 100644 --- a/src/common/dataFetch/tokenSaver.js +++ b/src/common/dataFetch/tokenSaver.js @@ -1,31 +1,31 @@ -import { TOKEN_ID } from "@common/constants.js"; - class TokenSaver { initialized = false; token = null; - init() { + tokenId = null; + init(tokenId) { if (typeof window === "undefined") return; - this.token = localStorage.getItem(TOKEN_ID) ?? null; + this.tokenId = tokenId; + this.token = localStorage.getItem(this.tokenId) ?? null; this.initialized = true; } - get() { + get(tokenId = this.tokenId) { if (this.initialized) return this.token; - this.init(); + this.init(tokenId); return this.token; } set(token) { this.token = token; - if (typeof window !== "undefined") localStorage.setItem(TOKEN_ID, token); + if (typeof window !== "undefined") localStorage.setItem(this.tokenId, token); this.initialzed = true; } - has() { + has(tokenId = this.tokenId) { if (this.initialized) return this.token !== null; - this.init(); + this.init(tokenId); return this.token !== null; } remove() { this.token = null; - if (typeof window !== "undefined") localStorage.removeItem(TOKEN_ID); + if (typeof window !== "undefined") localStorage.removeItem(this.tokenId); this.initialzed = true; } } diff --git a/src/common/modal/modal.jsx b/src/common/modal/modal.jsx index 6cbd318b..d98f9b4e 100644 --- a/src/common/modal/modal.jsx +++ b/src/common/modal/modal.jsx @@ -1,6 +1,5 @@ import { createContext, useCallback, useEffect, useState, useRef } from "react"; import useModalStore, { closeModal } from "./store.js"; -import { delay } from "@common/utils.js"; export const ModalCloseContext = createContext(() => { console.log("모달이 닫힙니다."); @@ -10,12 +9,16 @@ function Modal({ layer }) { const timeoutRef = useRef(null); const child = useModalStore(layer); const [opacity, setOpacity] = useState(0); - const close = useCallback(async () => { - setOpacity(0); - if (timeoutRef.current === null) { - await delay(150); - closeModal(layer); - } + const close = useCallback(() => { + return new Promise( (resolve)=>{ + setOpacity(0); + + if (timeoutRef.current !== null) return resolve(); + timeoutRef.current = setTimeout( ()=>{ + closeModal(layer); + resolve(); + }, 150 ); + } ); }, [layer]); useEffect(() => { diff --git a/src/mainPage/shared/auth/store.js b/src/mainPage/shared/auth/store.js index 133d016a..c57bb7b7 100644 --- a/src/mainPage/shared/auth/store.js +++ b/src/mainPage/shared/auth/store.js @@ -1,5 +1,6 @@ import { create } from "zustand"; import tokenSaver from "@common/dataFetch/tokenSaver.js"; +import { SERVICE_TOKEN_ID } from "@common/constants.js"; const userStore = create(() => ({ isLogin: false, @@ -23,8 +24,8 @@ export function logout() { } export function initLoginState() { - tokenSaver.init(); - const token = tokenSaver.get(); + tokenSaver.init(SERVICE_TOKEN_ID); + const token = tokenSaver.get(SERVICE_TOKEN_ID); const userName = parseTokenToUserName(token); if (token === null) userStore.setState(() => ({ isLogin: false, userName: "" })); From 38093c3741981a96305113003f3a87fa8d1d77a4 Mon Sep 17 00:00:00 2001 From: lybell-art Date: Mon, 12 Aug 2024 18:38:27 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[chore]=20=EB=A6=B0=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EB=B0=8F=20=ED=94=84=EB=A6=AC=ED=8B=B0=EC=96=B4=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.js | 18 ++++++------- src/adminPage/App.jsx | 8 ++++-- src/adminPage/main-client.jsx | 25 +++++++++++-------- src/common/constants.js | 2 +- src/common/dataFetch/tokenSaver.js | 3 ++- src/common/modal/modal.jsx | 10 ++++---- src/common/utils.js | 2 +- .../interactions/modal/InteractionAnswer.jsx | 2 +- .../interactions/modal/InteractionModal.jsx | 2 +- src/mainPage/features/introSection/index.jsx | 5 ++-- .../simpleInformation/contentSection.jsx | 5 +++- .../shared/realtimeEvent/getEventDateState.js | 2 +- src/mainPage/shared/scroll/constants.js | 2 +- 13 files changed, 48 insertions(+), 38 deletions(-) diff --git a/build.js b/build.js index 3e9142c6..57d04ea4 100644 --- a/build.js +++ b/build.js @@ -1,6 +1,7 @@ import { build } from "vite"; -import { parse, resolve, dirname } from "node:path"; +import { resolve, dirname } from "node:path"; import { fileURLToPath } from "node:url"; +import process from "node:process"; import { readFile, writeFile, rm, mkdir } from "node:fs/promises"; import config from "./vite.config.js"; @@ -30,14 +31,12 @@ const buildConfig = { }, } -async function processBuild(mode) -{ +async function processBuild(mode) { await Promise.all([buildClient(mode), buildSSG(mode)]); await injectSSGToHtml(mode); } -async function buildClient(mode) -{ +async function buildClient(mode) { await build({ ...config, build: { @@ -54,8 +53,7 @@ async function buildClient(mode) await rm(toAbsolute(`dist/${mode}/mockServiceWorker.js`)); } -function buildSSG(mode) -{ +function buildSSG(mode) { return build({ ...config, build: { @@ -72,8 +70,7 @@ function buildSSG(mode) }); } -async function injectSSGToHtml(mode) -{ +async function injectSSGToHtml(mode) { console.log("--ssg result--"); const {default: render} = await import(`./dist-ssg/${mode}/entry.js`); const template = await readFile(`dist/${mode}/${buildConfig[mode].clientEntry}`, "utf-8"); @@ -89,8 +86,7 @@ async function injectSSGToHtml(mode) await mkdir(dir, { recursive: true }); await writeFile(absolutePath, html); console.log(`pre-rendered : ${path}`); - } - catch { + } catch { console.log(`pre-rendered failed : ${path}`); } } ); diff --git a/src/adminPage/App.jsx b/src/adminPage/App.jsx index 45f81d71..68a41729 100644 --- a/src/adminPage/App.jsx +++ b/src/adminPage/App.jsx @@ -4,7 +4,11 @@ function App() { return ( <> - event 생성 화면} /> + event 생성 화면} + /> event 보는 화면} /> 이벤트 목록 화면} /> 기대평 화면} /> @@ -16,4 +20,4 @@ function App() { ); } -export default App; \ No newline at end of file +export default App; diff --git a/src/adminPage/main-client.jsx b/src/adminPage/main-client.jsx index 54ade981..b7b99f54 100644 --- a/src/adminPage/main-client.jsx +++ b/src/adminPage/main-client.jsx @@ -16,17 +16,22 @@ if (import.meta.env.DEV) { }; enableMocking().then(() => { const root = createRoot($root); - root.render( - - - - ); + root.render( + + + + + , + ); }); } else { // 배포 시 - hydrateRoot($root, - - - - ); + hydrateRoot( + $root, + + + + + , + ); } diff --git a/src/common/constants.js b/src/common/constants.js index 609e51e2..15bb2edb 100644 --- a/src/common/constants.js +++ b/src/common/constants.js @@ -1,3 +1,3 @@ export const EVENT_ID = "0"; export const SERVICE_TOKEN_ID = "AWESOME_ORANGE_ACCESS_TOKEN"; -export const ADMIN_TOKEN_ID = "AWESOME_ORANGE_ADMIN_ACCESS_TOKEN"; \ No newline at end of file +export const ADMIN_TOKEN_ID = "AWESOME_ORANGE_ADMIN_ACCESS_TOKEN"; diff --git a/src/common/dataFetch/tokenSaver.js b/src/common/dataFetch/tokenSaver.js index 8bd9ae3d..ae1404bf 100644 --- a/src/common/dataFetch/tokenSaver.js +++ b/src/common/dataFetch/tokenSaver.js @@ -15,7 +15,8 @@ class TokenSaver { } set(token) { this.token = token; - if (typeof window !== "undefined") localStorage.setItem(this.tokenId, token); + if (typeof window !== "undefined") + localStorage.setItem(this.tokenId, token); this.initialzed = true; } has(tokenId = this.tokenId) { diff --git a/src/common/modal/modal.jsx b/src/common/modal/modal.jsx index d98f9b4e..138a8d92 100644 --- a/src/common/modal/modal.jsx +++ b/src/common/modal/modal.jsx @@ -10,15 +10,15 @@ function Modal({ layer }) { const child = useModalStore(layer); const [opacity, setOpacity] = useState(0); const close = useCallback(() => { - return new Promise( (resolve)=>{ + return new Promise((resolve) => { setOpacity(0); - + if (timeoutRef.current !== null) return resolve(); - timeoutRef.current = setTimeout( ()=>{ + timeoutRef.current = setTimeout(() => { closeModal(layer); resolve(); - }, 150 ); - } ); + }, 150); + }); }, [layer]); useEffect(() => { diff --git a/src/common/utils.js b/src/common/utils.js index 7b80d1a6..23a251cb 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -28,5 +28,5 @@ export function convertSecondsToString(time) { } export function delay(ms) { - return new Promise( resolve=>setTimeout(resolve, ms) ); + return new Promise((resolve) => setTimeout(resolve, ms)); } diff --git a/src/mainPage/features/interactions/modal/InteractionAnswer.jsx b/src/mainPage/features/interactions/modal/InteractionAnswer.jsx index 60b15e59..fb05ec65 100644 --- a/src/mainPage/features/interactions/modal/InteractionAnswer.jsx +++ b/src/mainPage/features/interactions/modal/InteractionAnswer.jsx @@ -6,7 +6,7 @@ import AuthModal from "@main/auth/AuthModal.jsx"; import openModal from "@common/modal/openModal.js"; import Button from "@common/components/Button.jsx"; -import style from "./InteractionAnswer.module.css" +import style from "./InteractionAnswer.module.css"; // import useEventStore from "@main/realtimeEvent/store"; export default function InteractionAnswer({ diff --git a/src/mainPage/features/interactions/modal/InteractionModal.jsx b/src/mainPage/features/interactions/modal/InteractionModal.jsx index 9730b6b0..61debf67 100644 --- a/src/mainPage/features/interactions/modal/InteractionModal.jsx +++ b/src/mainPage/features/interactions/modal/InteractionModal.jsx @@ -4,7 +4,7 @@ import InteractionAnswer from "./InteractionAnswer.jsx"; import { ModalCloseContext } from "@common/modal/modal.jsx"; import Suspense from "@common/components/Suspense.jsx"; import Button from "@common/components/Button.jsx"; -import ResetButton from "@main/components/ResetButton.jsx" +import ResetButton from "@main/components/ResetButton.jsx"; import userStore from "@main/auth/store.js"; diff --git a/src/mainPage/features/introSection/index.jsx b/src/mainPage/features/introSection/index.jsx index 19ad230e..f7bcb2aa 100644 --- a/src/mainPage/features/introSection/index.jsx +++ b/src/mainPage/features/introSection/index.jsx @@ -7,7 +7,6 @@ import style from "./index.module.css"; import SpinningCarVideo from "./car-spin.webm"; import Pointer from "./pointer.svg"; - function IntroSection() { const videoRef = useRef(null); const introRef = useRef(null); @@ -106,7 +105,9 @@ function IntroSection() { 더뉴 아이오닉5 신차 출시 이벤트 - 09/09 (mon) - 09/13 (fri) + + 09/09 (mon) - 09/13 (fri) +
diff --git a/src/mainPage/features/simpleInformation/contentSection.jsx b/src/mainPage/features/simpleInformation/contentSection.jsx index 575821e2..c197dc72 100644 --- a/src/mainPage/features/simpleInformation/contentSection.jsx +++ b/src/mainPage/features/simpleInformation/contentSection.jsx @@ -58,7 +58,10 @@ export default function ContentSection({ content }) {
-

+

{makeHighlight(content.desc, style.highlightAnim)}

diff --git a/src/mainPage/shared/realtimeEvent/getEventDateState.js b/src/mainPage/shared/realtimeEvent/getEventDateState.js index 7ad0d42c..c0b1b9ef 100644 --- a/src/mainPage/shared/realtimeEvent/getEventDateState.js +++ b/src/mainPage/shared/realtimeEvent/getEventDateState.js @@ -6,4 +6,4 @@ export default function getEventDateState(currrentTimeDate, eventTimeDate) { if (currentTime < eventTime) return "default"; if (currentTime < eventEndTime) return "active"; return "ended"; -} \ No newline at end of file +} diff --git a/src/mainPage/shared/scroll/constants.js b/src/mainPage/shared/scroll/constants.js index 8c87183b..c8b8bc20 100644 --- a/src/mainPage/shared/scroll/constants.js +++ b/src/mainPage/shared/scroll/constants.js @@ -3,4 +3,4 @@ export const OTHER_SECTION = 0; export const INTERACTION_SECTION = 1; export const DETAIL_SECTION = 2; export const COMMENT_SECTION = 3; -export const FCFS_SECTION = 4; \ No newline at end of file +export const FCFS_SECTION = 4;