diff --git a/.storybook/main.ts b/.storybook/main.ts
index e409de02..fcfff918 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -11,6 +11,7 @@ const config: StorybookConfig = {
'@storybook/addon-essentials',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
+ '@storybook/addon-viewport',
],
framework: {
name: '@storybook/react-webpack5',
diff --git a/.storybook/preview.ts b/.storybook/preview.ts
index 838f72d8..1fdf2555 100644
--- a/.storybook/preview.ts
+++ b/.storybook/preview.ts
@@ -1,6 +1,19 @@
import type { Preview } from '@storybook/react';
+import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import '../src/styles/reset.css';
+const customViewports = {
+ mobile: {
+ name: 'mobile',
+ styles: {
+ width: '430px',
+ height: '400px',
+ },
+ type: 'mobile',
+ },
+};
+
+
const preview: Preview = {
parameters: {
controls: {
@@ -9,7 +22,13 @@ const preview: Preview = {
date: /Date$/i,
},
},
+ viewport: {
+ viewports: {
+ ...INITIAL_VIEWPORTS,
+ ...customViewports
+ },
+ },
},
};
-export default preview;
+export default preview;
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index b3ffdcfb..e37a8bdf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,6 +38,7 @@
"@storybook/addon-interactions": "^8.1.9",
"@storybook/addon-links": "^8.1.9",
"@storybook/addon-onboarding": "^8.1.9",
+ "@storybook/addon-viewport": "^8.4.7",
"@storybook/addon-webpack5-compiler-swc": "^1.0.3",
"@storybook/blocks": "^8.1.9",
"@storybook/react": "^8.1.9",
@@ -109,18 +110,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/@aw-web-design/x-default-browser": {
- "version": "1.4.126",
- "resolved": "https://registry.npmjs.org/@aw-web-design/x-default-browser/-/x-default-browser-1.4.126.tgz",
- "integrity": "sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==",
- "dev": true,
- "dependencies": {
- "default-browser-id": "3.0.0"
- },
- "bin": {
- "x-default-browser": "bin/x-default-browser.js"
- }
- },
"node_modules/@babel/code-frame": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
@@ -670,21 +659,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-syntax-flow": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz",
- "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-syntax-import-assertions": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz",
@@ -1132,22 +1106,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/plugin-transform-flow-strip-types": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.7.tgz",
- "integrity": "sha512-cjRKJ7FobOH2eakx7Ja+KpJRj8+y+/SiB3ooYm/n2UJfxu0oEaOoxOinitkJcPqv9KxS0kxTGPUaR7L2XcXDXA==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-flow": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/plugin-transform-for-of": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
@@ -1867,23 +1825,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/preset-flow": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.24.7.tgz",
- "integrity": "sha512-NL3Lo0NorCU607zU3NwRyJbpaB6E3t0xtd3LfAQKDfkeX4/ggcDXvkmkW42QWT5owUeW/jAe4hn+2qvkV1IbfQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-validator-option": "^7.24.7",
- "@babel/plugin-transform-flow-strip-types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@babel/preset-modules": {
"version": "0.1.6-no-external-plugins",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
@@ -1937,97 +1878,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@babel/register": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.24.6.tgz",
- "integrity": "sha512-WSuFCc2wCqMeXkz/i3yfAAsxwWflEgbVkZzivgAmXl/MxrXeoYFZOOPllbC8R8WTF7u61wSRQtDVZ1879cdu6w==",
- "dev": true,
- "dependencies": {
- "clone-deep": "^4.0.1",
- "find-cache-dir": "^2.0.0",
- "make-dir": "^2.1.0",
- "pirates": "^4.0.6",
- "source-map-support": "^0.5.16"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/register/node_modules/find-cache-dir": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
- "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
- "dev": true,
- "dependencies": {
- "commondir": "^1.0.1",
- "make-dir": "^2.0.0",
- "pkg-dir": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@babel/register/node_modules/find-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
- "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
- "dev": true,
- "dependencies": {
- "locate-path": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@babel/register/node_modules/locate-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
- "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
- "dev": true,
- "dependencies": {
- "p-locate": "^3.0.0",
- "path-exists": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@babel/register/node_modules/p-locate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
- "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@babel/register/node_modules/path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/register/node_modules/pkg-dir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
- "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
- "dev": true,
- "dependencies": {
- "find-up": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/@babel/regjsgen": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
@@ -2141,16 +1991,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
- "node_modules/@colors/colors": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
- "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
- "dev": true,
- "optional": true,
- "engines": {
- "node": ">=0.1.90"
- }
- },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -2756,12 +2596,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
- "node_modules/@fal-works/esbuild-plugin-global-externals": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz",
- "integrity": "sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==",
- "dev": true
- },
"node_modules/@floating-ui/core": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz",
@@ -3343,17 +3177,6 @@
}
}
},
- "node_modules/@ndelangen/get-tarball": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz",
- "integrity": "sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA==",
- "dev": true,
- "dependencies": {
- "gunzip-maybe": "^1.4.2",
- "pump": "^3.0.0",
- "tar-fs": "^2.1.1"
- }
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3802,18 +3625,6 @@
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"dev": true
},
- "node_modules/@sindresorhus/merge-streams": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
- "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@storybook/addon-actions": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.1.9.tgz",
@@ -3921,6 +3732,19 @@
"url": "https://opencollective.com/storybook"
}
},
+ "node_modules/@storybook/addon-essentials/node_modules/@storybook/addon-viewport": {
+ "version": "8.1.9",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.1.9.tgz",
+ "integrity": "sha512-ZCoqzNWp2w9TLJL8RC0fjv1RQcuGhwI64jjlGvszZm7TxP82C1SS71X/jbx5LWc2Dyl5xMt1/yOGFXvkAB2SUg==",
+ "dev": true,
+ "dependencies": {
+ "memoizerific": "^1.11.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ }
+ },
"node_modules/@storybook/addon-highlight": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.1.9.tgz",
@@ -4027,9 +3851,9 @@
}
},
"node_modules/@storybook/addon-viewport": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.1.9.tgz",
- "integrity": "sha512-ZCoqzNWp2w9TLJL8RC0fjv1RQcuGhwI64jjlGvszZm7TxP82C1SS71X/jbx5LWc2Dyl5xMt1/yOGFXvkAB2SUg==",
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.4.7.tgz",
+ "integrity": "sha512-hvczh/jjuXXcOogih09a663sRDDSATXwbE866al1DXgbDFraYD/LxX/QDb38W9hdjU9+Qhx8VFIcNWoMQns5HQ==",
"dev": true,
"dependencies": {
"memoizerific": "^1.11.3"
@@ -4037,6 +3861,9 @@
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.4.7"
}
},
"node_modules/@storybook/addon-webpack5-compiler-swc": {
@@ -4100,32 +3927,6 @@
}
}
},
- "node_modules/@storybook/builder-manager": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-8.1.9.tgz",
- "integrity": "sha512-CmDXVrx3moUde6VWmdb49eCYHNu4e2wxeANKSsW1yEC0OLysQ9N6W9B5CuVWeoV3axVX/tKDqC83YY/008/4Qg==",
- "dev": true,
- "dependencies": {
- "@fal-works/esbuild-plugin-global-externals": "^2.1.2",
- "@storybook/core-common": "8.1.9",
- "@storybook/manager": "8.1.9",
- "@storybook/node-logger": "8.1.9",
- "@types/ejs": "^3.1.1",
- "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10",
- "browser-assert": "^1.2.1",
- "ejs": "^3.1.10",
- "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0",
- "esbuild-plugin-alias": "^0.2.1",
- "express": "^4.17.3",
- "fs-extra": "^11.1.0",
- "process": "^0.11.10",
- "util": "^0.12.4"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
"node_modules/@storybook/builder-webpack5": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.1.9.tgz",
@@ -4287,399 +4088,126 @@
"url": "https://opencollective.com/storybook"
}
},
- "node_modules/@storybook/cli": {
+ "node_modules/@storybook/client-logger": {
+ "version": "8.1.9",
+ "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.1.9.tgz",
+ "integrity": "sha512-sHX0UhAquhVCtbRtDNN5Ura8hUxRjZWKgQKt8NWQIt9hOSSurGJE3+93OzNAYDp54kh77QKY3qdZCgAJZuWZPw==",
+ "dev": true,
+ "dependencies": {
+ "@storybook/global": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ }
+ },
+ "node_modules/@storybook/components": {
"version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-8.1.9.tgz",
- "integrity": "sha512-+4DQJf5yrdmKrAs8sx0WvKu/ja49oOLQU2MxRPKhXW3bxDFjkTYvWuCKwSbMwUa7Npt96CK3bwAPP53jz/+mXA==",
+ "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.1.9.tgz",
+ "integrity": "sha512-YGDYTJfobtNDBJrvXNgmExX3LGnb9jGPGdroS4uHewLFaqEI3Fqu3RiFLaJf40TlZ27uWLprysdLRol8j+wYEw==",
+ "dev": true,
+ "dependencies": {
+ "@radix-ui/react-dialog": "^1.0.5",
+ "@radix-ui/react-slot": "^1.0.2",
+ "@storybook/client-logger": "8.1.9",
+ "@storybook/csf": "^0.1.7",
+ "@storybook/global": "^5.0.0",
+ "@storybook/icons": "^1.2.5",
+ "@storybook/theming": "8.1.9",
+ "@storybook/types": "8.1.9",
+ "memoizerific": "^1.11.3",
+ "util-deprecate": "^1.0.2"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta"
+ }
+ },
+ "node_modules/@storybook/core": {
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.4.7.tgz",
+ "integrity": "sha512-7Z8Z0A+1YnhrrSXoKKwFFI4gnsLbWzr8fnDCU6+6HlDukFYh8GHRcZ9zKfqmy6U3hw2h8H5DrHsxWfyaYUUOoA==",
+ "dev": true,
+ "dependencies": {
+ "@storybook/csf": "^0.1.11",
+ "better-opn": "^3.0.2",
+ "browser-assert": "^1.2.1",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0",
+ "esbuild-register": "^3.5.0",
+ "jsdoc-type-pratt-parser": "^4.0.0",
+ "process": "^0.11.10",
+ "recast": "^0.23.5",
+ "semver": "^7.6.2",
+ "util": "^0.12.5",
+ "ws": "^8.2.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@storybook/core-common": {
+ "version": "8.1.9",
+ "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.1.9.tgz",
+ "integrity": "sha512-+KReoo41FUknTxk3fbnoul995SnZdKAVSK6MuqKOQnC9PH6bh864k6i1LShVZx/wk3n25h9xorD3UgyRI6sZ0w==",
"dev": true,
"dependencies": {
- "@babel/core": "^7.24.4",
- "@babel/types": "^7.24.0",
- "@ndelangen/get-tarball": "^3.0.7",
- "@storybook/codemod": "8.1.9",
- "@storybook/core-common": "8.1.9",
"@storybook/core-events": "8.1.9",
- "@storybook/core-server": "8.1.9",
"@storybook/csf-tools": "8.1.9",
"@storybook/node-logger": "8.1.9",
- "@storybook/telemetry": "8.1.9",
"@storybook/types": "8.1.9",
- "@types/semver": "^7.3.4",
"@yarnpkg/fslib": "2.10.3",
"@yarnpkg/libzip": "2.3.0",
"chalk": "^4.1.0",
- "commander": "^6.2.1",
"cross-spawn": "^7.0.3",
- "detect-indent": "^6.1.0",
- "envinfo": "^7.7.3",
+ "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0",
+ "esbuild-register": "^3.5.0",
"execa": "^5.0.0",
+ "file-system-cache": "2.3.0",
+ "find-cache-dir": "^3.0.0",
"find-up": "^5.0.0",
"fs-extra": "^11.1.0",
- "get-npm-tarball-url": "^2.0.3",
- "giget": "^1.0.0",
- "globby": "^14.0.1",
- "jscodeshift": "^0.15.1",
- "leven": "^3.1.0",
- "ora": "^5.4.1",
- "prettier": "^3.1.1",
- "prompts": "^2.4.0",
- "read-pkg-up": "^7.0.1",
+ "glob": "^10.0.0",
+ "handlebars": "^4.7.7",
+ "lazy-universal-dotenv": "^4.0.0",
+ "node-fetch": "^2.0.0",
+ "picomatch": "^2.3.0",
+ "pkg-dir": "^5.0.0",
+ "prettier-fallback": "npm:prettier@^3",
+ "pretty-hrtime": "^1.0.3",
+ "resolve-from": "^5.0.0",
"semver": "^7.3.7",
- "strip-json-comments": "^3.0.1",
"tempy": "^3.1.0",
"tiny-invariant": "^1.3.1",
- "ts-dedent": "^2.0.0"
- },
- "bin": {
- "getstorybook": "bin/index.js",
- "sb": "bin/index.js"
+ "ts-dedent": "^2.0.0",
+ "util": "^0.12.4"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
}
},
- "node_modules/@storybook/cli/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@storybook/cli/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@storybook/cli/node_modules/commander": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
- "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/@storybook/cli/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/globby": {
- "version": "14.0.2",
- "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
- "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
- "dev": true,
- "dependencies": {
- "@sindresorhus/merge-streams": "^2.1.0",
- "fast-glob": "^3.3.2",
- "ignore": "^5.2.4",
- "path-type": "^5.0.0",
- "slash": "^5.1.0",
- "unicorn-magic": "^0.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/path-type": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
- "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/semver": {
- "version": "7.6.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
- "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@storybook/cli/node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/cli/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@storybook/cli/node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/client-logger": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-8.1.9.tgz",
- "integrity": "sha512-sHX0UhAquhVCtbRtDNN5Ura8hUxRjZWKgQKt8NWQIt9hOSSurGJE3+93OzNAYDp54kh77QKY3qdZCgAJZuWZPw==",
- "dev": true,
- "dependencies": {
- "@storybook/global": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
- "node_modules/@storybook/codemod": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-8.1.9.tgz",
- "integrity": "sha512-thTdwiAO/eUUyiCzgkyGjA4fE3BAdXqf3WdTRjH4Vqk4yby9EalwcBitkj/M6bCDGjdoxU2q2ByUDD9opwyMiw==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.24.4",
- "@babel/preset-env": "^7.24.4",
- "@babel/types": "^7.24.0",
- "@storybook/csf": "^0.1.7",
- "@storybook/csf-tools": "8.1.9",
- "@storybook/node-logger": "8.1.9",
- "@storybook/types": "8.1.9",
- "@types/cross-spawn": "^6.0.2",
- "cross-spawn": "^7.0.3",
- "globby": "^14.0.1",
- "jscodeshift": "^0.15.1",
- "lodash": "^4.17.21",
- "prettier": "^3.1.1",
- "recast": "^0.23.5",
- "tiny-invariant": "^1.3.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
- "node_modules/@storybook/codemod/node_modules/globby": {
- "version": "14.0.2",
- "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
- "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
- "dev": true,
- "dependencies": {
- "@sindresorhus/merge-streams": "^2.1.0",
- "fast-glob": "^3.3.2",
- "ignore": "^5.2.4",
- "path-type": "^5.0.0",
- "slash": "^5.1.0",
- "unicorn-magic": "^0.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/codemod/node_modules/path-type": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
- "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/codemod/node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/components": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.1.9.tgz",
- "integrity": "sha512-YGDYTJfobtNDBJrvXNgmExX3LGnb9jGPGdroS4uHewLFaqEI3Fqu3RiFLaJf40TlZ27uWLprysdLRol8j+wYEw==",
- "dev": true,
- "dependencies": {
- "@radix-ui/react-dialog": "^1.0.5",
- "@radix-ui/react-slot": "^1.0.2",
- "@storybook/client-logger": "8.1.9",
- "@storybook/csf": "^0.1.7",
- "@storybook/global": "^5.0.0",
- "@storybook/icons": "^1.2.5",
- "@storybook/theming": "8.1.9",
- "@storybook/types": "8.1.9",
- "memoizerific": "^1.11.3",
- "util-deprecate": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- },
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta",
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta"
- }
- },
- "node_modules/@storybook/core-common": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-8.1.9.tgz",
- "integrity": "sha512-+KReoo41FUknTxk3fbnoul995SnZdKAVSK6MuqKOQnC9PH6bh864k6i1LShVZx/wk3n25h9xorD3UgyRI6sZ0w==",
- "dev": true,
- "dependencies": {
- "@storybook/core-events": "8.1.9",
- "@storybook/csf-tools": "8.1.9",
- "@storybook/node-logger": "8.1.9",
- "@storybook/types": "8.1.9",
- "@yarnpkg/fslib": "2.10.3",
- "@yarnpkg/libzip": "2.3.0",
- "chalk": "^4.1.0",
- "cross-spawn": "^7.0.3",
- "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0",
- "esbuild-register": "^3.5.0",
- "execa": "^5.0.0",
- "file-system-cache": "2.3.0",
- "find-cache-dir": "^3.0.0",
- "find-up": "^5.0.0",
- "fs-extra": "^11.1.0",
- "glob": "^10.0.0",
- "handlebars": "^4.7.7",
- "lazy-universal-dotenv": "^4.0.0",
- "node-fetch": "^2.0.0",
- "picomatch": "^2.3.0",
- "pkg-dir": "^5.0.0",
- "prettier-fallback": "npm:prettier@^3",
- "pretty-hrtime": "^1.0.3",
- "resolve-from": "^5.0.0",
- "semver": "^7.3.7",
- "tempy": "^3.1.0",
- "tiny-invariant": "^1.3.1",
- "ts-dedent": "^2.0.0",
- "util": "^0.12.4"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- },
- "peerDependencies": {
- "prettier": "^2 || ^3"
- },
- "peerDependenciesMeta": {
- "prettier": {
- "optional": true
- }
- }
- },
- "node_modules/@storybook/core-common/node_modules/ansi-styles": {
+ "node_modules/@storybook/core-common/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
@@ -4991,127 +4519,24 @@
"url": "https://opencollective.com/storybook"
}
},
- "node_modules/@storybook/core-server": {
+ "node_modules/@storybook/core-webpack": {
"version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-8.1.9.tgz",
- "integrity": "sha512-bn3M264vr3GY9kgAdRRIUdVV4PcUqtYvttQ/h6XDVJWC1UYUQW49zQNxQLQUXSQo4KLISnvTKHmP5qgbY6BASQ==",
+ "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.1.9.tgz",
+ "integrity": "sha512-BuTuotH62S7izi3x04WXtPqBFU98qBB87z+GiEEerCMk4l2+rPKyKdkZHULhhH+0vzstLE39hq2YrWdqjdfwqA==",
"dev": true,
"dependencies": {
- "@aw-web-design/x-default-browser": "1.4.126",
- "@babel/core": "^7.24.4",
- "@babel/parser": "^7.24.4",
- "@discoveryjs/json-ext": "^0.5.3",
- "@storybook/builder-manager": "8.1.9",
- "@storybook/channels": "8.1.9",
"@storybook/core-common": "8.1.9",
- "@storybook/core-events": "8.1.9",
- "@storybook/csf": "^0.1.7",
- "@storybook/csf-tools": "8.1.9",
- "@storybook/docs-mdx": "3.1.0-next.0",
- "@storybook/global": "^5.0.0",
- "@storybook/manager": "8.1.9",
- "@storybook/manager-api": "8.1.9",
"@storybook/node-logger": "8.1.9",
- "@storybook/preview-api": "8.1.9",
- "@storybook/telemetry": "8.1.9",
"@storybook/types": "8.1.9",
- "@types/detect-port": "^1.3.0",
- "@types/diff": "^5.0.9",
"@types/node": "^18.0.0",
- "@types/pretty-hrtime": "^1.0.0",
- "@types/semver": "^7.3.4",
- "better-opn": "^3.0.2",
- "chalk": "^4.1.0",
- "cli-table3": "^0.6.1",
- "compression": "^1.7.4",
- "detect-port": "^1.3.0",
- "diff": "^5.2.0",
- "express": "^4.17.3",
- "fs-extra": "^11.1.0",
- "globby": "^14.0.1",
- "lodash": "^4.17.21",
- "open": "^8.4.0",
- "pretty-hrtime": "^1.0.3",
- "prompts": "^2.4.0",
- "read-pkg-up": "^7.0.1",
- "semver": "^7.3.7",
- "telejson": "^7.2.0",
- "tiny-invariant": "^1.3.1",
- "ts-dedent": "^2.0.0",
- "util": "^0.12.4",
- "util-deprecate": "^1.0.2",
- "watchpack": "^2.2.0",
- "ws": "^8.2.3"
+ "ts-dedent": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
}
},
- "node_modules/@storybook/core-server/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@storybook/core-server/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@storybook/core-server/node_modules/globby": {
- "version": "14.0.2",
- "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
- "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
- "dev": true,
- "dependencies": {
- "@sindresorhus/merge-streams": "^2.1.0",
- "fast-glob": "^3.3.2",
- "ignore": "^5.2.4",
- "path-type": "^5.0.0",
- "slash": "^5.1.0",
- "unicorn-magic": "^0.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/core-server/node_modules/path-type": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
- "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/core-server/node_modules/semver": {
+ "node_modules/@storybook/core/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
@@ -5123,47 +4548,6 @@
"node": ">=10"
}
},
- "node_modules/@storybook/core-server/node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@storybook/core-server/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@storybook/core-webpack": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.1.9.tgz",
- "integrity": "sha512-BuTuotH62S7izi3x04WXtPqBFU98qBB87z+GiEEerCMk4l2+rPKyKdkZHULhhH+0vzstLE39hq2YrWdqjdfwqA==",
- "dev": true,
- "dependencies": {
- "@storybook/core-common": "8.1.9",
- "@storybook/node-logger": "8.1.9",
- "@storybook/types": "8.1.9",
- "@types/node": "^18.0.0",
- "ts-dedent": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
"node_modules/@storybook/csf": {
"version": "0.1.11",
"resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.11.tgz",
@@ -5220,12 +4604,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@storybook/docs-mdx": {
- "version": "3.1.0-next.0",
- "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-3.1.0-next.0.tgz",
- "integrity": "sha512-t4syFIeSyufieNovZbLruPt2DmRKpbwL4fERCZ1MifWDRIORCKLc4NCEHy+IqvIqd71/SJV2k4B51nF7vlJfmQ==",
- "dev": true
- },
"node_modules/@storybook/docs-tools": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-8.1.9.tgz",
@@ -5284,16 +4662,6 @@
"url": "https://opencollective.com/storybook"
}
},
- "node_modules/@storybook/manager": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-8.1.9.tgz",
- "integrity": "sha512-sp1N7ZgOtGK5uhCgwuPQlJ4JYKr3TyNeahotwAf2FUb5n70YyXDzqoqO8q8H0y9NarX+EcP1gJ4GmpT9+qTxsQ==",
- "dev": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
"node_modules/@storybook/manager-api": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.1.9.tgz",
@@ -5703,69 +5071,6 @@
"url": "https://opencollective.com/storybook"
}
},
- "node_modules/@storybook/telemetry": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-8.1.9.tgz",
- "integrity": "sha512-ayNt4g6MKIQCj5fPmB2WhYbEEH+AMVswUOedFp2DtPojeDnVJMp38lSFykTbjaq+/HrDpnoZn6fG4pd+05N+dg==",
- "dev": true,
- "dependencies": {
- "@storybook/client-logger": "8.1.9",
- "@storybook/core-common": "8.1.9",
- "@storybook/csf-tools": "8.1.9",
- "chalk": "^4.1.0",
- "detect-package-manager": "^2.0.1",
- "fetch-retry": "^5.0.2",
- "fs-extra": "^11.1.0",
- "read-pkg-up": "^7.0.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/storybook"
- }
- },
- "node_modules/@storybook/telemetry/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@storybook/telemetry/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@storybook/telemetry/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@storybook/test": {
"version": "8.1.9",
"resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.1.9.tgz",
@@ -6677,15 +5982,6 @@
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==",
"dev": true
},
- "node_modules/@types/cross-spawn": {
- "version": "6.0.6",
- "resolved": "https://registry.npmjs.org/@types/cross-spawn/-/cross-spawn-6.0.6.tgz",
- "integrity": "sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==",
- "dev": true,
- "dependencies": {
- "@types/node": "*"
- }
- },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@@ -6695,30 +5991,12 @@
"@types/ms": "*"
}
},
- "node_modules/@types/detect-port": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.5.tgz",
- "integrity": "sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA==",
- "dev": true
- },
- "node_modules/@types/diff": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@types/diff/-/diff-5.2.1.tgz",
- "integrity": "sha512-uxpcuwWJGhe2AR1g8hD9F5OYGCqjqWnBUQFD8gMZsDbv8oPHzxJF6iMO6n8Tk0AdzlxoaaoQhOYlIg/PukVU8g==",
- "dev": true
- },
"node_modules/@types/doctrine": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.3.tgz",
"integrity": "sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA==",
"dev": true
},
- "node_modules/@types/ejs": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz",
- "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==",
- "dev": true
- },
"node_modules/@types/emscripten": {
"version": "1.39.13",
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz",
@@ -6876,23 +6154,11 @@
"@types/node": "*"
}
},
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
- "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
- "dev": true
- },
"node_modules/@types/parse-json": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
},
- "node_modules/@types/pretty-hrtime": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
- "integrity": "sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA==",
- "dev": true
- },
"node_modules/@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
@@ -7572,22 +6838,7 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true
- },
- "node_modules/@yarnpkg/esbuild-plugin-pnp": {
- "version": "3.0.0-rc.15",
- "resolved": "https://registry.npmjs.org/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz",
- "integrity": "sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==",
- "dev": true,
- "dependencies": {
- "tslib": "^2.4.0"
- },
- "engines": {
- "node": ">=14.15.0"
- },
- "peerDependencies": {
- "esbuild": ">=0.10.0"
- }
+ "dev": true
},
"node_modules/@yarnpkg/fslib": {
"version": "2.10.3",
@@ -7677,15 +6928,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/address": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz",
- "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==",
- "dev": true,
- "engines": {
- "node": ">= 10.0.0"
- }
- },
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -8044,12 +7286,6 @@
"integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
"dev": true
},
- "node_modules/async": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
- "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
- "dev": true
- },
"node_modules/asynciterator.prototype": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz",
@@ -8112,15 +7348,6 @@
"dequal": "^2.0.3"
}
},
- "node_modules/babel-core": {
- "version": "7.0.0-bridge.0",
- "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
- "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
- "dev": true,
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/babel-loader": {
"version": "9.1.3",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz",
@@ -8288,15 +7515,6 @@
"node": ">=12.0.0"
}
},
- "node_modules/big-integer": {
- "version": "1.6.52",
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
- "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
- "dev": true,
- "engines": {
- "node": ">=0.6"
- }
- },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -8390,18 +7608,6 @@
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
"dev": true
},
- "node_modules/bplist-parser": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
- "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
- "dev": true,
- "dependencies": {
- "big-integer": "^1.6.44"
- },
- "engines": {
- "node": ">= 5.10.0"
- }
- },
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -8430,15 +7636,6 @@
"integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==",
"dev": true
},
- "node_modules/browserify-zlib": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
- "integrity": "sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==",
- "dev": true,
- "dependencies": {
- "pako": "~0.2.0"
- }
- },
"node_modules/browserslist": {
"version": "4.24.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz",
@@ -8680,15 +7877,6 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/chownr": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
- "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/chromatic": {
"version": "11.5.4",
"resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.5.4.tgz",
@@ -8721,15 +7909,6 @@
"node": ">=6.0"
}
},
- "node_modules/citty": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
- "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==",
- "dev": true,
- "dependencies": {
- "consola": "^3.2.3"
- }
- },
"node_modules/cjs-module-lexer": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
@@ -8772,21 +7951,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/cli-table3": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz",
- "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0"
- },
- "engines": {
- "node": "10.* || >= 12.*"
- },
- "optionalDependencies": {
- "@colors/colors": "1.5.0"
- }
- },
"node_modules/cli-width": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
@@ -8998,15 +8162,6 @@
"node": ">=0.8"
}
},
- "node_modules/consola": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz",
- "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==",
- "dev": true,
- "engines": {
- "node": "^14.18.0 || >=16.10.0"
- }
- },
"node_modules/constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@@ -9372,22 +8527,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/default-browser-id": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz",
- "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==",
- "dev": true,
- "dependencies": {
- "bplist-parser": "^0.2.0",
- "untildify": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/default-gateway": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
@@ -9455,12 +8594,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/defu": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
- "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
- "dev": true
- },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -9497,15 +8630,6 @@
"npm": "1.2.8000 || >= 1.4.16"
}
},
- "node_modules/detect-indent": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
- "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
@@ -9518,44 +8642,6 @@
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
"dev": true
},
- "node_modules/detect-package-manager": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-package-manager/-/detect-package-manager-2.0.1.tgz",
- "integrity": "sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==",
- "dev": true,
- "dependencies": {
- "execa": "^5.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/detect-port": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz",
- "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==",
- "dev": true,
- "dependencies": {
- "address": "^1.0.1",
- "debug": "4"
- },
- "bin": {
- "detect": "bin/detect-port.js",
- "detect-port": "bin/detect-port.js"
- },
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
- "dev": true,
- "engines": {
- "node": ">=0.3.1"
- }
- },
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@@ -9720,39 +8806,6 @@
"node": ">=12"
}
},
- "node_modules/duplexify": {
- "version": "3.7.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
- "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
- "dev": true,
- "dependencies": {
- "end-of-stream": "^1.0.0",
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.0",
- "stream-shift": "^1.0.0"
- }
- },
- "node_modules/duplexify/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/duplexify/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -9765,21 +8818,6 @@
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"dev": true
},
- "node_modules/ejs": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
- "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
- "dev": true,
- "dependencies": {
- "jake": "^10.8.5"
- },
- "bin": {
- "ejs": "bin/cli.js"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/electron-to-chromium": {
"version": "1.5.65",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.65.tgz",
@@ -9810,15 +8848,6 @@
"node": ">= 0.8"
}
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dev": true,
- "dependencies": {
- "once": "^1.4.0"
- }
- },
"node_modules/endent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/endent/-/endent-2.1.0.tgz",
@@ -10081,12 +9110,6 @@
"@esbuild/win32-x64": "0.20.2"
}
},
- "node_modules/esbuild-plugin-alias": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz",
- "integrity": "sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==",
- "dev": true
- },
"node_modules/esbuild-register": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.5.0.tgz",
@@ -11185,12 +10208,6 @@
"node": ">=0.8.0"
}
},
- "node_modules/fetch-retry": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.6.tgz",
- "integrity": "sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==",
- "dev": true
- },
"node_modules/figures": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
@@ -11259,36 +10276,6 @@
"ramda": "0.29.0"
}
},
- "node_modules/filelist": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
- "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
- "dev": true,
- "dependencies": {
- "minimatch": "^5.0.1"
- }
- },
- "node_modules/filelist/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/filelist/node_modules/minimatch": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
- "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/filesize": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.2.tgz",
@@ -11491,15 +10478,6 @@
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
"dev": true
},
- "node_modules/flow-parser": {
- "version": "0.238.0",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.238.0.tgz",
- "integrity": "sha512-VE7XSv1epljsIN2YeBnxCmGJihpNIAnLLu/pPOdA+Gkso7qDltJwUi6vfHjgxdBbjSdAuPGnhuOHJUQG+yYwIg==",
- "dev": true,
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/follow-redirects": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
@@ -11684,12 +10662,6 @@
"node": ">= 0.6"
}
},
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true
- },
"node_modules/fs-extra": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
@@ -11704,36 +10676,6 @@
"node": ">=14.14"
}
},
- "node_modules/fs-minipass": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
- "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/fs-minipass/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fs-minipass/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/fs-monkey": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz",
@@ -11850,15 +10792,6 @@
"node": ">=6"
}
},
- "node_modules/get-npm-tarball-url": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz",
- "integrity": "sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA==",
- "dev": true,
- "engines": {
- "node": ">=12.17"
- }
- },
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -11899,25 +10832,6 @@
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
- "node_modules/giget": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.3.tgz",
- "integrity": "sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==",
- "dev": true,
- "dependencies": {
- "citty": "^0.1.6",
- "consola": "^3.2.3",
- "defu": "^6.1.4",
- "node-fetch-native": "^1.6.3",
- "nypm": "^0.3.8",
- "ohash": "^1.1.3",
- "pathe": "^1.1.2",
- "tar": "^6.2.0"
- },
- "bin": {
- "giget": "dist/cli.mjs"
- }
- },
"node_modules/github-slugger": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
@@ -12038,23 +10952,6 @@
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
- "node_modules/gunzip-maybe": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz",
- "integrity": "sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==",
- "dev": true,
- "dependencies": {
- "browserify-zlib": "^0.1.4",
- "is-deflate": "^1.0.0",
- "is-gzip": "^1.0.0",
- "peek-stream": "^1.1.0",
- "pumpify": "^1.3.3",
- "through2": "^2.0.3"
- },
- "bin": {
- "gunzip-maybe": "bin.js"
- }
- },
"node_modules/handle-thing": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@@ -12224,12 +11121,6 @@
"react-is": "^16.7.0"
}
},
- "node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true
- },
"node_modules/hpack.js": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
@@ -12894,12 +11785,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-deflate": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz",
- "integrity": "sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==",
- "dev": true
- },
"node_modules/is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -12972,15 +11857,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-gzip": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz",
- "integrity": "sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
@@ -13279,80 +12155,19 @@
"node_modules/jackspeak": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
- "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
- "dev": true,
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/jake": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz",
- "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==",
- "dev": true,
- "dependencies": {
- "async": "^3.2.3",
- "chalk": "^4.0.2",
- "filelist": "^1.0.4",
- "minimatch": "^3.1.2"
- },
- "bin": {
- "jake": "bin/cli.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/jake/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jake/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
"dev": true,
"dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
+ "@isaacs/cliui": "^8.0.2"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
},
"funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jake/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
+ "url": "https://github.com/sponsors/isaacs"
},
- "engines": {
- "node": ">=8"
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
}
},
"node_modules/jest-worker": {
@@ -13395,86 +12210,13 @@
"js-yaml": "bin/js-yaml.js"
}
},
- "node_modules/jscodeshift": {
- "version": "0.15.2",
- "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.15.2.tgz",
- "integrity": "sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA==",
- "dev": true,
- "dependencies": {
- "@babel/core": "^7.23.0",
- "@babel/parser": "^7.23.0",
- "@babel/plugin-transform-class-properties": "^7.22.5",
- "@babel/plugin-transform-modules-commonjs": "^7.23.0",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11",
- "@babel/plugin-transform-optional-chaining": "^7.23.0",
- "@babel/plugin-transform-private-methods": "^7.22.5",
- "@babel/preset-flow": "^7.22.15",
- "@babel/preset-typescript": "^7.23.0",
- "@babel/register": "^7.22.15",
- "babel-core": "^7.0.0-bridge.0",
- "chalk": "^4.1.2",
- "flow-parser": "0.*",
- "graceful-fs": "^4.2.4",
- "micromatch": "^4.0.4",
- "neo-async": "^2.5.0",
- "node-dir": "^0.1.17",
- "recast": "^0.23.3",
- "temp": "^0.8.4",
- "write-file-atomic": "^2.3.0"
- },
- "bin": {
- "jscodeshift": "bin/jscodeshift.js"
- },
- "peerDependencies": {
- "@babel/preset-env": "^7.1.6"
- },
- "peerDependenciesMeta": {
- "@babel/preset-env": {
- "optional": true
- }
- }
- },
- "node_modules/jscodeshift/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/jscodeshift/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/jscodeshift/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "node_modules/jsdoc-type-pratt-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
"dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
"engines": {
- "node": ">=8"
+ "node": ">=12.0.0"
}
},
"node_modules/jsesc": {
@@ -13568,15 +12310,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/language-subtag-registry": {
"version": "0.3.22",
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz",
@@ -13619,15 +12352,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -13813,28 +12537,6 @@
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
- "node_modules/make-dir": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
- "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
- "dev": true,
- "dependencies": {
- "pify": "^4.0.1",
- "semver": "^5.6.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/make-dir/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
"node_modules/map-or-similar": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz",
@@ -14017,55 +12719,6 @@
"node": ">=8"
}
},
- "node_modules/minizlib": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
- "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
- "dev": true,
- "dependencies": {
- "minipass": "^3.0.0",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/minizlib/node_modules/minipass": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
- "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/minizlib/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "dev": true,
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
- "dev": true
- },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -14261,18 +12914,6 @@
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
"dev": true
},
- "node_modules/node-dir": {
- "version": "0.1.17",
- "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz",
- "integrity": "sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==",
- "dev": true,
- "dependencies": {
- "minimatch": "^3.0.2"
- },
- "engines": {
- "node": ">= 0.10.5"
- }
- },
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -14293,232 +12934,52 @@
}
}
},
- "node_modules/node-fetch-native": {
- "version": "1.6.4",
- "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.4.tgz",
- "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==",
- "dev": true
- },
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
"dev": true,
- "engines": {
- "node": ">= 6.13.0"
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
- "dev": true
- },
- "node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "dev": true,
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/nth-check": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
- "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
- "dev": true,
- "dependencies": {
- "boolbase": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/fb55/nth-check?sponsor=1"
- }
- },
- "node_modules/nypm": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.3.8.tgz",
- "integrity": "sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==",
- "dev": true,
- "dependencies": {
- "citty": "^0.1.6",
- "consola": "^3.2.3",
- "execa": "^8.0.1",
- "pathe": "^1.1.2",
- "ufo": "^1.4.0"
- },
- "bin": {
- "nypm": "dist/cli.mjs"
- },
- "engines": {
- "node": "^14.16.0 || >=16.10.0"
- }
- },
- "node_modules/nypm/node_modules/execa": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
- "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
- "dev": true,
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^8.0.1",
- "human-signals": "^5.0.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^4.1.0",
- "strip-final-newline": "^3.0.0"
- },
- "engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/nypm/node_modules/get-stream": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
- "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
- "dev": true,
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nypm/node_modules/human-signals": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
- "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
- "dev": true,
- "engines": {
- "node": ">=16.17.0"
- }
- },
- "node_modules/nypm/node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nypm/node_modules/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nypm/node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
- "dev": true,
- "dependencies": {
- "path-key": "^4.0.0"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nypm/node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
- "dev": true,
- "dependencies": {
- "mimic-fn": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "engines": {
+ "node": ">= 6.13.0"
}
},
- "node_modules/nypm/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "node_modules/node-releases": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true,
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": ">=0.10.0"
}
},
- "node_modules/nypm/node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
- "engines": {
- "node": ">=14"
+ "dependencies": {
+ "path-key": "^3.0.0"
},
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
+ "engines": {
+ "node": ">=8"
}
},
- "node_modules/nypm/node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
- "engines": {
- "node": ">=12"
+ "dependencies": {
+ "boolbase": "^1.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/object-assign": {
@@ -14666,12 +13127,6 @@
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true
},
- "node_modules/ohash": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.3.tgz",
- "integrity": "sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==",
- "dev": true
- },
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -14887,12 +13342,6 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true
},
- "node_modules/pako": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
- "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==",
- "dev": true
- },
"node_modules/param-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -15036,12 +13485,6 @@
"node": ">=8"
}
},
- "node_modules/pathe": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
- "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
- "dev": true
- },
"node_modules/pathval": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
@@ -15051,17 +13494,6 @@
"node": "*"
}
},
- "node_modules/peek-stream": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz",
- "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==",
- "dev": true,
- "dependencies": {
- "buffer-from": "^1.0.0",
- "duplexify": "^3.5.0",
- "through2": "^2.0.3"
- }
- },
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
@@ -15079,24 +13511,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
- "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
- "dev": true,
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -15345,19 +13759,6 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "dev": true,
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -15395,37 +13796,6 @@
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
- "node_modules/pump": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
- "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
- "dev": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/pumpify": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
- "dev": true,
- "dependencies": {
- "duplexify": "^3.6.0",
- "inherits": "^2.0.3",
- "pump": "^2.0.0"
- }
- },
- "node_modules/pumpify/node_modules/pump": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
- "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
- "dev": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -15812,56 +14182,6 @@
"react-dom": ">=16.6.0"
}
},
- "node_modules/read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
- "dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "dev": true,
- "dependencies": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up/node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg/node_modules/type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -16661,12 +14981,6 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "dev": true
- },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -16744,38 +15058,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
- "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
- "dev": true
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.18",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
- "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
- "dev": true
- },
"node_modules/spdy": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
@@ -16834,28 +15116,31 @@
"dev": true
},
"node_modules/storybook": {
- "version": "8.1.9",
- "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.1.9.tgz",
- "integrity": "sha512-Jymrfn299+MJBIZVDYPJlIGJMZM33udFCjbeRdOHIXF2BfpqOSS2FoEfmlp3zya3gwyZDq/BE7uiBc7HIVZa4g==",
+ "version": "8.4.7",
+ "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.4.7.tgz",
+ "integrity": "sha512-RP/nMJxiWyFc8EVMH5gp20ID032Wvk+Yr3lmKidoegto5Iy+2dVQnUoElZb2zpbVXNHWakGuAkfI0dY1Hfp/vw==",
"dev": true,
"dependencies": {
- "@storybook/cli": "8.1.9"
+ "@storybook/core": "8.4.7"
},
"bin": {
- "sb": "index.js",
- "storybook": "index.js"
+ "getstorybook": "bin/index.cjs",
+ "sb": "bin/index.cjs",
+ "storybook": "bin/index.cjs"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "prettier": "^2 || ^3"
+ },
+ "peerDependenciesMeta": {
+ "prettier": {
+ "optional": true
+ }
}
},
- "node_modules/stream-shift": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
- "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
- "dev": true
- },
"node_modules/strict-event-emitter": {
"version": "0.4.6",
"resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.4.6.tgz",
@@ -17237,63 +15522,6 @@
"node": ">=6"
}
},
- "node_modules/tar": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
- "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
- "dev": true,
- "dependencies": {
- "chownr": "^2.0.0",
- "fs-minipass": "^2.0.0",
- "minipass": "^5.0.0",
- "minizlib": "^2.1.1",
- "mkdirp": "^1.0.3",
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
- "dev": true,
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "node_modules/tar-fs/node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "dev": true
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "dev": true,
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tar/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/telejson": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/telejson/-/telejson-7.2.0.tgz",
@@ -17303,18 +15531,6 @@
"memoizerific": "^1.11.3"
}
},
- "node_modules/temp": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz",
- "integrity": "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==",
- "dev": true,
- "dependencies": {
- "rimraf": "~2.6.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/temp-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
@@ -17324,19 +15540,6 @@
"node": ">=14.16"
}
},
- "node_modules/temp/node_modules/rimraf": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
- "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
"node_modules/tempy": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz",
@@ -17443,37 +15646,6 @@
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true
},
- "node_modules/through2": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
- "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
- "dev": true,
- "dependencies": {
- "readable-stream": "~2.3.6",
- "xtend": "~4.0.1"
- }
- },
- "node_modules/through2/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/through2/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
"node_modules/thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
@@ -17833,12 +16005,6 @@
"node": ">=14.17"
}
},
- "node_modules/ufo": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
- "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
- "dev": true
- },
"node_modules/uglify-js": {
"version": "3.18.0",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz",
@@ -17913,18 +16079,6 @@
"node": ">=4"
}
},
- "node_modules/unicorn-magic": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
- "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/unique-string": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
@@ -18021,15 +16175,6 @@
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
"dev": true
},
- "node_modules/untildify": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
- "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/update-browserslist-db": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
@@ -18197,16 +16342,6 @@
"uuid": "dist/bin/uuid"
}
},
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -18803,17 +16938,6 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
- "node_modules/write-file-atomic": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
- "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.11",
- "imurmurhash": "^0.1.4",
- "signal-exit": "^3.0.2"
- }
- },
"node_modules/ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
@@ -18835,15 +16959,6 @@
}
}
},
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
- "engines": {
- "node": ">=0.4"
- }
- },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index 4af34519..ce18167f 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"@storybook/addon-interactions": "^8.1.9",
"@storybook/addon-links": "^8.1.9",
"@storybook/addon-onboarding": "^8.1.9",
+ "@storybook/addon-viewport": "^8.4.7",
"@storybook/addon-webpack5-compiler-swc": "^1.0.3",
"@storybook/blocks": "^8.1.9",
"@storybook/react": "^8.1.9",
diff --git a/public/index.html b/public/index.html
index d683a159..c828820d 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,6 +1,7 @@
+
PICK-O
diff --git a/src/App.tsx b/src/App.tsx
index 42ed6274..afc3e23a 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import React from 'react';
+import React, { useEffect } from 'react';
import { LocalizationProvider } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import 'dayjs/locale/ko';
@@ -39,10 +39,25 @@ import BalanceGameCreationPage from './pages/BalanceGameCreationPage/BalanceGame
// import PostPage from './pages/PostPage/PostPage';
// import SearchResultPage from './pages/SearchResultPage/SearchResultPage';
// import SignUpPage from './pages/SignUpPage/SignUpPage';
-// import { useNewSelector } from './store';
-// import { selectAccessToken } from './store/auth';
+import { getCookie } from './utils/cookie';
+import { axiosInstance } from './api/interceptor';
+import { useNewDispatch } from './store';
+import { tokenActions } from './store/auth';
const App: React.FC = () => {
+ const dispatch = useNewDispatch();
+
+ useEffect(() => {
+ const token = getCookie('accessToken');
+ if (token) {
+ localStorage.setItem('accessToken', token);
+ localStorage.setItem('refreshToken', 'refreshToken');
+
+ dispatch(tokenActions.setToken(token));
+ axiosInstance.defaults.headers.Authorization = `Bearer ${token}`;
+ }
+ }, [dispatch]);
+
// const accessToken = useNewSelector(selectAccessToken);
// const { member } = useMemberQuery(useParseJwt(accessToken).memberId);
const isLoggedIn = !!localStorage.getItem('accessToken');
diff --git a/src/api/game.ts b/src/api/game.ts
index cd4ccf7b..49ff1299 100644
--- a/src/api/game.ts
+++ b/src/api/game.ts
@@ -4,6 +4,7 @@ import {
BalanceGame,
Game,
GameContent,
+ GameParams,
GameSet,
TempGame,
} from '@/types/game';
@@ -61,21 +62,35 @@ export const getNewGames = async () => {
};
export const getBestGames = async (tagName: string) => {
+ const params: GameParams = {
+ page: GAME_VALUE.PAGE,
+ size: GAME_VALUE.SIZE,
+ };
+
+ if (tagName !== 'μΈκΈ°') {
+ params.tagName = tagName;
+ }
+
const { data } = await axiosInstance.get(
`${END_POINT.BEST_GAME}`,
- {
- params: { tagName, page: GAME_VALUE.PAGE, size: GAME_VALUE.SIZE },
- },
+ { params },
);
return data;
};
export const getLatestGames = async (tagName: string) => {
+ const params: GameParams = {
+ page: GAME_VALUE.PAGE,
+ size: GAME_VALUE.SIZE,
+ };
+
+ if (tagName !== 'μΈκΈ°') {
+ params.tagName = tagName;
+ }
+
const { data } = await axiosInstance.get(
`${END_POINT.LATEST_GAME}`,
- {
- params: { tagName, page: GAME_VALUE.PAGE, size: GAME_VALUE.SIZE },
- },
+ { params },
);
return data;
};
diff --git a/src/api/mypages.ts b/src/api/mypages.ts
index 71521241..80178222 100644
--- a/src/api/mypages.ts
+++ b/src/api/mypages.ts
@@ -62,6 +62,6 @@ export const getGameBookmark = async (page: number, size: number) => {
};
export const getMyInfo = async (memberId: Id): Promise => {
- const response = await axiosInstance.get(`/members/${memberId}`);
- return response.data;
+ const { data } = await axiosInstance.get(`/members/${memberId}`);
+ return data;
};
diff --git a/src/assets/index.ts b/src/assets/index.ts
index fa163110..5946521a 100644
--- a/src/assets/index.ts
+++ b/src/assets/index.ts
@@ -91,6 +91,31 @@ export { default as IcMobileVote } from './svg/MobileVote.svg';
export { default as IcMobileVoteDF } from './svg/MobileVoteDF.svg';
export { default as IcMobileWritten } from './svg/MobileWritten.svg';
export { default as IcMobileWrittenDF } from './svg/MobileWrittenDF.svg';
+export { default as ListIcon } from './svg/list.svg';
+export { default as LogoSmall } from './svg/logo-small.svg';
+export { default as PickVoteSmall } from './svg/pick-vote-small.svg';
+export { default as RandomGameSmall } from './svg/random-game-small.svg';
+export { default as CheckSmall } from './svg/check-small.svg';
+export { default as PopularSmall } from './svg/popular-small.svg';
+export { default as CoupleSmall } from './svg/couple-small.svg';
+export { default as TasteSmall } from './svg/taste-small.svg';
+export { default as WorldcupSmall } from './svg/worldcup-small.svg';
+export { default as TriangleDown } from './svg/triangle-down.svg';
+export { default as TriangleUp } from './svg/triangle-up.svg';
+export { default as BookmarkDFSmall } from './svg/bookmark-df-sm.svg';
+export { default as BookmarkPRSmall } from './svg/bookmark-pr-sm.svg';
+export { default as CirclePencil } from './svg/circle-pencil.svg';
+export { default as CircleClose } from './svg/circle-close.svg';
+export { default as CircleGame } from './svg/circle-game.svg';
+export { default as CircleTalkPick } from './svg/circle-talkpick.svg';
+export { default as MobileBookmarkDF } from './svg/mobile-bookmark-df.svg';
+export { default as MobileBookmarkPR } from './svg/mobile-bookmark-pr.svg';
+export { default as MobileShare } from './svg/mobile-share.svg';
+export { default as MobileModalClose } from './svg/mobile-modal-close.svg';
+export { default as MobileFolder } from './svg/mobile-folder.svg';
+export { default as MobileFolderCheck } from './svg/mobile-folder-check.svg';
+export { default as MobileCheckIcon } from './svg/mobile-check-icon.svg';
+export { default as MobileTempIcon } from './svg/mobile-temp-icon.svg';
// TODO: μ΄μ SVG
export { default as Email } from './svg/email.svg';
diff --git a/src/assets/svg/bookmark-df-sm.svg b/src/assets/svg/bookmark-df-sm.svg
new file mode 100644
index 00000000..ec9b0085
--- /dev/null
+++ b/src/assets/svg/bookmark-df-sm.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/bookmark-df.svg b/src/assets/svg/bookmark-df.svg
index 89eb93d1..7e5564a3 100644
--- a/src/assets/svg/bookmark-df.svg
+++ b/src/assets/svg/bookmark-df.svg
@@ -1,10 +1,10 @@
\ No newline at end of file
+
diff --git a/src/assets/svg/bookmark-pr-sm.svg b/src/assets/svg/bookmark-pr-sm.svg
new file mode 100644
index 00000000..18378deb
--- /dev/null
+++ b/src/assets/svg/bookmark-pr-sm.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/check-small.svg b/src/assets/svg/check-small.svg
new file mode 100644
index 00000000..dddd9a86
--- /dev/null
+++ b/src/assets/svg/check-small.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/circle-close.svg b/src/assets/svg/circle-close.svg
new file mode 100644
index 00000000..d0cf7663
--- /dev/null
+++ b/src/assets/svg/circle-close.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/assets/svg/circle-game.svg b/src/assets/svg/circle-game.svg
new file mode 100644
index 00000000..7ddf5dca
--- /dev/null
+++ b/src/assets/svg/circle-game.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/assets/svg/circle-pencil.svg b/src/assets/svg/circle-pencil.svg
new file mode 100644
index 00000000..75e16a94
--- /dev/null
+++ b/src/assets/svg/circle-pencil.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/assets/svg/circle-talkpick.svg b/src/assets/svg/circle-talkpick.svg
new file mode 100644
index 00000000..7c669882
--- /dev/null
+++ b/src/assets/svg/circle-talkpick.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/assets/svg/couple-small.svg b/src/assets/svg/couple-small.svg
new file mode 100644
index 00000000..9e503224
--- /dev/null
+++ b/src/assets/svg/couple-small.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/assets/svg/list.svg b/src/assets/svg/list.svg
new file mode 100644
index 00000000..10ad71c9
--- /dev/null
+++ b/src/assets/svg/list.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/logo-small.svg b/src/assets/svg/logo-small.svg
new file mode 100644
index 00000000..16739f01
--- /dev/null
+++ b/src/assets/svg/logo-small.svg
@@ -0,0 +1,16 @@
+
diff --git a/src/assets/svg/mobile-bookmark-df.svg b/src/assets/svg/mobile-bookmark-df.svg
new file mode 100644
index 00000000..07f5e9cd
--- /dev/null
+++ b/src/assets/svg/mobile-bookmark-df.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/mobile-bookmark-pr.svg b/src/assets/svg/mobile-bookmark-pr.svg
new file mode 100644
index 00000000..ea6fae8f
--- /dev/null
+++ b/src/assets/svg/mobile-bookmark-pr.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/mobile-check-icon.svg b/src/assets/svg/mobile-check-icon.svg
new file mode 100644
index 00000000..8f1c6e73
--- /dev/null
+++ b/src/assets/svg/mobile-check-icon.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/svg/mobile-folder-check.svg b/src/assets/svg/mobile-folder-check.svg
new file mode 100644
index 00000000..6e33df9e
--- /dev/null
+++ b/src/assets/svg/mobile-folder-check.svg
@@ -0,0 +1,10 @@
+
diff --git a/src/assets/svg/mobile-folder.svg b/src/assets/svg/mobile-folder.svg
new file mode 100644
index 00000000..c815ebf1
--- /dev/null
+++ b/src/assets/svg/mobile-folder.svg
@@ -0,0 +1,11 @@
+
diff --git a/src/assets/svg/mobile-modal-close.svg b/src/assets/svg/mobile-modal-close.svg
new file mode 100644
index 00000000..5a75ae98
--- /dev/null
+++ b/src/assets/svg/mobile-modal-close.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/svg/mobile-share.svg b/src/assets/svg/mobile-share.svg
new file mode 100644
index 00000000..faae4e31
--- /dev/null
+++ b/src/assets/svg/mobile-share.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/mobile-temp-icon.svg b/src/assets/svg/mobile-temp-icon.svg
new file mode 100644
index 00000000..88c27224
--- /dev/null
+++ b/src/assets/svg/mobile-temp-icon.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/svg/pick-vote-small.svg b/src/assets/svg/pick-vote-small.svg
new file mode 100644
index 00000000..09056124
--- /dev/null
+++ b/src/assets/svg/pick-vote-small.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/assets/svg/popular-small.svg b/src/assets/svg/popular-small.svg
new file mode 100644
index 00000000..a4d7f805
--- /dev/null
+++ b/src/assets/svg/popular-small.svg
@@ -0,0 +1,16 @@
+
diff --git a/src/assets/svg/random-game-small.svg b/src/assets/svg/random-game-small.svg
new file mode 100644
index 00000000..62f97593
--- /dev/null
+++ b/src/assets/svg/random-game-small.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/assets/svg/taste-small.svg b/src/assets/svg/taste-small.svg
new file mode 100644
index 00000000..b79afbfb
--- /dev/null
+++ b/src/assets/svg/taste-small.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/assets/svg/triangle-down.svg b/src/assets/svg/triangle-down.svg
new file mode 100644
index 00000000..a8520511
--- /dev/null
+++ b/src/assets/svg/triangle-down.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/triangle-up.svg b/src/assets/svg/triangle-up.svg
new file mode 100644
index 00000000..49a27ed9
--- /dev/null
+++ b/src/assets/svg/triangle-up.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/svg/worldcup-small.svg b/src/assets/svg/worldcup-small.svg
new file mode 100644
index 00000000..e367c3f3
--- /dev/null
+++ b/src/assets/svg/worldcup-small.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/src/components/atoms/BalanceGameCategoryButton/BalanceGameCategoryButton.style.ts b/src/components/atoms/BalanceGameCategoryButton/BalanceGameCategoryButton.style.ts
index c04a9ff7..61ace0fa 100644
--- a/src/components/atoms/BalanceGameCategoryButton/BalanceGameCategoryButton.style.ts
+++ b/src/components/atoms/BalanceGameCategoryButton/BalanceGameCategoryButton.style.ts
@@ -12,6 +12,9 @@ export const buttonStyle = css({
border: 'none',
outline: 'none',
width: '284px',
+ '@media (max-width: 430px)': {
+ width: '84px',
+ },
});
export const buttonTitleStyle = css({
@@ -20,18 +23,32 @@ export const buttonTitleStyle = css({
alignItems: 'center',
marginBottom: '8px',
transition: 'color 0.3s ease-in-out',
+ '@media (max-width: 430px)': {
+ marginBottom: '2px',
+ },
});
export const iconStyle = css({
marginLeft: '8px',
+ '@media (max-width: 430px)': {
+ marginLeft: '2px',
+ },
});
-export const activeStyle = css(typo.Component.Bold, {
+export const activeStyle = css({
+ ...typo.Component.Bold,
color: color.MAIN,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.Bold_12,
+ },
});
-export const inactiveStyle = css(typo.Component.Medium, {
+export const inactiveStyle = css({
+ ...typo.Component.Medium,
color: color.GY[1],
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.Medium_12,
+ },
});
export const inactiveBadgeWrapStyle = css({
@@ -40,6 +57,9 @@ export const inactiveBadgeWrapStyle = css({
justifyContent: 'center',
width: '100%',
marginTop: '22px',
+ '@media (max-width: 430px)': {
+ marginTop: '6px',
+ },
});
export const badgeWrapStyle = css({
@@ -48,21 +68,32 @@ export const badgeWrapStyle = css({
justifyContent: 'center',
width: '100%',
marginTop: '14px',
+ '@media (max-width: 430px)': {
+ marginTop: '2px',
+ },
});
export const inactiveLineStyle = (label: string) => {
- let borderRadius = '0';
+ let baseBorderRadius = '0';
+ let mobileBorderRadius = '0';
+
if (label === 'μΈκΈ°') {
- borderRadius = '10px 0 0 10px';
+ baseBorderRadius = '10px 0 0 10px';
+ mobileBorderRadius = '3px 0 0 3px';
} else if (label === 'μλμ»΅') {
- borderRadius = '0 10px 10px 0';
+ baseBorderRadius = '0 10px 10px 0';
+ mobileBorderRadius = '0 3px 3px 0';
}
return css({
flex: 1,
height: '5px',
backgroundColor: color.GY[2],
- borderRadius,
+ borderRadius: baseBorderRadius,
+ '@media (max-width: 430px)': {
+ height: '1.5px',
+ borderRadius: mobileBorderRadius,
+ },
});
};
@@ -71,6 +102,10 @@ export const leftLineStyle = css({
height: '5px',
borderRadius: '10px 0 0 10px',
backgroundColor: color.MAIN,
+ '@media (max-width: 430px)': {
+ height: '1.5px',
+ borderRadius: '3px 0 0 3px',
+ },
});
export const rightLineStyle = css({
@@ -78,11 +113,20 @@ export const rightLineStyle = css({
height: '5px',
borderRadius: '0 10px 10px 0',
backgroundColor: color.MAIN,
+ '@media (max-width: 430px)': {
+ height: '1.5px',
+ borderRadius: '0 3px 3px 0',
+ },
});
-export const badgeStyle = css(typo.Comment.SemiBold, {
+export const badgeStyle = css({
+ ...typo.Comment.SemiBold,
padding: '4.5px 32px',
borderRadius: '30px',
backgroundColor: color.MAIN,
color: color.WT,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.SemiBold_7,
+ padding: '0.5px 5.5px',
+ },
});
diff --git a/src/components/atoms/Bookmark/Bookmark.style.ts b/src/components/atoms/Bookmark/Bookmark.style.ts
index f863a744..7b9468e2 100644
--- a/src/components/atoms/Bookmark/Bookmark.style.ts
+++ b/src/components/atoms/Bookmark/Bookmark.style.ts
@@ -11,6 +11,10 @@ export const bookmarkButton = css`
border: none;
cursor: pointer;
padding: 0;
+ @media (max-width: 430px) {
+ width: 19px;
+ height: 19px;
+ }
`;
export const icon = css`
diff --git a/src/components/atoms/Bookmark/Bookmark.tsx b/src/components/atoms/Bookmark/Bookmark.tsx
index 6c395ca7..af3b2287 100644
--- a/src/components/atoms/Bookmark/Bookmark.tsx
+++ b/src/components/atoms/Bookmark/Bookmark.tsx
@@ -1,5 +1,11 @@
import React, { useState, useEffect, ComponentPropsWithRef } from 'react';
-import { BookmarkDF, BookmarkPR } from '@/assets';
+import {
+ BookmarkDF,
+ BookmarkDFSmall,
+ BookmarkPR,
+ BookmarkPRSmall,
+} from '@/assets';
+import useIsMobile from '@/hooks/common/useIsMobile';
import * as S from './Bookmark.style';
export interface BookmarkProps extends ComponentPropsWithRef<'button'> {
@@ -8,6 +14,7 @@ export interface BookmarkProps extends ComponentPropsWithRef<'button'> {
const Bookmark = ({ bookmarked = false, ...attributes }: BookmarkProps) => {
const [isPressed, setIsPressed] = useState(bookmarked);
+ const isMobile = useIsMobile();
useEffect(() => {
setIsPressed(bookmarked);
@@ -17,6 +24,13 @@ const Bookmark = ({ bookmarked = false, ...attributes }: BookmarkProps) => {
setIsPressed((prevState) => !prevState);
};
+ const renderIcon = () => {
+ if (isPressed) {
+ return isMobile ? : ;
+ }
+ return isMobile ? : ;
+ };
+
return (
);
};
diff --git a/src/components/atoms/Button/Button.style.ts b/src/components/atoms/Button/Button.style.ts
index a3cc3094..0b273039 100644
--- a/src/components/atoms/Button/Button.style.ts
+++ b/src/components/atoms/Button/Button.style.ts
@@ -107,12 +107,14 @@ export const getSizeByVariantStyling = (
padding: '8px 16px',
}),
medium: css({}),
+ small: css({}),
},
primarySquare: {
large: css(typo.Main.SemiBold, {
padding: '15.5px 120px',
}),
medium: css({}),
+ small: css({}),
},
roundPrimary: {
large: css(typo.SubTitle, {
@@ -124,6 +126,7 @@ export const getSizeByVariantStyling = (
padding: '10px 25px',
borderRadius: '25px',
}),
+ small: css({}),
},
roundPrimary2: {
large: css(typo.Main.SemiBold, {
@@ -131,18 +134,21 @@ export const getSizeByVariantStyling = (
borderRadius: '25px',
}),
medium: css({}),
+ small: css({}),
},
outlinePrimary: {
large: css(typo.Main.SemiBold, {
padding: '10px 25px',
}),
medium: css({}),
+ small: css({}),
},
outlineSecondary: {
large: css(typo.Main.SemiBold, {
padding: '10px 25px',
}),
medium: css({}),
+ small: css({}),
},
outlinePrimarySquare: {
large: css(typo.Main.SemiBold, {
@@ -151,6 +157,7 @@ export const getSizeByVariantStyling = (
medium: css(typo.Main.SemiBold_16, {
padding: '8px 16px',
}),
+ small: css({}),
},
outlineShadow: {
large: css(typo.Main.SemiBold, {
@@ -163,6 +170,15 @@ export const getSizeByVariantStyling = (
color: color.MAIN,
boxShadow: '1px 2px 7px rgba(0, 0, 0, 0.15)',
}),
+ small: css(typo.Mobile.Text.SemiBold_10, {
+ padding: '7.2px 14.4px',
+ color: color.BK,
+ boxShadow: '1px 2px 7px rgba(0, 0, 0, 0.15)',
+ '& svg': {
+ width: '10.5px',
+ height: '10.5px',
+ },
+ }),
},
outlineHighlightR: {
large: css(typo.Component.Bold, {
@@ -170,6 +186,7 @@ export const getSizeByVariantStyling = (
padding: '22px 50px',
}),
medium: css({}),
+ small: css({}),
},
outlineHighlightB: {
large: css(typo.Component.Bold, {
@@ -177,6 +194,7 @@ export const getSizeByVariantStyling = (
padding: '22px 50px',
}),
medium: css({}),
+ small: css({}),
},
circle: {
large: css({
@@ -186,7 +204,14 @@ export const getSizeByVariantStyling = (
height: '22px',
},
}),
- medium: css({}),
+ medium: css({
+ padding: '8.5px',
+ '& svg': {
+ width: '10.5px',
+ height: '10.5px',
+ },
+ }),
+ small: css({}),
},
};
diff --git a/src/components/atoms/Button/Button.tsx b/src/components/atoms/Button/Button.tsx
index 5ef6fd59..8033c1e1 100644
--- a/src/components/atoms/Button/Button.tsx
+++ b/src/components/atoms/Button/Button.tsx
@@ -8,7 +8,7 @@ import {
} from './Button.style';
export interface ButtonProps extends ComponentPropsWithRef<'button'> {
- size?: Extract;
+ size?: Extract;
variant?:
| 'primary'
| 'primarySquare'
diff --git a/src/components/atoms/CategoryButton/CategoryButton.style.ts b/src/components/atoms/CategoryButton/CategoryButton.style.ts
index 3b96b103..6d6f3648 100644
--- a/src/components/atoms/CategoryButton/CategoryButton.style.ts
+++ b/src/components/atoms/CategoryButton/CategoryButton.style.ts
@@ -2,27 +2,37 @@ import { css } from '@emotion/react';
import color from '@/styles/color';
import typo from '@/styles/typo';
-export const categoryButtonBaseStyle = css`
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- width: 367px;
- height: 189px;
- padding: 40px 85px;
- border-radius: 20px;
- border: 1px solid #dedede;
- background-color: ${color.WT};
- box-shadow: 1px 1px 15px 0 rgba(0, 0, 0, 0.1);
- cursor: pointer;
- transition: all 0.3s ease-in;
-`;
+export const categoryButtonBaseStyle = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ width: '367px',
+ height: '189px',
+ padding: '40px 85px',
+ borderRadius: '20px',
+ border: '1px solid #dedede',
+ backgroundColor: color.WT,
+ boxShadow: '1px 1px 15px 0 rgba(0, 0, 0, 0.1)',
+ cursor: 'pointer',
+ transition: 'all 0.3s ease-in',
+ '@media (max-width: 430px)': {
+ width: '164px',
+ height: '70px',
+ padding: '5px 45px 14px 45px',
+ borderRadius: '7px',
+ border: '0.35px solid #dedede',
+ },
+});
-export const imgWrap = css`
- flex-shrink: 0;
-`;
+export const imgWrap = css({
+ flexShrink: 0,
+});
-export const labelStyle = css`
- ${typo.SubTitle}
- margin-top: auto;
-`;
+export const labelStyle = css({
+ ...typo.SubTitle,
+ marginTop: 'auto',
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.Medium_8,
+ },
+});
diff --git a/src/components/atoms/CategoryButton/CategoryButton.tsx b/src/components/atoms/CategoryButton/CategoryButton.tsx
index 23cb951b..61250b54 100644
--- a/src/components/atoms/CategoryButton/CategoryButton.tsx
+++ b/src/components/atoms/CategoryButton/CategoryButton.tsx
@@ -1,25 +1,33 @@
import React from 'react';
import type { ComponentPropsWithRef } from 'react';
-import { PickVote, RandomGame, TodayPick } from '@/assets';
+import {
+ PickVote,
+ PickVoteSmall,
+ RandomGame,
+ RandomGameSmall,
+ TodayPick,
+} from '@/assets';
import * as S from './CategoryButton.style';
export interface CategoryButtonProps extends ComponentPropsWithRef<'button'> {
imageType: 'PickVote' | 'RandomGame' | 'TodayPick';
label: string;
+ isMobile?: boolean;
}
const CategoryButton = ({
imageType,
label,
+ isMobile = false,
...attributes
}: CategoryButtonProps) => {
let ImageComponent;
switch (imageType) {
case 'PickVote':
- ImageComponent = PickVote;
+ ImageComponent = isMobile ? PickVoteSmall : PickVote;
break;
case 'RandomGame':
- ImageComponent = RandomGame;
+ ImageComponent = isMobile ? RandomGameSmall : RandomGame;
break;
case 'TodayPick':
ImageComponent = TodayPick;
diff --git a/src/components/atoms/CheckBoxButton/CheckBoxButton.style.ts b/src/components/atoms/CheckBoxButton/CheckBoxButton.style.ts
index 9662a9d5..fbf5b81e 100644
--- a/src/components/atoms/CheckBoxButton/CheckBoxButton.style.ts
+++ b/src/components/atoms/CheckBoxButton/CheckBoxButton.style.ts
@@ -48,6 +48,6 @@ export const checkBoxRadioStyling = css({
export const checkBoxTextStyling = css(typo.Main.Medium, {
marginLeft: '14px',
- color: color.GY[4],
+ color: '#555555',
cursor: 'pointer',
});
diff --git a/src/components/atoms/Chips/Chips.style.ts b/src/components/atoms/Chips/Chips.style.ts
index 667292fe..7f21fefe 100644
--- a/src/components/atoms/Chips/Chips.style.ts
+++ b/src/components/atoms/Chips/Chips.style.ts
@@ -3,7 +3,8 @@ import color from '@/styles/color';
import typo from '@/styles/typo';
import type { ChipsProps } from './Chips';
-export const chipsStyling = css(typo.Main.SemiBold, {
+export const chipsStyling = css({
+ ...typo.Main.SemiBold,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
@@ -11,6 +12,10 @@ export const chipsStyling = css(typo.Main.SemiBold, {
backgroundColor: color.WT,
color: color.MAIN,
outline: `1px solid ${color.MAIN}`,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.SemiBold_10,
+ padding: '4px 9px',
+ },
});
export const getChipStyling = (variant: Required['variant']) => {
@@ -18,6 +23,10 @@ export const getChipStyling = (variant: Required['variant']) => {
outline: css({
padding: '10px 18px',
borderRadius: '12px',
+ '@media (max-width: 430px)': {
+ padding: '4px 9px',
+ borderRadius: '7.2px',
+ },
}),
roundOutline: css({
padding: '10px 25px',
diff --git a/src/components/atoms/SearchBar/SearchBar.style.ts b/src/components/atoms/SearchBar/SearchBar.style.ts
index 9a45ab66..2c78c88f 100644
--- a/src/components/atoms/SearchBar/SearchBar.style.ts
+++ b/src/components/atoms/SearchBar/SearchBar.style.ts
@@ -12,6 +12,11 @@ export const searchBarStyling = css({
outline: `1px solid ${color.GY[2]}`,
borderRadius: '50px',
boxShadow: '1px 2px 15px rgba(0, 0, 0, 0.05)',
+ '@media (max-width: 430px)': {
+ width: '335px',
+ height: '36px',
+ padding: '0 5px',
+ },
});
export const inputStyling = css(typo.SubTitle, {
@@ -20,3 +25,9 @@ export const inputStyling = css(typo.SubTitle, {
outline: 'none',
padding: '0 35px',
});
+
+export const mobileInputStyling = css(typo.Mobile.Text.Medium_12, {
+ width: '100%',
+ height: '36px',
+ padding: '0 5px',
+});
diff --git a/src/components/atoms/SearchBar/SearchBar.tsx b/src/components/atoms/SearchBar/SearchBar.tsx
index c7065c24..7f0519bf 100644
--- a/src/components/atoms/SearchBar/SearchBar.tsx
+++ b/src/components/atoms/SearchBar/SearchBar.tsx
@@ -10,24 +10,52 @@ import * as S from './SearchBar.style';
export interface SearchBarProps extends ComponentPropsWithoutRef<'input'> {
onSearchClick: () => void;
onInputChange: (e: React.ChangeEvent) => void;
+ isMobile?: boolean;
}
const SearchBar = (
- { onSearchClick, onInputChange, ...props }: SearchBarProps,
+ { onSearchClick, onInputChange, isMobile = false, ...props }: SearchBarProps,
ref: ForwardedRef,
-) => (
-
-
-
-
-);
+) => {
+ const handleInputKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key === 'Enter') {
+ onSearchClick();
+ }
+ };
+
+ return (
+
+ {isMobile ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+ );
+};
export default forwardRef(SearchBar);
diff --git a/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.style.ts b/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.style.ts
index 77d12aa3..4f86089e 100644
--- a/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.style.ts
+++ b/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.style.ts
@@ -3,6 +3,7 @@ import color from '@/styles/color';
import typo from '@/styles/typo';
export const searchTalkPickItemStyle = css({
+ all: 'unset',
display: 'flex',
flexDirection: 'row',
width: '1065px',
@@ -36,12 +37,13 @@ export const dateStyle = css(typo.Number.Regular, {
});
export const contentWrapStyle = css({
- display: 'flex',
+ display: 'inline',
+ height: '45px',
+ overflowY: 'hidden',
});
+
export const contentStyle = (highlighted: boolean) =>
css(typo.Comment.Regular, {
- overflowY: 'hidden',
- height: '45px',
color: highlighted ? color.MAIN : color.GY[1],
});
diff --git a/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.tsx b/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.tsx
index 68a2e1e6..0fda6e2b 100644
--- a/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.tsx
+++ b/src/components/atoms/SearchTalkPickItem/SearchTalkPickItem.tsx
@@ -9,6 +9,7 @@ export interface SearchTalkPickItemProps {
content: string;
firstImgUrl: string;
keyword: string;
+ onClick: () => void;
}
const SearchTalkPickItem = ({
@@ -17,9 +18,10 @@ const SearchTalkPickItem = ({
content,
firstImgUrl,
keyword,
+ onClick,
}: SearchTalkPickItemProps) => {
return (
-
+
+ {firstImgUrl && (
+
+
+
+ )}
+
);
};
export default SearchTalkPickItem;
diff --git a/src/components/atoms/SelectGroup/SelectGroup.style.ts b/src/components/atoms/SelectGroup/SelectGroup.style.ts
index e756ac7f..6b73ceff 100644
--- a/src/components/atoms/SelectGroup/SelectGroup.style.ts
+++ b/src/components/atoms/SelectGroup/SelectGroup.style.ts
@@ -7,7 +7,7 @@ export const selectGroupStyling = css({
alignItems: 'center',
backgroundColor: 'transparent',
padding: '4px',
- width: '100%',
+ width: '912px',
justifyContent: 'space-between',
position: 'relative',
});
diff --git a/src/components/atoms/SelectGroup/SelectGroup.tsx b/src/components/atoms/SelectGroup/SelectGroup.tsx
index d03008a6..8593904e 100644
--- a/src/components/atoms/SelectGroup/SelectGroup.tsx
+++ b/src/components/atoms/SelectGroup/SelectGroup.tsx
@@ -1,34 +1,39 @@
import React from 'react';
import * as S from './SelectGroup.style';
-export type SelectGroupItem = {
+export type SelectGroupItem = {
label: string;
- value: string;
+ value: T;
};
-export interface SelectGroupProps {
- items: SelectGroupItem[];
- selectedValue?: string;
- onSelect?: (value: string) => void;
+export interface SelectGroupProps {
+ items: [SelectGroupItem, SelectGroupItem];
+ selectedValue?: T;
+ onSelect?: (value: T) => void;
}
-const SelectGroup = ({ items, selectedValue, onSelect }: SelectGroupProps) => (
-
- {Array.isArray(items) &&
- items.length === 2 &&
- items.map((item) => (
-
- ))}
+
+const SelectGroup =
({
+ items,
+ selectedValue,
+ onSelect,
+}: SelectGroupProps) => (
+
+ {items.map(({ label, value }) => (
+
+ ))}
);
diff --git a/src/components/atoms/ToggleGroup/ToggleGroup.tsx b/src/components/atoms/ToggleGroup/ToggleGroup.tsx
index e55d3d0e..5c3da7d0 100644
--- a/src/components/atoms/ToggleGroup/ToggleGroup.tsx
+++ b/src/components/atoms/ToggleGroup/ToggleGroup.tsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { ToggleGroupItem, ToggleGroupProps } from '@/types/toggle';
import {
selectedStyling,
firstItemRadius,
@@ -7,22 +8,21 @@ import {
toggleButtonItemStyling,
} from './ToggleGroup.style';
-export type ToggleGroupItem = {
- label: string;
- value: string;
-};
-
-export interface ToggleGroupProps {
- items?: ToggleGroupItem[];
- selectedValue?: string;
- onClick?: (value: string) => void;
-}
-
const defaultItems: ToggleGroupItem[] = [
- { label: 'μΈκΈ°μ', value: 'views' },
- { label: 'μ΅μ μ', value: 'createdAt' },
+ { label: 'μΈκΈ°μ', value: { field: 'views', order: 'desc' } },
+ { label: 'μ΅μ μ', value: { field: 'createdAt', order: 'desc' } },
];
+const isSelected = (
+ selectedValue: { field: string; order: 'asc' | 'desc' } | undefined,
+ value: { field: string; order: 'asc' | 'desc' },
+): boolean => {
+ if (!selectedValue) return false;
+ return (
+ selectedValue.field === value.field && selectedValue.order === value.order
+ );
+};
+
const ToggleGroup = ({
items = defaultItems,
selectedValue,
@@ -31,18 +31,18 @@ const ToggleGroup = ({
{Array.isArray(items) &&
items.length === 2 &&
- items.map((item, idx) => (
+ items.map(({ label, value }, idx) => (
))}
diff --git a/src/components/mobile/atoms/Button/Button.style.ts b/src/components/mobile/atoms/Button/Button.style.ts
new file mode 100644
index 00000000..14a4b850
--- /dev/null
+++ b/src/components/mobile/atoms/Button/Button.style.ts
@@ -0,0 +1,85 @@
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+import { css } from '@emotion/react';
+import type { ButtonProps } from './Button';
+
+export const getVariantStyling = (
+ variant: Required['variant'],
+ active: boolean,
+) => {
+ const style = {
+ primary: css({
+ borderRadius: '10px',
+ backgroundColor: active ? color.MAIN : color.GY[2],
+ color: color.WT,
+ }),
+ roundPrimary: css({
+ borderRadius: '80px',
+ backgroundColor: active ? color.MAIN : color.GY[2],
+ color: color.WT,
+ }),
+ Primary2: css({
+ borderRadius: '6px',
+ backgroundColor: color.MAIN,
+ color: color.WT,
+ }),
+ outlineShadow: css({
+ border: `1px solid ${color.GY[4]}`,
+ borderRadius: '6px',
+ backgroundColor: color.GY[5],
+ color: color.GY[1],
+ }),
+ };
+
+ return style[variant];
+};
+
+export const getSizeByVariantStyling = (
+ variant: Required['variant'],
+ size: Required['size'],
+) => {
+ const style = {
+ primary: {
+ large: css(typo.Main.SemiBold, {
+ width: '335px',
+ height: '50px',
+ }),
+ medium: css(typo.Main.SemiBold, {
+ width: '130px',
+ height: '50px',
+ }),
+ },
+ roundPrimary: {
+ large: css(typo.Mobile.Text.SemiBold_14, {
+ width: '295px',
+ height: '40px',
+ }),
+ medium: css({}),
+ },
+ Primary2: {
+ large: css({}),
+ medium: css({
+ width: '64px',
+ height: '34px',
+ }),
+ },
+ outlineShadow: {
+ large: css({}),
+ medium: css({
+ width: '64px',
+ height: '34px',
+ }),
+ },
+ };
+
+ return style[variant][size];
+};
+
+export const buttonStyling = css({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ border: 'none',
+ whiteSpace: 'nowrap',
+ cursor: 'pointer',
+});
diff --git a/src/components/mobile/atoms/Button/Button.tsx b/src/components/mobile/atoms/Button/Button.tsx
new file mode 100644
index 00000000..097dde0e
--- /dev/null
+++ b/src/components/mobile/atoms/Button/Button.tsx
@@ -0,0 +1,35 @@
+import React, { forwardRef } from 'react';
+import type { ComponentPropsWithRef, ForwardedRef } from 'react';
+import * as S from './Button.style';
+
+export interface ButtonProps extends ComponentPropsWithRef<'button'> {
+ size?: 'large' | 'medium';
+ variant?: 'primary' | 'roundPrimary' | 'Primary2' | 'outlineShadow';
+ active?: boolean;
+}
+
+const Button = (
+ {
+ size = 'medium',
+ variant = 'primary',
+ active = true,
+ children,
+ ...attributes
+ }: ButtonProps,
+ ref: ForwardedRef,
+) => (
+
+);
+
+export default forwardRef(Button);
diff --git a/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.style.ts b/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.style.ts
new file mode 100644
index 00000000..85dfa057
--- /dev/null
+++ b/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.style.ts
@@ -0,0 +1,10 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const buttonStyle = css(typo.Comment.SemiBold, {
+ outline: 'none',
+ color: color.MAIN,
+ padding: '10px',
+ cursor: 'pointer',
+});
diff --git a/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.tsx b/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.tsx
new file mode 100644
index 00000000..75a6ed8d
--- /dev/null
+++ b/src/components/mobile/atoms/DraftSaveButton/DraftSaveButton.tsx
@@ -0,0 +1,15 @@
+import React from 'react';
+import * as S from './DraftSaveButton.style';
+
+interface DraftSaveButtonProps {
+ onClick: () => void;
+}
+
+const DraftSaveButton = ({ onClick }: DraftSaveButtonProps) => {
+ return (
+
+ );
+};
+export default DraftSaveButton;
diff --git a/src/components/mobile/atoms/FloatingButton/FloatingButton.style.ts b/src/components/mobile/atoms/FloatingButton/FloatingButton.style.ts
new file mode 100644
index 00000000..22c4908c
--- /dev/null
+++ b/src/components/mobile/atoms/FloatingButton/FloatingButton.style.ts
@@ -0,0 +1,31 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const categoryButtonBaseStyle = (imageType: 'talkpick' | 'game') =>
+ css({
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'center',
+ gap: '13px',
+ padding: '5px 5px 5px 21px',
+ borderRadius: '500px',
+ backgroundColor: color.WT,
+ boxShadow: '1px 2px 15px 0 rgba(119, 130, 255, 0.2)',
+ cursor: 'pointer',
+ transition: 'all 0.3s ease-in',
+ width: imageType === 'talkpick' ? '102px' : '139px',
+ marginLeft: imageType === 'talkpick' ? '37px' : 0,
+ '&:hover': {
+ boxShadow: '1px 2px 15px 0 rgba(119, 130, 255, 0.8)',
+ },
+ });
+
+export const imgWrap = css({
+ flexShrink: 0,
+});
+
+export const labelStyle = css(typo.Mobile.Text.SemiBold_14, {
+ color: color.MAIN,
+});
diff --git a/src/components/mobile/atoms/FloatingButton/FloatingButton.tsx b/src/components/mobile/atoms/FloatingButton/FloatingButton.tsx
new file mode 100644
index 00000000..0deeb216
--- /dev/null
+++ b/src/components/mobile/atoms/FloatingButton/FloatingButton.tsx
@@ -0,0 +1,42 @@
+import React, { ComponentPropsWithRef } from 'react';
+import { CircleGame, CircleTalkPick } from '@/assets';
+import * as S from './FloatingButton.style';
+
+interface FloatingButtonProps extends ComponentPropsWithRef<'button'> {
+ imageType: 'talkpick' | 'game';
+ label: string;
+ onClick?: () => void;
+}
+
+const FloatingButton = ({
+ imageType,
+ label,
+ onClick,
+ ...attributes
+}: FloatingButtonProps) => {
+ let ImageComponent;
+ switch (imageType) {
+ case 'talkpick':
+ ImageComponent = CircleTalkPick;
+ break;
+ case 'game':
+ ImageComponent = CircleGame;
+ break;
+ default:
+ return null;
+ }
+
+ return (
+
+ );
+};
+
+export default FloatingButton;
diff --git a/src/components/mobile/atoms/GameStageLabel/GameStageLabel.style.ts b/src/components/mobile/atoms/GameStageLabel/GameStageLabel.style.ts
new file mode 100644
index 00000000..dc346252
--- /dev/null
+++ b/src/components/mobile/atoms/GameStageLabel/GameStageLabel.style.ts
@@ -0,0 +1,9 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const getStageLabelColor = (labelColor: string) => {
+ return css(typo.Mobile.Text.SemiBold_14, {
+ color: labelColor === 'main' ? color.MAIN : color.GY[1],
+ });
+};
diff --git a/src/components/mobile/atoms/GameStageLabel/GameStageLabel.tsx b/src/components/mobile/atoms/GameStageLabel/GameStageLabel.tsx
new file mode 100644
index 00000000..93b27aa4
--- /dev/null
+++ b/src/components/mobile/atoms/GameStageLabel/GameStageLabel.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import * as S from './GameStageLabel.style';
+
+export interface GameStageLabelProps {
+ stage: number;
+ color?: 'main' | 'default';
+}
+
+const GameStageLabel = ({ stage, color = 'default' }: GameStageLabelProps) => (
+ {stage + 1} / 10
+);
+
+export default GameStageLabel;
diff --git a/src/components/mobile/atoms/GameTag/GameTag.style.ts b/src/components/mobile/atoms/GameTag/GameTag.style.ts
new file mode 100644
index 00000000..affcea54
--- /dev/null
+++ b/src/components/mobile/atoms/GameTag/GameTag.style.ts
@@ -0,0 +1,8 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const tagStyle = css(typo.Mobile.Text.SemiBold_20, {
+ color: color.MAIN,
+ gap: '5px',
+});
diff --git a/src/components/mobile/atoms/GameTag/GameTag.tsx b/src/components/mobile/atoms/GameTag/GameTag.tsx
new file mode 100644
index 00000000..4793e628
--- /dev/null
+++ b/src/components/mobile/atoms/GameTag/GameTag.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import * as S from './GameTag.style';
+
+export interface GameTagProps {
+ tag: string;
+}
+
+const GameTag = ({ tag }: GameTagProps) => (
+
+ # {tag}
+
+);
+
+export default GameTag;
diff --git a/src/components/mobile/atoms/GameTagChip/GameTagChip.style.ts b/src/components/mobile/atoms/GameTagChip/GameTagChip.style.ts
new file mode 100644
index 00000000..f6d9cd0c
--- /dev/null
+++ b/src/components/mobile/atoms/GameTagChip/GameTagChip.style.ts
@@ -0,0 +1,15 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const tagStyle = css(typo.Mobile.Text.Medium_12, {
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: '6px 14px',
+ borderRadius: '6px',
+ border: `1px solid ${color.WT_VIOLET}`,
+ color: color.MAIN,
+ fontSize: '14px',
+ gap: '5px',
+});
diff --git a/src/components/mobile/atoms/GameTagChip/GameTagChip.tsx b/src/components/mobile/atoms/GameTagChip/GameTagChip.tsx
new file mode 100644
index 00000000..9a8f991b
--- /dev/null
+++ b/src/components/mobile/atoms/GameTagChip/GameTagChip.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import * as S from './GameTagChip.style';
+
+export interface GameTagChipProps {
+ tag: string;
+}
+
+const GameTagChip = ({ tag }: GameTagChipProps) => (
+
+ #{tag}
+
+);
+
+export default GameTagChip;
diff --git a/src/components/mobile/atoms/IconButton/IconButton.style.ts b/src/components/mobile/atoms/IconButton/IconButton.style.ts
new file mode 100644
index 00000000..6bcfb6f1
--- /dev/null
+++ b/src/components/mobile/atoms/IconButton/IconButton.style.ts
@@ -0,0 +1,14 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+
+export const buttonStyle = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: ' center',
+ width: '54px',
+ height: '34px',
+ border: `1px solid ${color.GY[3]}`,
+ borderRadius: '4px',
+ cursor: 'pointer',
+});
diff --git a/src/components/mobile/atoms/IconButton/IconButton.tsx b/src/components/mobile/atoms/IconButton/IconButton.tsx
new file mode 100644
index 00000000..800a7b3d
--- /dev/null
+++ b/src/components/mobile/atoms/IconButton/IconButton.tsx
@@ -0,0 +1,23 @@
+import React, {
+ ComponentPropsWithoutRef,
+ ForwardedRef,
+ forwardRef,
+} from 'react';
+import * as S from './IconButton.style';
+
+interface IconButtonProps extends ComponentPropsWithoutRef<'button'> {
+ icon: React.ReactNode;
+}
+
+const IconButton = (
+ { icon, onClick, ...props }: IconButtonProps,
+ ref: ForwardedRef,
+) => {
+ return (
+
+ );
+};
+
+export default forwardRef(IconButton);
diff --git a/src/components/mobile/atoms/InteractionButton/InteractionButton.style.ts b/src/components/mobile/atoms/InteractionButton/InteractionButton.style.ts
new file mode 100644
index 00000000..486cf187
--- /dev/null
+++ b/src/components/mobile/atoms/InteractionButton/InteractionButton.style.ts
@@ -0,0 +1,46 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const buttonStyle = css({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '163px',
+ height: '58px',
+ borderRadius: '12px',
+ border: `1px solid ${color.GY[2]}`,
+ boxShadow: '1px 1px 4px rgba(0, 0, 0, 0.15)',
+ cursor: 'pointer',
+});
+
+export const itemWrapper = css({
+ display: 'flex',
+ flexDirection: 'column',
+ paddingTop: '10px',
+ gap: '3px',
+});
+
+export const buttonLabelStyle = css(typo.Mobile.Text.Medium_12, {
+ color: color.MAIN,
+ fontSize: '11px',
+ fontWeight: '700',
+});
+
+export const iconWrapper = css({
+ display: 'flex',
+ justifyContent: 'center',
+ gap: '3px',
+});
+
+export const iconStyle = css({
+ width: '24px',
+ height: '24px',
+ flexShrink: '0',
+});
+
+export const iconLabelStyle = css(typo.Mobile.Text.Medium_12, {
+ color: color.GY[1],
+ fontWeight: '600',
+});
diff --git a/src/components/mobile/atoms/InteractionButton/InteractionButton.tsx b/src/components/mobile/atoms/InteractionButton/InteractionButton.tsx
new file mode 100644
index 00000000..c359cd7c
--- /dev/null
+++ b/src/components/mobile/atoms/InteractionButton/InteractionButton.tsx
@@ -0,0 +1,31 @@
+import React, {
+ ComponentPropsWithoutRef,
+ ForwardedRef,
+ forwardRef,
+} from 'react';
+import * as S from './InteractionButton.style';
+
+interface InteractionButtonProps extends ComponentPropsWithoutRef<'button'> {
+ buttonLabel: string;
+ icon: React.ReactNode;
+ iconLabel: string;
+}
+
+const InteractionButton = (
+ { buttonLabel, icon, iconLabel, ...props }: InteractionButtonProps,
+ ref: ForwardedRef,
+) => {
+ return (
+
+ );
+};
+
+export default forwardRef(InteractionButton);
diff --git a/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.style.ts b/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.style.ts
new file mode 100644
index 00000000..ab768501
--- /dev/null
+++ b/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.style.ts
@@ -0,0 +1,36 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const buttonGroupStyle = css({
+ position: 'fixed',
+ top: '55px',
+ right: 0,
+ width: '134px',
+ height: '100%',
+ backgroundColor: color.WT,
+ boxShadow: '0px 0 5px rgba(0, 0, 0, 0.1)',
+ zIndex: 1100,
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+});
+
+export const buttonContainerStyle = css({
+ display: 'flex',
+ flexDirection: 'column',
+});
+
+export const fillerStyle = css({
+ flex: 1,
+});
+
+export const buttonStyle = css(typo.Mobile.Text.Medium_12, {
+ outline: 'none',
+ cursor: 'pointer',
+ backgroundColor: 'transparent',
+ padding: '10.5px 60px 10.5px 24px',
+ textAlign: 'left',
+ color: color.BK,
+ border: 'none',
+});
diff --git a/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.tsx b/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.tsx
new file mode 100644
index 00000000..3336354a
--- /dev/null
+++ b/src/components/mobile/atoms/MobileSideMenu/MobileSideMenu.tsx
@@ -0,0 +1,71 @@
+import React from 'react';
+import { useNavigate } from 'react-router-dom';
+import * as S from './MobileSideMenu.style';
+
+interface MobileSideMenuProps {
+ isOpen: boolean;
+ accessToken: string | null;
+ handleLoginButton: () => void;
+ setIsOpen: (isOpen: boolean) => void;
+}
+
+const MobileSideMenu = ({
+ isOpen,
+ accessToken,
+ handleLoginButton,
+ setIsOpen,
+}: MobileSideMenuProps) => {
+ const navigate = useNavigate();
+
+ const handleNavigation = (path: string) => {
+ setIsOpen(false);
+ navigate(path);
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
+
+
+
+ {accessToken && (
+
+ )}
+
+
+
+ );
+};
+
+export default MobileSideMenu;
diff --git a/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.style.ts b/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.style.ts
new file mode 100644
index 00000000..e7a7f424
--- /dev/null
+++ b/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.style.ts
@@ -0,0 +1,33 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const toggleGroupStyle = css({
+ display: 'flex',
+ flexDirection: 'column',
+});
+
+export const clickedToggleStyle = (isOpen: boolean) =>
+ css(typo.Mobile.Text.SemiBold_12, {
+ color: color.MAIN,
+ backgroundColor: color.WT_VIOLET,
+ display: 'flex',
+ alignItems: 'center',
+ gap: '8px',
+ padding: '4px 8px 4px 9px',
+ borderBottom: isOpen ? `0.6px solid ${color.SKYBLUE}` : undefined,
+ borderRadius: isOpen ? undefined : '6px',
+ cursor: 'pointer',
+ });
+
+export const unClickedToggleStyle = css(typo.Mobile.Text.SemiBold_12, {
+ color: color.GY[1],
+ backgroundColor: color.WT,
+ padding: '4px 26px 4px 9px',
+ transition: 'all .1s ease-in',
+ borderRadius: '0 0 6px 6px',
+ cursor: 'pointer',
+ '&:hover': {
+ backgroundColor: color.WT_VIOLET,
+ },
+});
diff --git a/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.tsx b/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.tsx
new file mode 100644
index 00000000..194e5f69
--- /dev/null
+++ b/src/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup.tsx
@@ -0,0 +1,76 @@
+import React, { useState, useEffect } from 'react';
+import { TriangleDown, TriangleUp } from '@/assets';
+import {
+ ToggleGroupItem,
+ ToggleGroupProps,
+ ToggleGroupValue,
+} from '@/types/toggle';
+import * as S from './MobileToggleGroup.style';
+
+const defaultItems: ToggleGroupItem[] = [
+ {
+ label: 'μΈκΈ°μ',
+ value: { field: 'views', order: 'desc' },
+ },
+ {
+ label: 'μ΅μ μ',
+ value: { field: 'createdAt', order: 'desc' },
+ },
+];
+
+const MobileToggleGroup = ({
+ items = defaultItems,
+ selectedValue,
+ onClick,
+}: ToggleGroupProps) => {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const handleMenuClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ setIsOpen(!isOpen);
+ };
+
+ const handleOutsideClick = () => {
+ setIsOpen(false);
+ };
+
+ const handleToggleClick = (value: ToggleGroupValue) => {
+ onClick?.(value);
+ setIsOpen(false);
+ };
+
+ useEffect(() => {
+ window.addEventListener('click', handleOutsideClick);
+ return () => {
+ window.removeEventListener('click', handleOutsideClick);
+ };
+ }, []);
+
+ const isSelectedViews = selectedValue?.field === 'views';
+
+ return (
+
+
+ {isOpen && (
+
+ )}
+
+ );
+};
+
+export default MobileToggleGroup;
diff --git a/src/components/mobile/atoms/Modal/Modal.style.ts b/src/components/mobile/atoms/Modal/Modal.style.ts
new file mode 100644
index 00000000..477f5393
--- /dev/null
+++ b/src/components/mobile/atoms/Modal/Modal.style.ts
@@ -0,0 +1,46 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import type { ModalProps } from './Modal';
+
+export const modalStyling = css({
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ position: 'relative',
+ width: '335px',
+ backgroundColor: color.WT,
+ borderRadius: '12px',
+ boxShadow: '1px 2px 30px rgba(0, 0, 0, 0.15)',
+});
+
+export const getModalSize = (action: Required['action']) => {
+ const style = {
+ share: css({
+ paddingTop: '24px',
+ paddingLeft: '20px',
+ paddingRight: '20px',
+ paddingBottom: '26px',
+ }),
+ tag: css({
+ paddingTop: '24px',
+ paddingLeft: '20px',
+ paddingRight: '20px',
+ paddingBottom: '30px',
+ }),
+ tempGame: css({
+ paddingTop: '24px',
+ paddingLeft: '20px',
+ paddingRight: '20px',
+ paddingBottom: '24px',
+ }),
+ };
+
+ return style[action];
+};
+
+export const modalCloseStyling = css({
+ position: 'absolute',
+ top: '24px',
+ right: '20px',
+ cursor: 'pointer',
+});
diff --git a/src/components/mobile/atoms/Modal/Modal.tsx b/src/components/mobile/atoms/Modal/Modal.tsx
new file mode 100644
index 00000000..f02b0b87
--- /dev/null
+++ b/src/components/mobile/atoms/Modal/Modal.tsx
@@ -0,0 +1,40 @@
+/* eslint-disable react-hooks/exhaustive-deps */
+import React, { useRef, ReactNode } from 'react';
+import { MobileModalClose } from '@/assets';
+import useOutsideClick from '@/hooks/common/useOutsideClick';
+import * as S from './Modal.style';
+
+export interface ModalProps {
+ action?: 'share' | 'tag' | 'tempGame';
+ isOpen?: boolean;
+ onClose?: () => void;
+ hasCloseButton?: boolean;
+ children?: ReactNode;
+}
+
+const Modal = ({
+ isOpen,
+ onClose,
+ action = 'share',
+ hasCloseButton = true,
+ children,
+}: ModalProps) => {
+ const modalRef = useRef(null);
+
+ useOutsideClick(modalRef, () => onClose?.());
+
+ return (
+
+ {isOpen && (
+
+ {hasCloseButton && (
+
+ )}
+ {children}
+
+ )}
+
+ );
+};
+
+export default Modal;
diff --git a/src/components/mobile/atoms/TempGameButton/TempGameButton.style.ts b/src/components/mobile/atoms/TempGameButton/TempGameButton.style.ts
new file mode 100644
index 00000000..c7df6486
--- /dev/null
+++ b/src/components/mobile/atoms/TempGameButton/TempGameButton.style.ts
@@ -0,0 +1,35 @@
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+import { css } from '@emotion/react';
+
+export const tempGameButtonStyling = css({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'flex-end',
+ padding: '10px',
+ width: '142px',
+ height: '136px',
+ backgroundColor: color.WT,
+ borderRadius: '10px',
+ border: `1px solid ${color.GY[3]}`,
+ boxShadow: '1px 2px 15px rgba(0, 0, 0, 0.05)',
+ cursor: 'pointer',
+});
+
+export const itemWrapper = css({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'space-between',
+ height: '95px',
+});
+
+export const buttonStyling = css(typo.Mobile.Text.SemiBold_14, {
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '122px',
+ height: '34px',
+ borderRadius: '8px',
+ backgroundColor: color.WT_VIOLET,
+ color: color.MAIN,
+});
diff --git a/src/components/mobile/atoms/TempGameButton/TempGameButton.tsx b/src/components/mobile/atoms/TempGameButton/TempGameButton.tsx
new file mode 100644
index 00000000..58484fca
--- /dev/null
+++ b/src/components/mobile/atoms/TempGameButton/TempGameButton.tsx
@@ -0,0 +1,24 @@
+import React, { forwardRef } from 'react';
+import type { ComponentPropsWithRef, ForwardedRef } from 'react';
+import { MobileFolder, MobileFolderCheck } from '@/assets';
+import * as S from './TempGameButton.style';
+
+export interface ButtonProps extends ComponentPropsWithRef<'button'> {
+ action?: 'save' | 'get';
+}
+
+const TempGameButton = (
+ { action = 'save', ...attributes }: ButtonProps,
+ ref: ForwardedRef,
+) => (
+
+);
+
+export default forwardRef(TempGameButton);
diff --git a/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.style.ts b/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.style.ts
new file mode 100644
index 00000000..0da97878
--- /dev/null
+++ b/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.style.ts
@@ -0,0 +1,35 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const fieldStyling = css({
+ display: 'flex',
+ flexDirection: 'column',
+ width: '375px',
+ padding: '12px 20px',
+});
+
+export const dividerWrapper = css({
+ margin: '12px 0',
+});
+
+export const titleStyling = css(typo.Mobile.Main.Medium_16, {
+ width: '100%',
+ color: color.BK,
+
+ '::placeholder': {
+ color: color.GY[1],
+ },
+});
+
+export const descriptionStyling = css(typo.Mobile.Text.Medium_12, {
+ fontSize: '14px',
+ width: '100%',
+ height: '200px',
+ resize: 'none',
+ color: color.BK,
+
+ '::placeholder': {
+ color: color.GY[1],
+ },
+});
diff --git a/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.tsx b/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.tsx
new file mode 100644
index 00000000..864bc54c
--- /dev/null
+++ b/src/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField.tsx
@@ -0,0 +1,61 @@
+import React, { ForwardedRef, forwardRef, useRef } from 'react';
+import Divider from '@/components/atoms/Divider/Divider';
+import * as S from './TitleDescriptionField.style';
+
+export interface TitleDescriptionFieldProps {
+ title: string;
+ description?: string;
+ onTitleChange: (e: React.ChangeEvent) => void;
+ onDescriptionChange?: (e: React.ChangeEvent) => void;
+}
+
+const TitleDescriptionField = (
+ {
+ title,
+ description,
+ onTitleChange,
+ onDescriptionChange,
+ }: TitleDescriptionFieldProps,
+ ref: ForwardedRef,
+) => {
+ const descriptionRef = useRef(null);
+
+ const handleTitleChange = (e: React.ChangeEvent) => {
+ if (e.target.value.length <= 100) {
+ onTitleChange(e);
+ }
+ };
+
+ const handleDescriptionChange = (
+ e: React.ChangeEvent,
+ ) => {
+ if (onDescriptionChange && e.target.value.length <= 30) {
+ onDescriptionChange(e);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default forwardRef(TitleDescriptionField);
diff --git a/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.style.ts b/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.style.ts
new file mode 100644
index 00000000..a9853eaa
--- /dev/null
+++ b/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.style.ts
@@ -0,0 +1,39 @@
+import { css } from '@emotion/react';
+
+export const overlay = css({
+ position: 'fixed',
+ top: 0,
+ left: 0,
+ width: '100vw',
+ height: '100vh',
+ backgroundColor: 'rgba(255, 255, 255, 0.5)',
+ zIndex: 10,
+});
+
+export const dropdownStyling = css({
+ display: 'flex',
+ flexDirection: 'column',
+ position: 'relative',
+ zIndex: 20,
+});
+
+export const ButtonWrapper = css({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'flex-end',
+ gap: '10px',
+ position: 'absolute',
+ bottom: '70px',
+ right: 0,
+ zIndex: 20,
+});
+
+export const dropdownButtonStyling = css({
+ cursor: 'pointer',
+ zIndex: 20,
+ width: '50px',
+ height: '50px',
+ position: 'absolute',
+ bottom: '10px',
+ right: '20px',
+});
diff --git a/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.tsx b/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.tsx
new file mode 100644
index 00000000..ffe85b4d
--- /dev/null
+++ b/src/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton.tsx
@@ -0,0 +1,78 @@
+/* eslint-disable jsx-a11y/click-events-have-key-events */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import { CircleClose, CirclePencil } from '@/assets';
+import FloatingButton from '@/components/mobile/atoms/FloatingButton/FloatingButton';
+import { PATH } from '@/constants/path';
+import React, { useEffect, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { useNewSelector } from '@/store';
+import { selectAccessToken } from '@/store/auth';
+import * as S from './FloatingMenuButton.style';
+
+const FloatingMenuButton = () => {
+ const navigate = useNavigate();
+ const accessToken = useNewSelector(selectAccessToken);
+ const [isOpen, setIsOpen] = useState(false);
+
+ const handleCreatePostButton = () => {
+ if (accessToken) {
+ navigate(PATH.CREATE.TALK_PICK);
+ } else {
+ navigate(PATH.LOGIN);
+ }
+ };
+
+ const handleCreateGameButton = () => {
+ if (accessToken) {
+ navigate(PATH.CREATE.GAME);
+ } else {
+ navigate(PATH.LOGIN);
+ }
+ };
+
+ const handleMenuClick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ setIsOpen(!isOpen);
+ };
+
+ const handleOutsideClick = () => {
+ setIsOpen(false);
+ };
+
+ useEffect(() => {
+ window.addEventListener('click', handleOutsideClick);
+ return () => {
+ window.removeEventListener('click', handleOutsideClick);
+ };
+ }, []);
+ return (
+
+ {isOpen && (
+
+ )}
+ {isOpen && (
+
+
+
+
+ )}
+
+
+ );
+};
+export default FloatingMenuButton;
diff --git a/src/components/mobile/molecules/GameTagModal/GameTagModal.style.ts b/src/components/mobile/molecules/GameTagModal/GameTagModal.style.ts
new file mode 100644
index 00000000..b0e3845d
--- /dev/null
+++ b/src/components/mobile/molecules/GameTagModal/GameTagModal.style.ts
@@ -0,0 +1,81 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const contentWrapper = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ gap: '20px',
+});
+
+export const textBox = css({
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ gap: '3px',
+});
+
+export const textStyling = css(typo.Main.SemiBold, {
+ color: color.BK,
+});
+
+export const tagTextStyling = css(typo.Mobile.Text.SemiBold_14, {
+ color: color.GY[1],
+});
+
+export const markStyling = css(typo.Mobile.Text.SemiBold_14, {
+ color: color.MAIN,
+});
+
+export const tagWrapper = css({
+ width: '100%',
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '6px',
+});
+
+export const buttonWrapper = css({
+ display: 'flex',
+ gap: '8px',
+});
+
+export const inputStyling = css(typo.Mobile.Text.Medium_12, {
+ fontSize: '14px',
+ width: '295px',
+ height: '42px',
+ padding: '10px 20px',
+ border: `1px solid ${color.GY[4]}`,
+ borderRadius: '6px',
+});
+
+export const customButtonStyle = (isDisabled: boolean) =>
+ css({
+ cursor: isDisabled ? 'not-allowed' : 'pointer',
+ });
+
+export const customDisabledBtnStyle = css({
+ color: color.WT,
+ backgroundColor: color.GY[2],
+ outline: '1px solid transparent',
+ pointerEvents: 'none',
+ ':hover': {
+ backgroundColor: color.GY[2],
+ },
+});
+
+export const getButtonStyling = (isSelected: boolean) => {
+ return css({
+ display: 'flex',
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '64px',
+ height: '34px',
+ borderRadius: '6px',
+ border: isSelected ? 'null' : `1px solid ${color.GY[4]}`,
+ backgroundColor: isSelected ? color.MAIN : color.GY[5],
+ color: isSelected ? color.WT : color.GY[1],
+ cursor: 'pointer',
+ });
+};
diff --git a/src/components/mobile/molecules/GameTagModal/GameTagModal.tsx b/src/components/mobile/molecules/GameTagModal/GameTagModal.tsx
new file mode 100644
index 00000000..0f849409
--- /dev/null
+++ b/src/components/mobile/molecules/GameTagModal/GameTagModal.tsx
@@ -0,0 +1,85 @@
+import React, { useState } from 'react';
+import { MobileCheckIcon } from '@/assets';
+import Modal from '@/components/mobile/atoms/Modal/Modal';
+import Button from '@/components/mobile/atoms/Button/Button';
+import Divider from '@/components/atoms/Divider/Divider';
+import * as S from './GameTagModal.style';
+
+interface GameTagModalProps {
+ isOpen?: boolean;
+ onClose?: () => void;
+ onTagSubmit: (mainTag: string, subTag: string) => void;
+}
+
+const GameTagModal = ({ isOpen, onClose, onTagSubmit }: GameTagModalProps) => {
+ const [mainTag, setMainTag] = useState<'컀ν' | 'μ·¨ν₯' | 'κΈ°ν' | null>(null);
+ const [subTag, setSubTag] = useState('');
+
+ const handleTagSubmit = () => {
+ if (mainTag) {
+ onTagSubmit(mainTag, subTag);
+ onClose?.();
+ }
+ };
+
+ return (
+
+
+
+
λ°Έλ°μ€κ²μ νκ·Έλ₯Ό μ νν΄μ£ΌμΈμ!
+
+
+
+ λ©μΈνκ·Έ
+ *
+
+
+
+
+
+
+
+
+
+ μλΈνκ·Έ
+
+
setSubTag(e.target.value)}
+ />
+
+
+
+
+ );
+};
+
+export default GameTagModal;
diff --git a/src/components/mobile/molecules/ShareModal/ShareModal.style.ts b/src/components/mobile/molecules/ShareModal/ShareModal.style.ts
new file mode 100644
index 00000000..b4f08219
--- /dev/null
+++ b/src/components/mobile/molecules/ShareModal/ShareModal.style.ts
@@ -0,0 +1,19 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const shareModalStyling = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+});
+
+export const textStyling = css(typo.Comment.SemiBold, {
+ marginTop: '24px',
+ marginBottom: '23px',
+ color: color.BK,
+});
+
+export const shareTextStyling = css(typo.Comment.SemiBold, {
+ color: color.MAIN,
+});
diff --git a/src/components/mobile/molecules/ShareModal/ShareModal.tsx b/src/components/mobile/molecules/ShareModal/ShareModal.tsx
new file mode 100644
index 00000000..9968e7be
--- /dev/null
+++ b/src/components/mobile/molecules/ShareModal/ShareModal.tsx
@@ -0,0 +1,27 @@
+import React from 'react';
+import Button from '@/components/mobile/atoms/Button/Button';
+import Modal from '@/components/mobile/atoms/Modal/Modal';
+import * as S from './ShareModal.style';
+
+export interface ShareModalProps {
+ isOpen?: boolean;
+ onConfirm?: () => void;
+ onClose?: () => void;
+}
+
+const ShareModal = ({ isOpen, onConfirm, onClose }: ShareModalProps) => {
+ return (
+
+
+
+ μΉ΄μΉ΄μ€ν‘μΌλ‘ 곡μ νμκ² μ΅λκΉ?
+
+
+
+
+ );
+};
+
+export default ShareModal;
diff --git a/src/components/mobile/molecules/TempGameModal/TempGameModal.style.ts b/src/components/mobile/molecules/TempGameModal/TempGameModal.style.ts
new file mode 100644
index 00000000..7e18b461
--- /dev/null
+++ b/src/components/mobile/molecules/TempGameModal/TempGameModal.style.ts
@@ -0,0 +1,21 @@
+import { css } from '@emotion/react';
+import color from '@/styles/color';
+import typo from '@/styles/typo';
+
+export const tempGameModalStyling = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ gap: '10px',
+});
+
+export const textStyling = css(typo.Main.SemiBold, {
+ color: color.BK,
+});
+
+export const buttonWrapper = css({
+ display: 'flex',
+ flexDirection: 'row',
+ gap: '11px',
+ marginTop: '5px',
+});
diff --git a/src/components/mobile/molecules/TempGameModal/TempGameModal.tsx b/src/components/mobile/molecules/TempGameModal/TempGameModal.tsx
new file mode 100644
index 00000000..4bb9ecff
--- /dev/null
+++ b/src/components/mobile/molecules/TempGameModal/TempGameModal.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { MobileTempIcon } from '@/assets';
+import Modal from '@/components/mobile/atoms/Modal/Modal';
+import TempGameButton from '@/components/mobile/atoms/TempGameButton/TempGameButton';
+import * as S from './TempGameModal.style';
+
+export interface TempGameModalProps {
+ isOpen?: boolean;
+ onSaveGame: () => void;
+ onGetGame: () => void;
+ onClose?: () => void;
+}
+
+const TempGameModal = ({
+ isOpen,
+ onSaveGame,
+ onGetGame,
+ onClose,
+}: TempGameModalProps) => {
+ return (
+
+
+
+
μμ μ μ₯
+
+
+
+
+
+
+ );
+};
+
+export default TempGameModal;
diff --git a/src/components/molecules/ActionBox/ActionBox.tsx b/src/components/molecules/ActionBox/ActionBox.tsx
index 912bf620..0e7ec5ef 100644
--- a/src/components/molecules/ActionBox/ActionBox.tsx
+++ b/src/components/molecules/ActionBox/ActionBox.tsx
@@ -1,12 +1,19 @@
import React, { useState } from 'react';
import ActionButton from '@/components/atoms/ActionButton/ActionButton';
+import { useNavigate } from 'react-router-dom';
+import { PATH } from '@/constants/path';
import { actionBoxContainer } from './ActionBox.style';
const ActionBox = () => {
+ const navigate = useNavigate();
const [activeButton, setActiveButton] = useState('activity');
const handleButtonClick = (buttonType: string) => {
setActiveButton(buttonType);
+
+ if (buttonType === 'edit') {
+ navigate(PATH.CHANGE.PROFILE);
+ }
};
return (
diff --git a/src/components/molecules/CategoryBar/CategoryBar.style.ts b/src/components/molecules/CategoryBar/CategoryBar.style.ts
index 28d3f041..92deec91 100644
--- a/src/components/molecules/CategoryBar/CategoryBar.style.ts
+++ b/src/components/molecules/CategoryBar/CategoryBar.style.ts
@@ -4,4 +4,7 @@ export const containerStyle = css({
display: 'flex',
alignItems: 'center',
padding: '20px 0',
+ '@media (max-width: 430px)': {
+ padding: 0,
+ },
});
diff --git a/src/components/molecules/CategoryBar/CategoryBar.tsx b/src/components/molecules/CategoryBar/CategoryBar.tsx
index 173afd46..be5ea076 100644
--- a/src/components/molecules/CategoryBar/CategoryBar.tsx
+++ b/src/components/molecules/CategoryBar/CategoryBar.tsx
@@ -1,5 +1,14 @@
import React from 'react';
-import { Popular, Couple, Taste, Worldcup } from '@/assets';
+import {
+ Popular,
+ Couple,
+ Taste,
+ Worldcup,
+ PopularSmall,
+ CoupleSmall,
+ TasteSmall,
+ WorldcupSmall,
+} from '@/assets';
import * as S from './CategoryBar.style';
import BalanceGameCategoryButton from '../../atoms/BalanceGameCategoryButton/BalanceGameCategoryButton';
@@ -8,9 +17,14 @@ export interface CategoryBarProps {
setActiveTab: React.Dispatch<
React.SetStateAction<'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅'>
>;
+ isMobile?: boolean;
}
-const CategoryBar = ({ activeTab, setActiveTab }: CategoryBarProps) => {
+const CategoryBar = ({
+ activeTab,
+ setActiveTab,
+ isMobile = false,
+}: CategoryBarProps) => {
const getBadgeText = (tab: 'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅') => {
switch (tab) {
case 'μΈκΈ°':
@@ -30,28 +44,28 @@ const CategoryBar = ({ activeTab, setActiveTab }: CategoryBarProps) => {
}
+ icon={isMobile ?
:
}
active={activeTab === 'μΈκΈ°'}
badgeText={getBadgeText('μΈκΈ°')}
onClick={() => setActiveTab('μΈκΈ°')}
/>
}
+ icon={isMobile ?
:
}
active={activeTab === '컀ν'}
badgeText={getBadgeText('컀ν')}
onClick={() => setActiveTab('컀ν')}
/>
}
+ icon={isMobile ?
:
}
active={activeTab === 'μ·¨ν₯'}
badgeText={getBadgeText('μ·¨ν₯')}
onClick={() => setActiveTab('μ·¨ν₯')}
/>
}
+ icon={isMobile ?
:
}
active={activeTab === 'μλμ»΅'}
badgeText={getBadgeText('μλμ»΅')}
onClick={() => setActiveTab('μλμ»΅')}
diff --git a/src/components/molecules/CategoryBox/CategoryBox.style.ts b/src/components/molecules/CategoryBox/CategoryBox.style.ts
index 8612c9e3..5ad9d638 100644
--- a/src/components/molecules/CategoryBox/CategoryBox.style.ts
+++ b/src/components/molecules/CategoryBox/CategoryBox.style.ts
@@ -2,5 +2,11 @@ import { css } from '@emotion/react';
export const categoryBoxStyling = css({
display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
gap: '20px',
+ width: '100%',
+ '@media (max-width: 430px)': {
+ gap: '7px',
+ },
});
diff --git a/src/components/molecules/CategoryBox/CategoryBox.tsx b/src/components/molecules/CategoryBox/CategoryBox.tsx
index 4212a8d4..41dfefdb 100644
--- a/src/components/molecules/CategoryBox/CategoryBox.tsx
+++ b/src/components/molecules/CategoryBox/CategoryBox.tsx
@@ -4,11 +4,24 @@ import CategoryButton from '@/components/atoms/CategoryButton/CategoryButton';
import { categoryBoxStyling } from './CategoryBox.style';
interface CategoryBoxProps {
+ isMobile?: boolean;
handleService: () => void;
}
-const CategoryBox = ({ handleService }: CategoryBoxProps) => {
- return (
+const CategoryBox = ({ handleService, isMobile = false }: CategoryBoxProps) => {
+ return isMobile ? (
+
+
+
+
+
+
+ ) : (
diff --git a/src/components/molecules/ContentsButton/ContentsButton.style.ts b/src/components/molecules/ContentsButton/ContentsButton.style.ts
index b80db34f..50a8539f 100644
--- a/src/components/molecules/ContentsButton/ContentsButton.style.ts
+++ b/src/components/molecules/ContentsButton/ContentsButton.style.ts
@@ -27,9 +27,17 @@ const sizeStyles = {
labelMaxWidth: '315px',
imageHeight: '183px',
},
+ extraSmall: {
+ width: '162px',
+ height: '121px',
+ infoHeight: '40px',
+ labelMaxWidth: '141px',
+ imageHeight: '81px',
+ },
};
export const cardWrapper = (size: SizeType) => css`
+ all: unset;
width: ${sizeStyles[size].width};
height: ${sizeStyles[size].height};
border-radius: 20px;
@@ -57,6 +65,14 @@ export const cardWrapper = (size: SizeType) => css`
transform: scale(1.05);
}
}
+ @media (max-width: 430px) {
+ border-radius: 10px;
+ }
+
+ &:focus-visible {
+ outline: 1px solid ${color.BK};
+ outline-offset: 1px;
+ }
`;
export const imageContainer = (size: SizeType) => css`
@@ -64,8 +80,6 @@ export const imageContainer = (size: SizeType) => css`
width: 100%;
height: ${sizeStyles[size].imageHeight};
overflow: hidden;
- border-top-left-radius: 20px;
- border-top-right-radius: 20px;
`;
export const imageWrapper = css`
@@ -97,12 +111,18 @@ export const infoContainer = (size: SizeType) => css`
display: flex;
justify-content: flex-start;
align-items: flex-start;
+ @media (max-width: 430px) {
+ padding: 10px;
+ }
`;
export const label = (size: SizeType, highlighted?: boolean) => css`
${typo.Component.Medium};
color: ${highlighted ? color.MAIN : color.BK};
max-width: ${sizeStyles[size].labelMaxWidth};
+ @media (max-width: 430px) {
+ ${typo.Mobile.Text.SemiBold_10};
+ }
`;
export const bookmarkWrapper = css`
diff --git a/src/components/molecules/ContentsButton/ContentsButton.tsx b/src/components/molecules/ContentsButton/ContentsButton.tsx
index 6c654b51..adc63cbb 100644
--- a/src/components/molecules/ContentsButton/ContentsButton.tsx
+++ b/src/components/molecules/ContentsButton/ContentsButton.tsx
@@ -4,15 +4,16 @@ import Bookmark, { BookmarkProps } from '@/components/atoms/Bookmark/Bookmark';
import { highlightText } from '@/utils/highlightText';
import * as S from './ContentsButton.style';
-export interface ContentsButtonProps extends ComponentPropsWithRef<'div'> {
+export interface ContentsButtonProps extends ComponentPropsWithRef<'button'> {
title: string;
mainTag: string;
subTag: string;
images: string[];
bookmarked?: BookmarkProps['bookmarked'];
showBookmark?: boolean;
- size?: 'large' | 'medium' | 'small';
+ size?: 'large' | 'medium' | 'small' | 'extraSmall';
keyword?: string;
+ onClick: () => void;
}
const ContentsButton = ({
@@ -24,10 +25,16 @@ const ContentsButton = ({
keyword,
bookmarked = false,
showBookmark = true,
+ onClick,
...attributes
}: ContentsButtonProps) => {
return (
-
+
);
};
diff --git a/src/components/molecules/InfoBox/InfoBox.style.ts b/src/components/molecules/InfoBox/InfoBox.style.ts
index 3f50a42f..879362a1 100644
--- a/src/components/molecules/InfoBox/InfoBox.style.ts
+++ b/src/components/molecules/InfoBox/InfoBox.style.ts
@@ -3,6 +3,7 @@ import color from '@/styles/color';
import typo from '@/styles/typo';
export const infoContainer = css`
+ all: unset;
display: flex;
width: 904px;
height: 84px;
@@ -15,6 +16,11 @@ export const infoContainer = css`
border-radius: 15px;
background-color: ${color.WT};
box-sizing: border-box;
+
+ &:focus-visible {
+ outline: 1px solid ${color.BK};
+ outline-offset: 1px;
+ }
`;
export const textContainer = css`
@@ -33,6 +39,7 @@ export const titleLabel = css`
${typo.Main.Medium_16};
color: ${color.BK};
margin: 0;
+ text-align: left;
`;
export const subtitleWrapper = css`
diff --git a/src/components/molecules/InfoBox/InfoBox.tsx b/src/components/molecules/InfoBox/InfoBox.tsx
index ad04d17d..9cc9b0ae 100644
--- a/src/components/molecules/InfoBox/InfoBox.tsx
+++ b/src/components/molecules/InfoBox/InfoBox.tsx
@@ -8,6 +8,7 @@ export interface InfoBoxProps {
commentContent: string;
commentCount: number;
bookmarks: number;
+ onClick: () => void;
}
const InfoBox = ({
title,
@@ -15,9 +16,10 @@ const InfoBox = ({
commentContent,
commentCount,
bookmarks,
+ onClick,
}: InfoBoxProps) => {
return (
-
+
+
);
};
diff --git a/src/components/molecules/MyContentBox/MyContentBox.style.ts b/src/components/molecules/MyContentBox/MyContentBox.style.ts
index 94932095..76431c6e 100644
--- a/src/components/molecules/MyContentBox/MyContentBox.style.ts
+++ b/src/components/molecules/MyContentBox/MyContentBox.style.ts
@@ -3,6 +3,7 @@ import color from '@/styles/color';
import typo from '@/styles/typo';
export const infoContainer = css`
+ all: unset;
display: flex;
width: 904px;
height: 61px;
@@ -15,6 +16,11 @@ export const infoContainer = css`
border-radius: 15px;
background-color: ${color.WT};
box-sizing: border-box;
+
+ &:focus-visible {
+ outline: 1px solid ${color.BK};
+ outline-offset: 1px;
+ }
`;
export const textContainer = css`
@@ -33,6 +39,7 @@ export const titleLabel = css`
${typo.Main.Medium_16};
color: ${color.BK};
margin: 0;
+ text-align: left;
`;
export const bookmarkWrapper = css`
diff --git a/src/components/molecules/MyContentBox/MyContentBox.tsx b/src/components/molecules/MyContentBox/MyContentBox.tsx
index c161b8cb..895f29c9 100644
--- a/src/components/molecules/MyContentBox/MyContentBox.tsx
+++ b/src/components/molecules/MyContentBox/MyContentBox.tsx
@@ -9,6 +9,7 @@ export interface MyContentBoxProps {
bookmarks: number;
showBookmark?: boolean;
bookmarked?: BookmarkProps['bookmarked'];
+ onClick: () => void;
}
const MyContentBox = ({
title,
@@ -16,9 +17,10 @@ const MyContentBox = ({
bookmarks,
showBookmark = false,
bookmarked = false,
+ onClick,
}: MyContentBoxProps) => {
return (
-
+
+
);
};
diff --git a/src/components/molecules/OptionSelector/OptionSelector.tsx b/src/components/molecules/OptionSelector/OptionSelector.tsx
index 30520928..1cfb4741 100644
--- a/src/components/molecules/OptionSelector/OptionSelector.tsx
+++ b/src/components/molecules/OptionSelector/OptionSelector.tsx
@@ -1,9 +1,9 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import Button from '@/components/atoms/Button/Button';
import * as S from './OptionSelector.style';
interface OptionSelectorProps {
- options: string[];
+ options: { label: string; value: string }[];
selectedOption?: string;
onSelect: (option: string) => void;
}
@@ -12,23 +12,31 @@ const OptionSelector = ({
selectedOption,
onSelect,
}: OptionSelectorProps) => {
- const [selected, setSelected] = useState(selectedOption || options[0]);
+ const [selected, setSelected] = useState(
+ selectedOption ?? options[0]?.value ?? '',
+ );
+
+ useEffect(() => {
+ if (selectedOption) {
+ setSelected(selectedOption);
+ }
+ }, [selectedOption]);
- const handleSelect = (option: string) => {
- setSelected(option);
- onSelect(option);
+ const handleSelect = (optionValue: string) => {
+ setSelected(optionValue);
+ onSelect(optionValue);
};
return (
- {options.map((option) => (
+ {options.map(({ label, value }) => (
))}
diff --git a/src/components/molecules/ReportModal/ReportModal.style.ts b/src/components/molecules/ReportModal/ReportModal.style.ts
index 375920ad..a431cffe 100644
--- a/src/components/molecules/ReportModal/ReportModal.style.ts
+++ b/src/components/molecules/ReportModal/ReportModal.style.ts
@@ -43,6 +43,6 @@ export const reportTextAreaStyling = css(typo.Comment.Regular, {
border: `1px solid ${color.GY[2]}`,
backgroundColor: color.WT,
boxShadow: '1px 2px 15px rgba(0, 0, 0, 0.05)',
- color: color.GY[4],
+ color: '#555555',
resize: 'none',
});
diff --git a/src/components/molecules/SearchGameList/SearchGameList.tsx b/src/components/molecules/SearchGameList/SearchGameList.tsx
index bcbeecc9..c80dd1be 100644
--- a/src/components/molecules/SearchGameList/SearchGameList.tsx
+++ b/src/components/molecules/SearchGameList/SearchGameList.tsx
@@ -1,23 +1,22 @@
import React from 'react';
-import ContentsButton, {
- ContentsButtonProps,
-} from '@/components/molecules/ContentsButton/ContentsButton';
+import { GameListItem } from '@/types/search';
+import ContentsButton from '@/components/molecules/ContentsButton/ContentsButton';
+import { PATH } from '@/constants/path';
+import { useNavigate } from 'react-router-dom';
import * as S from './SearchGameList.style';
-export type GameItem = Pick<
- ContentsButtonProps,
- 'title' | 'mainTag' | 'subTag' | 'images'
-> & {
- optionAImg?: string;
- optionBImg?: string;
-};
-
export interface SearchGameListProps {
- gameList: GameItem[];
+ gameList: GameListItem[];
keyword: string;
}
const SearchGameList = ({ gameList, keyword }: SearchGameListProps) => {
+ const navigate = useNavigate();
+
+ const handleItemClick = (gameId: number) => {
+ navigate(`/${PATH.BALANCEGAME(gameId)}`);
+ };
+
return (
{gameList.map((game) => (
@@ -30,6 +29,7 @@ const SearchGameList = ({ gameList, keyword }: SearchGameListProps) => {
showBookmark={false}
size="small"
keyword={keyword}
+ onClick={() => handleItemClick(game.gameSetId)}
/>
))}
diff --git a/src/components/molecules/SearchTagBar/SearchTagBar.tsx b/src/components/molecules/SearchTagBar/SearchTagBar.tsx
index 92f0629e..f301cce5 100644
--- a/src/components/molecules/SearchTagBar/SearchTagBar.tsx
+++ b/src/components/molecules/SearchTagBar/SearchTagBar.tsx
@@ -6,9 +6,10 @@ import * as S from './SearchTagBar.style';
interface SearchTagBarProps {
onSearch: (query: string) => void;
+ isMobile?: boolean;
}
-const SearchTagBar = ({ onSearch }: SearchTagBarProps) => {
+const SearchTagBar = ({ onSearch, isMobile = false }: SearchTagBarProps) => {
const [inputValue, setInputValue] = useState('');
const handleInputChange = (e: React.ChangeEvent
) => {
@@ -19,7 +20,14 @@ const SearchTagBar = ({ onSearch }: SearchTagBarProps) => {
onSearch(inputValue);
};
- return (
+ return isMobile ? (
+
+ ) : (
{
+ const navigate = useNavigate();
+
+ const handleTalkPickClick = (talkPickId: number) => {
+ navigate(`/${PATH.TALKPICK(talkPickId)}`);
+ };
+
return (
{searchTalkPickList.map((searchItem, idx) => (
@@ -24,6 +31,7 @@ const SearchTalkPickList = ({
content={searchItem.content}
firstImgUrl={searchItem.firstImgUrl}
keyword={keyword}
+ onClick={() => handleTalkPickClick(searchItem.id)}
/>
{idx < searchTalkPickList.length - 1 && (
diff --git a/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.style.ts b/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.style.ts
index 2b575492..9ebc7662 100644
--- a/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.style.ts
+++ b/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.style.ts
@@ -16,9 +16,15 @@ export const talkPickStyling = css({
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
cursor: 'pointer',
+ '@media (max-width: 430px)': {
+ height: '227px',
+ paddingTop: '31px',
+ paddingBottom: '48px',
+ },
});
-export const bannerChipStyling = css(typo.Main.SemiBold, {
+export const bannerChipStyling = css({
+ ...typo.Main.SemiBold,
display: 'flex',
width: '142px',
height: '38px',
@@ -28,9 +34,16 @@ export const bannerChipStyling = css(typo.Main.SemiBold, {
borderRadius: '24px',
backgroundColor: color.WT,
color: color.BK,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.SemiBold_7,
+ width: '53px',
+ height: '15px',
+ gap: '2px',
+ },
});
-export const bannerBtnStyling = css(typo.Main.Medium, {
+export const bannerBtnStyling = css({
+ ...typo.Main.Medium,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
@@ -39,11 +52,23 @@ export const bannerBtnStyling = css(typo.Main.Medium, {
borderRadius: '10px',
backgroundColor: color.MAIN,
color: color.WT,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.SemiBold_7,
+ width: '128px',
+ height: '25px',
+ borderRadius: '4px',
+ },
});
-export const talkPickTextStyling = css(typo.Title, {
+export const talkPickTextStyling = css({
+ ...typo.Title,
textAlign: 'center',
marginTop: '40px',
marginBottom: '70px',
color: color.WT,
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.Bold_16,
+ marginTop: '32px',
+ marginBottom: '35px',
+ },
});
diff --git a/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.tsx b/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.tsx
index c6f342f8..671fa9ef 100644
--- a/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.tsx
+++ b/src/components/molecules/TopBanner/TodayTalkPickBanner/TodayTalkPickBanner.tsx
@@ -2,7 +2,8 @@ import React from 'react';
import { PATH } from '@/constants/path';
import { useNavigate } from 'react-router-dom';
import { TodayTalkPick } from '@/types/talk-pick';
-import { Check } from '@/assets';
+import { Check, CheckSmall } from '@/assets';
+import useIsMobile from '@/hooks/common/useIsMobile';
import {
bannerBtnStyling,
bannerChipStyling,
@@ -16,7 +17,7 @@ interface TodayTalkPickBannerProps {
const TodayTalkPickBanner = ({ talkPick }: TodayTalkPickBannerProps) => {
const navigate = useNavigate();
-
+ const isMobile = useIsMobile();
const onClickBanner = () => {
navigate(`/${PATH.TODAY_TALKPICK}`, {
state: { talkPickId: talkPick?.id, isTodayTalkPick: true },
@@ -31,8 +32,8 @@ const TodayTalkPickBanner = ({ talkPick }: TodayTalkPickBannerProps) => {
onClick={onClickBanner}
>
-
- μ€λμ ν‘ ν½
+ {isMobile ? : }
+ μ€λμ ν‘ν½
{talkPick?.title}
diff --git a/src/components/molecules/TopBanner/TopBanner.style.ts b/src/components/molecules/TopBanner/TopBanner.style.ts
index 6a667102..c9d6eef1 100644
--- a/src/components/molecules/TopBanner/TopBanner.style.ts
+++ b/src/components/molecules/TopBanner/TopBanner.style.ts
@@ -5,6 +5,9 @@ export const bannerStyling = css({
width: '100%',
overflow: 'hidden',
position: 'relative',
+ '@media (max-width: 430px)': {
+ height: '227px',
+ },
});
export const getBannerMovement = (idx: number) =>
@@ -25,19 +28,35 @@ export const dotWrapperStyling = css({
bottom: '20px',
gap: '13px',
position: 'absolute',
+ '@media (max-width: 430px)': {
+ bottom: '14px',
+ gap: '5px',
+ },
});
export const dotStyling = css({
+ all: 'unset',
width: '10px',
height: '10px',
borderRadius: '50%',
- backgroundColor: color.GY[4],
+ backgroundColor: '#555555',
transition: '0.5s ease-in-out',
cursor: 'pointer',
+ display: 'inline-block',
+ '@media (max-width: 430px)': {
+ width: '4px',
+ height: '4px',
+ borderRadius: '50%',
+ },
});
export const activeDotStyling = css({
width: '79px',
borderRadius: '10px',
backgroundColor: color.GY[2],
+ '@media (max-width: 430px)': {
+ width: '32px',
+ height: '4px',
+ borderRadius: '5px',
+ },
});
diff --git a/src/components/molecules/VotePrototype/VotePrototype.style.ts b/src/components/molecules/VotePrototype/VotePrototype.style.ts
index 093393a7..5e8b48b5 100644
--- a/src/components/molecules/VotePrototype/VotePrototype.style.ts
+++ b/src/components/molecules/VotePrototype/VotePrototype.style.ts
@@ -39,12 +39,13 @@ export const loggedOutContainerStyling = css({
display: 'flex',
position: 'absolute',
top: '90px',
- left: '-100px',
+ left: '50%',
+ transform: 'translateX(-50%)',
width: '1215px',
height: '260px',
backdropFilter: 'blur(11px)',
backgroundColor: 'rgba(255, 255, 255, 0.01)',
- zIndex: 1,
+ zIndex: '1',
});
export const toastModalStyling = css({
diff --git a/src/components/molecules/VotePrototype/VotePrototype.tsx b/src/components/molecules/VotePrototype/VotePrototype.tsx
index 1bc360eb..fd7757ab 100644
--- a/src/components/molecules/VotePrototype/VotePrototype.tsx
+++ b/src/components/molecules/VotePrototype/VotePrototype.tsx
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { NOTICE } from '@/constants/message';
+import { PATH } from '@/constants/path';
import { VoteOption, MyVoteOption } from '@/types/vote';
import Button from '@/components/atoms/Button/Button';
import VoteBar from '@/components/atoms/VoteBar/VoteBar';
@@ -71,7 +72,7 @@ const VotePrototype: React.FC
= ({
localStorage.setItem(`talkpick_${talkPickId}`, voteOption);
showToastModal(NOTICE.REQUIRED.LOGIN, () => {
- navigate('/login', { state: { talkPickId } });
+ navigate(`/${PATH.LOGIN}`, { state: { talkPickId } });
});
}
};
diff --git a/src/components/organisms/BalanceGameCreation/BalanceGameCreation.style.ts b/src/components/organisms/BalanceGameCreation/BalanceGameCreation.style.ts
index 0aeecbc6..e5ac9231 100644
--- a/src/components/organisms/BalanceGameCreation/BalanceGameCreation.style.ts
+++ b/src/components/organisms/BalanceGameCreation/BalanceGameCreation.style.ts
@@ -29,3 +29,11 @@ export const navigationContainer = css({
width: '100%',
justifyContent: 'center',
});
+
+export const toastModalStyling = css({
+ position: 'fixed',
+ top: '110px',
+ left: '50%',
+ transform: 'translate(-50%)',
+ zIndex: '1000',
+});
diff --git a/src/components/organisms/BalanceGameCreation/BalanceGameCreation.tsx b/src/components/organisms/BalanceGameCreation/BalanceGameCreation.tsx
index 7193abf7..61a29dfd 100644
--- a/src/components/organisms/BalanceGameCreation/BalanceGameCreation.tsx
+++ b/src/components/organisms/BalanceGameCreation/BalanceGameCreation.tsx
@@ -5,7 +5,8 @@ import DraftPostButton from '@/components/atoms/DraftPostButton/DraftPostButton'
import { BalanceGameSet } from '@/types/game';
import { useBalanceGameCreation } from '@/hooks/game/useBalanceGameCreation';
import GameNavigationSection from '@/components/molecules/GameNavigationSection/GameNavigationSection';
-import { useStageNavigation } from '@/hooks/game/useStageNavigation';
+import useToastModal from '@/hooks/modal/useToastModal';
+import ToastModal from '@/components/atoms/ToastModal/ToastModal';
import * as S from './BalanceGameCreation.style';
export interface BalanceGameCreationProps {
@@ -30,24 +31,23 @@ const BalanceGameCreation = ({
loadedGames,
}: BalanceGameCreationProps) => {
const totalStage = 10;
-
- const { currentStage, clearInput, handleNextStage, handlePrevStage } =
- useStageNavigation(totalStage);
+ const { isVisible, modalText, showToastModal } = useToastModal();
const {
games,
+ currentStage,
currentOptions,
currentDescription,
- handleOptionChange,
- handleDescriptionChange,
+ clearInput,
+ handleNextStage,
+ handlePrevStage,
handleStageDescriptionChange,
- } = useBalanceGameCreation(currentStage, loadedGames, totalStage);
+ handleOptionUpdate,
+ } = useBalanceGameCreation(showToastModal, totalStage, loadedGames);
useEffect(() => {
- if (currentOptions.length > 0) {
- onGamesUpdate(games);
- }
- }, [currentOptions, games, onGamesUpdate]);
+ onGamesUpdate(games);
+ }, [games, onGamesUpdate]);
return (
@@ -67,11 +67,12 @@ const BalanceGameCreation = ({
onImageDelete={() => onImageDelete(currentStage, 0)}
choiceInputProps={{
value: currentOptions[0]?.name || '',
- onChange: handleOptionChange('A'),
+ onChange: (e) => handleOptionUpdate('A', 'name', e.target.value),
}}
infoInputProps={{
value: currentOptions[0]?.description || '',
- onChange: (e) => handleDescriptionChange('A', e),
+ onChange: (e) =>
+ handleOptionUpdate('A', 'description', e.target.value),
}}
clearInput={clearInput}
/>
@@ -82,11 +83,12 @@ const BalanceGameCreation = ({
onImageDelete={() => onImageDelete(currentStage, 1)}
choiceInputProps={{
value: currentOptions[1]?.name || '',
- onChange: handleOptionChange('B'),
+ onChange: (e) => handleOptionUpdate('B', 'name', e.target.value),
}}
infoInputProps={{
value: currentOptions[1]?.description || '',
- onChange: (e) => handleDescriptionChange('B', e),
+ onChange: (e) =>
+ handleOptionUpdate('B', 'description', e.target.value),
}}
clearInput={clearInput}
/>
@@ -103,6 +105,9 @@ const BalanceGameCreation = ({
handleCompleteClick={handleCompleteClick}
/>
+
+ {isVisible && {modalText}}
+
);
};
diff --git a/src/components/organisms/BalanceGameList/BalanceGameList.style.ts b/src/components/organisms/BalanceGameList/BalanceGameList.style.ts
index 5207accf..4c3840ac 100644
--- a/src/components/organisms/BalanceGameList/BalanceGameList.style.ts
+++ b/src/components/organisms/BalanceGameList/BalanceGameList.style.ts
@@ -3,25 +3,44 @@ import typo from '@/styles/typo';
export const containerStyle = css({
width: '1158px',
+ '@media (max-width: 430px)': {
+ maxWidth: '335px',
+ alignItems: 'center',
+ justifyContent: 'center',
+ display: 'flex',
+ flexDirection: 'column',
+ },
});
-export const titleWrapStyle = css(typo.Title, {
+export const titleWrapStyle = css({
+ ...typo.Title,
display: 'flex',
justifyContent: 'space-between',
- alignItems: 'center',
marginBottom: '20px',
+ '@media (max-width: 430px)': {
+ ...typo.Mobile.Text.Bold_16,
+ marginBottom: 0,
+ height: '50px',
+ width: '100%',
+ },
});
export const barStyle = css({
margin: '48px 0',
display: 'flex',
justifyContent: 'center',
+ '@media (max-width: 430px)': {
+ margin: '0 0 18px 0',
+ },
});
export const contentStyle = css({
display: 'grid',
gridTemplateColumns: 'repeat(2, 1fr)',
gap: '20px',
+ '@media (max-width: 430px)': {
+ gap: '9px',
+ },
});
export const loadMoreWrapperStyle = css({
@@ -29,4 +48,7 @@ export const loadMoreWrapperStyle = css({
display: 'flex',
justifyContent: 'center',
padding: '62px 0 95px 0',
+ '@media (max-width: 430px)': {
+ padding: '16px 0',
+ },
});
diff --git a/src/components/organisms/BalanceGameList/BalanceGameList.tsx b/src/components/organisms/BalanceGameList/BalanceGameList.tsx
index 2a04c5ce..37bc8a1f 100644
--- a/src/components/organisms/BalanceGameList/BalanceGameList.tsx
+++ b/src/components/organisms/BalanceGameList/BalanceGameList.tsx
@@ -1,20 +1,27 @@
-import React, { useState } from 'react';
+/* eslint-disable no-alert */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+import React, { useCallback, useState } from 'react';
import { AngleSmallDown } from '@/assets';
import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
import Button from '@/components/atoms/Button/Button';
import CategoryBar from '@/components/molecules/CategoryBar/CategoryBar';
import ContentsButton from '@/components/molecules/ContentsButton/ContentsButton';
import { GameContent } from '@/types/game';
+import { ToggleGroupValue } from '@/types/toggle';
+import { useNavigate } from 'react-router-dom';
+import { ERROR } from '@/constants/message';
+import MobileToggleGroup from '@/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup';
import * as S from './BalanceGameList.style';
export interface ContentListProps {
contents: GameContent[];
- selectedValue: string;
- setSelectedValue: React.Dispatch
>;
+ selectedValue: ToggleGroupValue;
+ setSelectedValue: React.Dispatch>;
activeTab: 'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅';
setActiveTab: React.Dispatch<
React.SetStateAction<'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅'>
>;
+ isMobile?: boolean;
}
const BalanceGameList = ({
@@ -23,38 +30,74 @@ const BalanceGameList = ({
setSelectedValue,
activeTab,
setActiveTab,
+ isMobile = false,
}: ContentListProps) => {
const [visibleItems, setVisibleItems] = useState(4);
+ const navigate = useNavigate();
- const handleLoadMore = () => {
+ const handleItemClick = useCallback(
+ (gameId: number) => {
+ if (!gameId || gameId <= 0) {
+ alert(ERROR.GAME.NOT_EXIST);
+ return;
+ }
+ navigate(`/balancegame/${gameId}`);
+ },
+ [navigate],
+ );
+
+ const handleLoadMore = useCallback(() => {
setVisibleItems((prev) => Math.min(prev + 6, contents.length));
- };
+ }, [contents.length]);
+
+ const handleToggleChange = useCallback(
+ (value: ToggleGroupValue) => {
+ setSelectedValue(value);
+ },
+ [setSelectedValue],
+ );
return (
μ£Όμ λ³ λ°Έλ°μ€ κ²μ
-
+ {isMobile ? (
+
+ ) : (
+
+ )}
-
+
{contents.slice(0, visibleItems).map((content) => (
handleItemClick(content.id)}
/>
))}
{visibleItems < contents.length && (
}
>
diff --git a/src/components/organisms/CommentsSection/CommentsSection.tsx b/src/components/organisms/CommentsSection/CommentsSection.tsx
index 30e7195e..1f3b1ff1 100644
--- a/src/components/organisms/CommentsSection/CommentsSection.tsx
+++ b/src/components/organisms/CommentsSection/CommentsSection.tsx
@@ -9,12 +9,11 @@ import Pagination from '@/components/atoms/Pagination/Pagination';
import TextArea from '@/components/molecules/TextArea/TextArea';
import Toggle from '@/components/atoms/Toggle/Toggle';
import ToastModal from '@/components/atoms/ToastModal/ToastModal';
-import ToggleGroup, {
- ToggleGroupItem,
-} from '@/components/atoms/ToggleGroup/ToggleGroup';
+import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
import { NOTICE } from '@/constants/message';
import CommentItem from '@/components/molecules/CommentItem/CommentItem';
import { useCreateCommentMutation } from '@/hooks/api/comment/useCreateCommentMutation';
+import { ToggleGroupItem, ToggleGroupValue } from '@/types/toggle';
import * as S from './CommentsSection.style';
export interface CommentsSectionProps {
@@ -22,8 +21,8 @@ export interface CommentsSectionProps {
talkPickWriter: string;
commentList?: CommentsPagination;
toggleItem: ToggleGroupItem[];
- selectedValue: string;
- setToggleValue: React.Dispatch
>;
+ selectedValue: ToggleGroupValue;
+ setToggleValue: React.Dispatch>;
selectedPage: number;
handlePageChange: (page: number) => void;
voted: boolean;
@@ -59,7 +58,9 @@ const CommentsSection = ({
{ content: commentValue },
{
onSuccess: () => {
- if (selectedValue === 'trend') setToggleValue('recent');
+ if (selectedValue.field === 'views') {
+ setToggleValue({ field: 'createdAt', order: 'desc' });
+ }
handlePageChange(1);
},
},
diff --git a/src/components/organisms/Header/Header.style.ts b/src/components/organisms/Header/Header.style.ts
index 09215c69..b8373bd1 100644
--- a/src/components/organisms/Header/Header.style.ts
+++ b/src/components/organisms/Header/Header.style.ts
@@ -2,49 +2,58 @@ import { css } from '@emotion/react';
import color from '@/styles/color';
import typo from '@/styles/typo';
-export const containerStyle = css({
- width: '100%',
- padding: '0 200px',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'space-between',
- backgroundColor: color.WT,
- boxShadow: '0px 4px 11px rgba(0, 0, 0, 0.1)',
- position: 'fixed',
- top: 0,
- left: 0,
- zIndex: 1000,
- height: '100px',
-});
+export const containerStyle = css`
+ width: 100%;
+ padding: 0 200px;
+ height: 100px;
+ @media (max-width: 430px) {
+ padding: 0 20px;
+ height: 55px;
+ }
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background-color: ${color.WT};
+ box-shadow: 0px 4px 11px rgba(0, 0, 0, 0.1);
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1000;
+`;
-export const logoStyle = css({
- display: 'flex',
- alignItems: 'center',
-});
+export const logoStyle = css`
+ display: flex;
+ align-items: center;
+ @media (max-width: 430px) {
+ flex: 1;
+ justify-content: center;
+ }
+`;
-export const IconStyle = css({
- marginRight: '8px',
-});
+export const LoginButtonStyle = css`
+ ${typo.Main.SemiBold};
+ background: none;
+ border: none;
+ cursor: pointer;
+ color: ${color.GY[1]};
+ width: 100.24px;
+ height: 32.92px;
+ margin-right: 7.76px;
+`;
-export const WriteButtonStyle = css({
- margin: '27px 28px 24px 0',
-});
+export const rightContainerStyle = css`
+ display: flex;
+ align-items: center;
+ @media screen and (max-width: 430px) {
+ flex: 1;
+ justify-content: flex-end;
+ }
+`;
-export const LoginButtonStyle = css(typo.Main.SemiBold, {
- background: 'none',
- border: 'none',
- cursor: 'pointer',
- color: color.GY[1],
- width: '100.24px',
- height: '32.92px',
- marginRight: '7.76px',
-});
+export const notificationStyle = css`
+ margin-left: 42.93px;
+`;
-export const rightContainerStyle = css({
- display: 'flex',
- alignItems: 'center',
-});
-
-export const notificationStyle = css({
- marginLeft: '42.93px',
-});
+export const listButtonStyle = css`
+ cursor: pointer;
+`;
diff --git a/src/components/organisms/Header/Header.tsx b/src/components/organisms/Header/Header.tsx
index 91ffcbb8..b4e63d28 100644
--- a/src/components/organisms/Header/Header.tsx
+++ b/src/components/organisms/Header/Header.tsx
@@ -3,14 +3,14 @@
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-misused-promises */
/* eslint-disable no-console */
-import React from 'react';
+import React, { useState } from 'react';
import { useNavigate, Link } from 'react-router-dom';
import { useLogoutMutation } from '@/hooks/api/member/useLogoutMutation';
import { useNewSelector } from '@/store';
import { useParseJwt } from '@/hooks/common/useParseJwt';
import { useMemberQuery } from '@/hooks/api/member/useMemberQuery';
import { selectAccessToken } from '@/store/auth';
-import { Logo, DefaultProfile } from '@/assets';
+import { Logo, DefaultProfile, ListIcon, LogoSmall } from '@/assets';
// import Button from '@/components/atoms/Button/Button';
// import Notification from '@/components/molecules/Notification/Notification';
import ProfileIcon from '@/components/atoms/ProfileIcon/ProfileIcon';
@@ -20,13 +20,22 @@ import ProfileIcon from '@/components/atoms/ProfileIcon/ProfileIcon';
import { MenuItem } from '@/components/atoms/MenuTap/MenuTap';
import CreateDropdown from '@/components/atoms/CreateDropdown/CreateDropdown';
import { PATH } from '@/constants/path';
+import MobileSideMenu from '@/components/mobile/atoms/MobileSideMenu/MobileSideMenu';
+import useIsMobile from '@/hooks/common/useIsMobile';
import * as S from './Header.style';
const Header = () => {
const navigate = useNavigate();
- const accessToken = useNewSelector(selectAccessToken);
+ const isMobile = useIsMobile();
+ const [isMenuOpen, setIsMenuOpen] = useState(false);
+ const accessToken = useNewSelector(selectAccessToken) ?? '';
const logout = useLogoutMutation();
const { member } = useMemberQuery(useParseJwt(accessToken)?.memberId);
+
+ const handleMenuToggle = () => {
+ setIsMenuOpen((prev) => !prev);
+ };
+
// FIXME:Notification κ΄λ ¨ μ½λ
// const [isNew, setIsNew] = useState(false);
// const [messages, setMessages] = useState([]);
@@ -80,6 +89,7 @@ const Header = () => {
// ];
const handleLoginButton = () => {
+ setIsMenuOpen(false);
if (accessToken) {
logout.mutate();
} else {
@@ -137,36 +147,59 @@ const Header = () => {
return (
-
-
-
+ {isMobile ? : }
-
-
-
- {/*
*/}
-
- {accessToken ? (
-
+
+ {isMenuOpen && (
+
- ) : (
-
)}
-
-
+ >
+ ) : (
+ <>
+
+
+
+ {/*
*/}
+
+ {accessToken ? (
+
+ ) : (
+
+ )}
+
+
+ >
+ )}
);
};
-
export default Header;
diff --git a/src/components/organisms/InfoList/InfoList.tsx b/src/components/organisms/InfoList/InfoList.tsx
index de4bf45e..1dbdef5a 100644
--- a/src/components/organisms/InfoList/InfoList.tsx
+++ b/src/components/organisms/InfoList/InfoList.tsx
@@ -1,15 +1,16 @@
-import React from 'react';
-import InfoBox, { InfoBoxProps } from '@/components/molecules/InfoBox/InfoBox';
+import React, { useMemo } from 'react';
+import InfoBox from '@/components/molecules/InfoBox/InfoBox';
+import { useNavigate } from 'react-router-dom';
import * as S from './InfoList.style';
export interface InfoItem {
id: number;
editedAt: string;
- title: InfoBoxProps['title'];
- prefix: InfoBoxProps['prefix'];
- commentContent: InfoBoxProps['commentContent'];
- commentCount: InfoBoxProps['commentCount'];
- bookmarks: InfoBoxProps['bookmarks'];
+ title: string;
+ prefix: string;
+ commentContent: string;
+ commentCount: number;
+ bookmarks: number;
}
export interface InfoListProps {
@@ -17,16 +18,24 @@ export interface InfoListProps {
}
const InfoList = ({ items = [] }: InfoListProps) => {
- const groupedItems = items.reduce(
- (acc, item) => {
- if (!acc[item.editedAt]) {
- acc[item.editedAt] = [];
- }
- acc[item.editedAt].push(item);
- return acc;
- },
- {} as Record,
- );
+ const navigate = useNavigate();
+
+ const groupedItems = useMemo(() => {
+ return items.reduce>(
+ (acc, { editedAt, ...rest }) => {
+ if (!acc[editedAt]) {
+ acc[editedAt] = [];
+ }
+ acc[editedAt].push({ editedAt, ...rest });
+ return acc;
+ },
+ {},
+ );
+ }, [items]);
+
+ const handleItemClick = (id: number) => {
+ navigate(`/talkpick/${id}`);
+ };
return (
@@ -34,17 +43,27 @@ const InfoList = ({ items = [] }: InfoListProps) => {
{editedAt}
- {groupedItems[editedAt].map((infoItem) => (
- -
-
-
- ))}
+ {groupedItems[editedAt].map(
+ ({
+ id,
+ title,
+ prefix,
+ commentContent,
+ commentCount,
+ bookmarks,
+ }) => (
+ -
+ handleItemClick(id)}
+ />
+
+ ),
+ )}
))}
diff --git a/src/components/organisms/MyBalanceGameList/MyBalanceGameList.tsx b/src/components/organisms/MyBalanceGameList/MyBalanceGameList.tsx
index f0e817f3..f2483630 100644
--- a/src/components/organisms/MyBalanceGameList/MyBalanceGameList.tsx
+++ b/src/components/organisms/MyBalanceGameList/MyBalanceGameList.tsx
@@ -1,20 +1,19 @@
-import React from 'react';
-import ContentsButton, {
- ContentsButtonProps,
-} from '@/components/molecules/ContentsButton/ContentsButton';
+import React, { useMemo } from 'react';
+import ContentsButton from '@/components/molecules/ContentsButton/ContentsButton';
+import { useNavigate } from 'react-router-dom';
import * as S from './MyBalanceGameList.style';
export interface MyBalanceGameItem {
- id: number;
+ gameId: number;
editedAt: string;
- optionAImg: ContentsButtonProps['images'][0];
- optionBImg: ContentsButtonProps['images'][1];
- title: ContentsButtonProps['title'];
- mainTag: ContentsButtonProps['mainTag'];
- subTag: ContentsButtonProps['subTag'];
- bookmarked?: ContentsButtonProps['bookmarked'];
- showBookmark?: ContentsButtonProps['showBookmark'];
- size?: ContentsButtonProps['size'];
+ optionAImg: string;
+ optionBImg: string;
+ title: string;
+ mainTagName: string;
+ subTag: string;
+ bookmarked?: boolean;
+ showBookmark?: boolean;
+ size?: 'large' | 'medium' | 'small';
}
export interface MyBalanceGameListProps {
@@ -22,16 +21,24 @@ export interface MyBalanceGameListProps {
}
const MyBalanceGameList = ({ items = [] }: MyBalanceGameListProps) => {
- const groupedItems = items.reduce(
- (acc, item) => {
- if (!acc[item.editedAt]) {
- acc[item.editedAt] = [];
- }
- acc[item.editedAt].push(item);
- return acc;
- },
- {} as Record
,
- );
+ const navigate = useNavigate();
+
+ const groupedItems = useMemo(() => {
+ return items.reduce(
+ (acc, { editedAt, ...rest }) => {
+ if (!acc[editedAt]) {
+ acc[editedAt] = [];
+ }
+ acc[editedAt].push({ editedAt, ...rest });
+ return acc;
+ },
+ {} as Record,
+ );
+ }, [items]);
+
+ const handleItemClick = (gameId: number) => {
+ navigate(`/balancegame/${gameId}`);
+ };
return (
@@ -39,22 +46,31 @@ const MyBalanceGameList = ({ items = [] }: MyBalanceGameListProps) => {
{date}
- {groupedItems[date].map((balanceGameItem) => (
- -
-
-
- ))}
+ {groupedItems[date].map(
+ ({
+ gameId,
+ optionAImg,
+ optionBImg,
+ title,
+ mainTagName,
+ subTag,
+ bookmarked,
+ showBookmark,
+ }) => (
+ -
+ handleItemClick(gameId)}
+ />
+
+ ),
+ )}
))}
diff --git a/src/components/organisms/MyContentList/MyContentList.tsx b/src/components/organisms/MyContentList/MyContentList.tsx
index ced0bd78..90193626 100644
--- a/src/components/organisms/MyContentList/MyContentList.tsx
+++ b/src/components/organisms/MyContentList/MyContentList.tsx
@@ -1,17 +1,16 @@
-import React from 'react';
-import MyContentBox, {
- MyContentBoxProps,
-} from '@/components/molecules/MyContentBox/MyContentBox';
+import React, { useMemo } from 'react';
+import MyContentBox from '@/components/molecules/MyContentBox/MyContentBox';
+import { useNavigate } from 'react-router-dom';
import * as S from './MyContentList.style';
export interface MyContentItem {
id: number;
editedAt: string;
- title: MyContentBoxProps['title'];
- commentCount: MyContentBoxProps['commentCount'];
- bookmarks: MyContentBoxProps['bookmarks'];
- showBookmark?: MyContentBoxProps['showBookmark'];
- bookmarked?: MyContentBoxProps['bookmarked'];
+ title: string;
+ commentCount: number;
+ bookmarks: number;
+ showBookmark?: boolean;
+ bookmarked?: boolean;
}
export interface MyContentListProps {
@@ -19,38 +18,56 @@ export interface MyContentListProps {
}
const MyContentList = ({ items = [] }: MyContentListProps) => {
- const groupedItems = items.reduce(
- (acc, item) => {
- if (!acc[item.editedAt]) {
- acc[item.editedAt] = [];
- }
- acc[item.editedAt].push(item);
- return acc;
- },
- {} as Record
,
- );
+ const navigate = useNavigate();
+
+ const groupedItems = useMemo(() => {
+ return items.reduce>(
+ (acc, { editedAt, ...rest }) => {
+ if (!acc[editedAt]) {
+ acc[editedAt] = [];
+ }
+ acc[editedAt].push({ editedAt, ...rest });
+ return acc;
+ },
+ {},
+ );
+ }, [items]);
+
+ const handleItemClick = (id: number) => {
+ navigate(`/talkpick/${id}`);
+ };
return (
-
- {Object.keys(groupedItems).map((date) => (
-
+
+ {Object.entries(groupedItems).map(([date, contentItems]) => (
+
{date}
- {groupedItems[date].map((contentItem) => (
- -
-
-
- ))}
+ {contentItems.map(
+ ({
+ id,
+ title,
+ commentCount,
+ bookmarks,
+ showBookmark,
+ bookmarked,
+ }) => (
+ -
+ handleItemClick(id)}
+ />
+
+ ),
+ )}
-
+
))}
-
+
);
};
diff --git a/src/components/organisms/OptionBar/OptionBar.style.ts b/src/components/organisms/OptionBar/OptionBar.style.ts
index 9fe840b8..27a4b02e 100644
--- a/src/components/organisms/OptionBar/OptionBar.style.ts
+++ b/src/components/organisms/OptionBar/OptionBar.style.ts
@@ -1,8 +1,9 @@
import { css } from '@emotion/react';
-export const container = css`
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 20px;
-`;
+export const container = css({
+ display: 'flex',
+ flexDirection: 'column',
+ width: '912px',
+ alignItems: 'center',
+ gap: '20px',
+});
diff --git a/src/components/organisms/OptionBar/OptionBar.tsx b/src/components/organisms/OptionBar/OptionBar.tsx
index 1ef59ac1..20459143 100644
--- a/src/components/organisms/OptionBar/OptionBar.tsx
+++ b/src/components/organisms/OptionBar/OptionBar.tsx
@@ -1,54 +1,45 @@
-import React, { useState, useEffect } from 'react';
+import React from 'react';
import SelectGroup, {
SelectGroupItem,
} from '@/components/atoms/SelectGroup/SelectGroup';
import OptionSelector from '@/components/molecules/OptionSelector/OptionSelector';
-import { optionSets, OptionKeys } from '@/constants/optionSets';
+import { OptionKeys } from '@/constants/optionSets';
import * as S from './OptionBar.style';
export interface OptionBarProps {
- selectGroupItems: SelectGroupItem[];
- initialSelectedGroupValue?: OptionKeys;
+ selectedGroup: OptionKeys;
selectedOption: string;
onGroupSelect: (value: OptionKeys) => void;
onOptionSelect: (option: string) => void;
+ options: { label: string; value: string }[];
}
+
const OptionBar = ({
- selectGroupItems,
- initialSelectedGroupValue = OptionKeys.TALK_PICK,
+ selectedGroup,
selectedOption,
onGroupSelect,
onOptionSelect,
+ options,
}: OptionBarProps) => {
- const [selectedGroup, setSelectedGroup] = useState(
- initialSelectedGroupValue,
- );
- const [options, setOptions] = useState(optionSets[selectedGroup]);
-
- useEffect(() => {
- setOptions(optionSets[selectedGroup]);
- }, [selectedGroup]);
-
- const handleGroupSelect = (value: string) => {
- setSelectedGroup(value as OptionKeys);
- onGroupSelect(value as OptionKeys);
- };
-
- const handleOptionSelect = (option: string) => {
- onOptionSelect(option);
- };
+ const selectGroupItems: [
+ SelectGroupItem,
+ SelectGroupItem,
+ ] = [
+ { label: 'ν‘ν½', value: OptionKeys.TALK_PICK },
+ { label: 'λ°Έλ°μ€ κ²μ', value: OptionKeys.BALANCE_GAME },
+ ];
return (
);
diff --git a/src/components/organisms/SearchGameListSection/SearchGameListSection.tsx b/src/components/organisms/SearchGameListSection/SearchGameListSection.tsx
index 4718d9ea..d1763955 100644
--- a/src/components/organisms/SearchGameListSection/SearchGameListSection.tsx
+++ b/src/components/organisms/SearchGameListSection/SearchGameListSection.tsx
@@ -1,22 +1,22 @@
import React from 'react';
+import { GameListItem } from '@/types/search';
import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
import Pagination from '@/components/atoms/Pagination/Pagination';
-import SearchGameList, {
- GameItem,
-} from '@/components/molecules/SearchGameList/SearchGameList';
+import SearchGameList from '@/components/molecules/SearchGameList/SearchGameList';
import { generatePageNumbers } from '@/utils/pagination';
import { NoResultsMessage } from '@/components/atoms/NoResultsMessage/NoResultsMessage';
import SearchResultCardSkeleton from '@/components/atoms/SearchResultCardSkeleton/SearchResultCardSkeleton';
+import { ToggleGroupValue } from '@/types/toggle';
import * as S from './SearchGameListSection.style';
interface SearchGameListSectionProps {
- gameList: GameItem[];
+ gameList: GameListItem[];
keyword: string;
selectedPage: number;
totalPages: number;
- sort: string;
+ sort: ToggleGroupValue;
onPageChange: (page: number) => void;
- onSortChange: (sort: string) => void;
+ onSortChange: (sort: ToggleGroupValue) => void;
isLoading: boolean;
}
diff --git a/src/components/organisms/SearchGameResult/SearchGameResult.tsx b/src/components/organisms/SearchGameResult/SearchGameResult.tsx
index 783105f2..de9e59bf 100644
--- a/src/components/organisms/SearchGameResult/SearchGameResult.tsx
+++ b/src/components/organisms/SearchGameResult/SearchGameResult.tsx
@@ -1,8 +1,7 @@
import React from 'react';
+import { GameListItem } from '@/types/search';
import MoreButton from '@/components/atoms/MoreButton/MoreButton';
-import SearchGameList, {
- GameItem,
-} from '@/components/molecules/SearchGameList/SearchGameList';
+import SearchGameList from '@/components/molecules/SearchGameList/SearchGameList';
import { NoResultsMessage } from '@/components/atoms/NoResultsMessage/NoResultsMessage';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { PATH } from '@/constants/path';
@@ -10,7 +9,7 @@ import SearchResultCardSkeleton from '@/components/atoms/SearchResultCardSkeleto
import * as S from './SearchGameResult.style';
interface SearchGameResultProps {
- gameList: GameItem[];
+ gameList: GameListItem[];
keyword: string;
isLoading: boolean;
}
diff --git a/src/components/organisms/SearchTalkPickListSection/SearchTalkPickListSection.tsx b/src/components/organisms/SearchTalkPickListSection/SearchTalkPickListSection.tsx
index 3292defa..c575e73c 100644
--- a/src/components/organisms/SearchTalkPickListSection/SearchTalkPickListSection.tsx
+++ b/src/components/organisms/SearchTalkPickListSection/SearchTalkPickListSection.tsx
@@ -1,22 +1,22 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react';
import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
-import { SearchTalkPickItemProps } from '@/components/atoms/SearchTalkPickItem/SearchTalkPickItem';
+import { SearchTalkPickListItem } from '@/types/search';
import SearchTalkPickList from '@/components/molecules/SearchTalkPickList/SearchTalkPickList';
import Pagination from '@/components/atoms/Pagination/Pagination';
import { generatePageNumbers } from '@/utils/pagination';
import { NoResultsMessage } from '@/components/atoms/NoResultsMessage/NoResultsMessage';
import SearchResultListSkeleton from '@/components/atoms/SearchResultListSkeleton/SearchResultListSkeleton';
+import { ToggleGroupValue } from '@/types/toggle';
import * as S from './SearchTalkPickListSection.style';
interface SearchTalkPickSectionProps {
- searchTalkPickList: SearchTalkPickItemProps[];
+ searchTalkPickList: SearchTalkPickListItem[];
keyword: string;
selectedPage: number;
totalPages: number;
- sort: string;
+ sort: ToggleGroupValue;
onPageChange: (page: number) => void;
- onSortChange: (sort: string) => void;
+ onSortChange: (sort: ToggleGroupValue) => void;
isLoading: boolean;
}
diff --git a/src/components/organisms/SearchTalkPickResult/SearchTalkPickResult.tsx b/src/components/organisms/SearchTalkPickResult/SearchTalkPickResult.tsx
index 3518ca11..bb2d6d3e 100644
--- a/src/components/organisms/SearchTalkPickResult/SearchTalkPickResult.tsx
+++ b/src/components/organisms/SearchTalkPickResult/SearchTalkPickResult.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import MoreButton from '@/components/atoms/MoreButton/MoreButton';
-import { SearchTalkPickItemProps } from '@/components/atoms/SearchTalkPickItem/SearchTalkPickItem';
+import { SearchTalkPickListItem } from '@/types/search';
import SearchTalkPickList from '@/components/molecules/SearchTalkPickList/SearchTalkPickList';
import { NoResultsMessage } from '@/components/atoms/NoResultsMessage/NoResultsMessage';
import { useNavigate, useSearchParams } from 'react-router-dom';
@@ -9,7 +9,7 @@ import SearchResultListSkeleton from '@/components/atoms/SearchResultListSkeleto
import * as S from './SearchTalkPickResult.style';
interface SearchTalkPickResultProps {
- searchTalkPickList: SearchTalkPickItemProps[];
+ searchTalkPickList: SearchTalkPickListItem[];
keyword: string;
isLoading: boolean;
}
diff --git a/src/components/organisms/SideBar/SideBar.style.ts b/src/components/organisms/SideBar/SideBar.style.ts
index a82b20c4..fb5119ec 100644
--- a/src/components/organisms/SideBar/SideBar.style.ts
+++ b/src/components/organisms/SideBar/SideBar.style.ts
@@ -1,20 +1,28 @@
import { css } from '@emotion/react';
import color from '@/styles/color';
+const commonSideBarContainer = css({
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ borderRadius: '20px',
+ width: '258px',
+ height: '538px',
+ flexShrink: 0,
+ paddingTop: '30px',
+ paddingBottom: '35px',
+});
+
export const sidebarContainer = (isLoading: boolean) =>
- css({
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- backgroundColor: isLoading ? color.GY[3] : color.WT,
- borderRadius: '20px',
- width: '258px',
- height: '538px',
- flexShrink: 0,
- border: isLoading ? '' : `1px solid ${color.SKYBLUE}`,
- paddingTop: '30px',
- paddingBottom: '35px',
- });
+ css([
+ commonSideBarContainer,
+ isLoading
+ ? { backgroundColor: color.GY[3] }
+ : {
+ backgroundColor: color.WT,
+ border: `1px solid ${color.SKYBLUE}`,
+ },
+ ]);
export const profileWrapper = css({
display: 'flex',
@@ -32,7 +40,7 @@ export const profileLabelBox = css({
marginBottom: '26px',
});
-export const sideWrapper = css({
+export const sideBoxWrapper = css({
width: '100%',
marginBottom: '40px',
});
diff --git a/src/components/organisms/SideBar/SideBar.tsx b/src/components/organisms/SideBar/SideBar.tsx
index bcd08070..538bbb58 100644
--- a/src/components/organisms/SideBar/SideBar.tsx
+++ b/src/components/organisms/SideBar/SideBar.tsx
@@ -1,46 +1,53 @@
import React from 'react';
-import ProfileIcon, {
- ProfileProps,
-} from '@/components/atoms/ProfileIcon/ProfileIcon';
-import ProfileLabel, {
- ProfileLabelProps,
-} from '@/components/atoms/ProfileLabel/ProfileLabel';
-import SideBox, { SideBoxProps } from '@/components/molecules/SideBox/SideBox';
+import ProfileIcon from '@/components/atoms/ProfileIcon/ProfileIcon';
+import ProfileLabel from '@/components/atoms/ProfileLabel/ProfileLabel';
+import SideBox from '@/components/molecules/SideBox/SideBox';
import ActionBox from '@/components/molecules/ActionBox/ActionBox';
import * as S from './SideBar.style';
-export interface SideBarProps {
- nickname?: ProfileLabelProps['nickname'];
- postsCount?: SideBoxProps['postsCount'];
- bookmarkedPostsCount?: SideBoxProps['bookmarkedPostsCount'];
- profileImageUrl?: ProfileProps['imgUrl'];
- isLoading?: boolean;
+interface LoadingProps {
+ isLoading: true;
}
-const SideBar = ({
- nickname,
- profileImageUrl,
- postsCount,
- bookmarkedPostsCount,
- isLoading = false,
-}: SideBarProps) => {
- const profileIconInteraction = profileImageUrl ? 'custom' : 'default';
-
- return (
-
- {isLoading ? (
-
- ) : (
+export interface LoadedSideBarProps {
+ isLoading: false;
+ nickname: string;
+ postsCount: number;
+ bookmarkedPostsCount: number;
+ profileImageUrl?: string;
+}
+
+type SideBarProps = LoadingProps | LoadedSideBarProps;
+
+const isLoadedSideBarProps = (
+ props: SideBarProps,
+): props is LoadedSideBarProps => {
+ return !props.isLoading;
+};
+
+const SideBar = (props: SideBarProps) => {
+ const { isLoading } = props;
+
+ if (isLoading) {
+ return
;
+ }
+
+ if (isLoadedSideBarProps(props)) {
+ const { profileImageUrl, nickname, postsCount, bookmarkedPostsCount } =
+ props;
+
+ return (
+
+ );
+ }
+
+ return null;
};
export default SideBar;
diff --git a/src/components/organisms/TalkPickListSection/TalkPickListSection.tsx b/src/components/organisms/TalkPickListSection/TalkPickListSection.tsx
index 9a1caa9c..63eb6237 100644
--- a/src/components/organisms/TalkPickListSection/TalkPickListSection.tsx
+++ b/src/components/organisms/TalkPickListSection/TalkPickListSection.tsx
@@ -10,12 +10,13 @@ import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
import Button from '@/components/atoms/Button/Button';
import Pagination from '@/components/atoms/Pagination/Pagination';
import TalkPickList from '@/components/molecules/TalkPickList/TalkPickList';
+import { ToggleGroupValue } from '@/types/toggle';
import * as S from './TalkPickListSection.style';
export interface TalkPickListProps {
talkPickList?: TalkPickListPagination;
- selectedValue: string;
- setToggleValue: React.Dispatch
>;
+ selectedValue: ToggleGroupValue;
+ setToggleValue: React.Dispatch>;
selectedPage: number;
handlePageChange: (page: number) => void;
}
diff --git a/src/components/organisms/TalkPickSection/TalkPickSection.style.ts b/src/components/organisms/TalkPickSection/TalkPickSection.style.ts
index 1512592d..bf7931fe 100644
--- a/src/components/organisms/TalkPickSection/TalkPickSection.style.ts
+++ b/src/components/organisms/TalkPickSection/TalkPickSection.style.ts
@@ -73,12 +73,17 @@ export const talkPickView = css(typo.Number.Medium, {
color: color.MAIN,
});
-export const talkPickContent = css(typo.Main.Medium, {
+export const talkPickContent = css({
width: '100%',
paddingTop: '40px',
paddingLeft: '173px',
paddingRight: '173px',
borderTop: '1px solid #F4F4F4',
+});
+
+export const talkPickContentTextStyling = css(typo.Main.Medium, {
+ width: '100%',
+ whiteSpace: 'pre-wrap',
color: color.BK,
});
diff --git a/src/components/organisms/TalkPickSection/TalkPickSection.tsx b/src/components/organisms/TalkPickSection/TalkPickSection.tsx
index f8239ac9..edaa37f2 100644
--- a/src/components/organisms/TalkPickSection/TalkPickSection.tsx
+++ b/src/components/organisms/TalkPickSection/TalkPickSection.tsx
@@ -10,6 +10,7 @@ import {
} from '@/assets';
import { useNavigate } from 'react-router-dom';
import { TalkPickDetail } from '@/types/talk-pick';
+import { PATH } from '@/constants/path';
import { ERROR, SUCCESS } from '@/constants/message';
import { formatDate, formatNumber } from '@/utils/formatData';
import Button from '@/components/atoms/Button/Button';
@@ -93,7 +94,7 @@ const TalkPickSection = ({
{
label: 'μμ ',
onClick: () => {
- navigate('/post/create', { state: { talkPick } });
+ navigate(`/${PATH.CREATE.TALK_PICK}`, { state: { talkPick } });
},
},
{
@@ -192,7 +193,9 @@ const TalkPickSection = ({
{isExpanded && (
-
{talkPick?.baseFields.content}
+
+ {talkPick?.baseFields.content}
+
{talkPick?.imgUrls.length !== 0 && (
{talkPick?.imgUrls.map((url, idx) => (
diff --git a/src/constants/api.ts b/src/constants/api.ts
index f964494b..d98a6bba 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -62,7 +62,7 @@ export const END_POINT = {
// search API
SEARCH_GAME: (query: string, page: number, size: number, sort: string) =>
- `/search/game?query=${query}&page=${page}&size=${size}&sort=${sort}`,
+ `/search/game-sets?query=${query}&page=${page}&size=${size}&sort=${sort}`,
SEARCH_TALKPICK: (query: string, page: number, size: number, sort: string) =>
`/talks/search?query=${query}&page=${page}&size=${size}&sort=${sort}`,
diff --git a/src/constants/message.ts b/src/constants/message.ts
index a116b756..befce25e 100644
--- a/src/constants/message.ts
+++ b/src/constants/message.ts
@@ -42,6 +42,25 @@ export const ERROR = {
MY_TALKPICK: 'λ³ΈμΈμ΄ μμ±ν ν‘ν½μ μ μ₯ν μ μμ΅λλ€.',
MY_GAME: 'λ³ΈμΈμ΄ λ§λ λ°Έλ°μ€κ²μμ μ μ₯ν μ μμ΅λλ€.',
},
+ TEMPGAME: {
+ LOAD: 'μμ μ μ₯ λ°μ΄ν°λ₯Ό λΆλ¬μ€λ λ° μ€ν¨νμ΅λλ€.',
+ SAVE: 'μμ μ μ₯μ μ€ν¨νμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.',
+ },
+ IMAGE: {
+ UPLOAD: 'μ΄λ―Έμ§ μ
λ‘λμ μ€ν¨νμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.',
+ DELETE: 'μ΄λ―Έμ§κ° μμ μ μ€ν¨νμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.',
+ },
+ CREATEGAME: {
+ EMPTY_DATA: 'κ²μ λ°μ΄ν°κ° μμ΅λλ€.',
+ FAIL: 'κ²μ μμ±μ μ€ν¨νμ΅λλ€.',
+ },
+ VALIDATE: {
+ GAME_IMAGE: 'Aμ Bμ μ΄λ―Έμ§κ° λͺ¨λ μκ±°λ λͺ¨λ μμ΄μΌ ν©λλ€!',
+ OPTION: 'λͺ¨λ μ΅μ
μ μ€λͺ
μ μ
λ ₯ν΄μ£ΌμΈμ!',
+ },
+ GAME: {
+ NOT_EXIST: 'μ ν¨νμ§ μμ κ²μμ
λλ€.',
+ },
} as const;
export const SUCCESS = {
@@ -68,6 +87,17 @@ export const SUCCESS = {
EDIT: 'μμ μλ£!',
SAVE: 'μμμ μ₯ μλ£!',
},
+ TEMPGAME: {
+ LOAD: 'μμ μ μ₯ λ°μ΄ν°λ₯Ό λΆλ¬μμ΅λλ€!',
+ SAVE: ' μμ μ μ₯μ΄ μλ£λμμ΅λλ€!',
+ },
+ IMAGE: {
+ UPLOAD: 'μ΄λ―Έμ§κ° μ
λ‘λ λμμ΅λλ€!',
+ DELETE: 'μ΄λ―Έμ§κ° μμ λμμ΅λλ€!',
+ },
+ CREATEGAME: {
+ CREATE: 'λ±λ‘λμμ΅λλ€!',
+ },
} as const;
export const NOTICE = {
diff --git a/src/constants/optionSets.ts b/src/constants/optionSets.ts
index 2887da92..aac76c44 100644
--- a/src/constants/optionSets.ts
+++ b/src/constants/optionSets.ts
@@ -3,12 +3,19 @@ export enum OptionKeys {
BALANCE_GAME = 'balanceGame',
}
-export const optionSets: Record
= {
+export const optionSets: Record<
+ OptionKeys,
+ { label: string; value: string }[]
+> = {
[OptionKeys.TALK_PICK]: [
- 'λ΄κ° μ μ₯ν',
- 'λ΄κ° ν¬νν',
- 'λ΄κ° λκΈλ¨',
- 'λ΄κ° μμ±ν',
+ { label: 'λ΄κ° μ μ₯ν', value: 'bookmarks' },
+ { label: 'λ΄κ° ν¬νν', value: 'votes' },
+ { label: 'λ΄κ° λκΈλ¨', value: 'comments' },
+ { label: 'λ΄κ° μμ±ν', value: 'written' },
+ ],
+ [OptionKeys.BALANCE_GAME]: [
+ { label: 'λ΄κ° μ μ₯ν', value: 'bookmarks' },
+ { label: 'λ΄κ° ν¬νν', value: 'votes' },
+ { label: 'λ΄κ° λ§λ ', value: 'written' },
],
- [OptionKeys.BALANCE_GAME]: ['λ΄κ° μ μ₯ν', 'λ΄κ° ν¬νν', 'λ΄κ° λ§λ '],
};
diff --git a/src/hooks/api/game/useBestGameListQuery.ts b/src/hooks/api/game/useBestGameListQuery.ts
index 8b64fe43..7d3468f7 100644
--- a/src/hooks/api/game/useBestGameListQuery.ts
+++ b/src/hooks/api/game/useBestGameListQuery.ts
@@ -2,10 +2,11 @@ import { useQuery } from '@tanstack/react-query';
import { GameContent } from '@/types/game';
import { getBestGames } from '@/api/game';
-export const useBestGameList = (tagName: string) => {
+export const useBestGameList = (tagName: string, isEnabled: boolean) => {
const { data: bestGames, isLoading } = useQuery({
queryKey: ['bestGames', tagName],
queryFn: () => getBestGames(tagName),
+ enabled: isEnabled,
});
return { bestGames, isLoading };
};
diff --git a/src/hooks/api/game/useCreateBalanceGameMutation.ts b/src/hooks/api/game/useCreateBalanceGameMutation.ts
index 4272f741..db6b22dd 100644
--- a/src/hooks/api/game/useCreateBalanceGameMutation.ts
+++ b/src/hooks/api/game/useCreateBalanceGameMutation.ts
@@ -11,7 +11,6 @@ export const useCreateBalanceGameMutation = () => {
return response.data;
},
onSuccess: async (response) => {
- console.log('κ²μ μμ± μ±κ³΅');
await queryClient.invalidateQueries({
queryKey: ['games'],
});
@@ -26,7 +25,6 @@ export const useCreateBalanceGameMutation = () => {
): Promise => {
try {
const gameId = await mutation.mutateAsync(gameData);
- console.log('κ²μ μμ± μ±κ³΅, κ²μ ID:', gameId);
return gameId;
} catch (error) {
console.error('κ²μ μμ± μ€ μ€λ₯ λ°μ:', error);
diff --git a/src/hooks/api/game/useLatestGameListQuery.ts b/src/hooks/api/game/useLatestGameListQuery.ts
index 5ae4784f..ff20c9ac 100644
--- a/src/hooks/api/game/useLatestGameListQuery.ts
+++ b/src/hooks/api/game/useLatestGameListQuery.ts
@@ -2,10 +2,11 @@ import { useQuery } from '@tanstack/react-query';
import { GameContent } from '@/types/game';
import { getLatestGames } from '@/api/game';
-export const useLatestGameList = (tagName: string) => {
+export const useLatestGameList = (tagName: string, isEnabled: boolean) => {
const { data: latestGames, isLoading } = useQuery({
queryKey: ['latestGames', tagName],
queryFn: () => getLatestGames(tagName),
+ enabled: isEnabled,
});
return { latestGames, isLoading };
};
diff --git a/src/hooks/api/game/useSaveTempGameMutation.ts b/src/hooks/api/game/useSaveTempGameMutation.ts
index 69b83711..3d6d2199 100644
--- a/src/hooks/api/game/useSaveTempGameMutation.ts
+++ b/src/hooks/api/game/useSaveTempGameMutation.ts
@@ -7,15 +7,12 @@ export const useSaveTempGameMutation = () => {
return useMutation({
mutationFn: (tempGameData: TempGame) => {
- console.log('μμ μ μ₯ μμ² λ°μ΄ν°:', tempGameData);
return postTempGame(tempGameData);
},
onSuccess: async (response) => {
- console.log('μμ μ μ₯ μ±κ³΅ μλ΅:', response);
await queryClient.invalidateQueries({
queryKey: ['tempGame'],
});
- console.log('μΊμ 무ν¨ν μλ£');
},
onError: (error) => {
console.error('μμ μ μ₯ μ€ν¨:', error);
diff --git a/src/hooks/api/member/useLogoutMutation.ts b/src/hooks/api/member/useLogoutMutation.ts
index dc299855..195a9f89 100644
--- a/src/hooks/api/member/useLogoutMutation.ts
+++ b/src/hooks/api/member/useLogoutMutation.ts
@@ -1,8 +1,11 @@
+/* eslint-disable no-console */
+/* eslint-disable no-alert */
import { AxiosErrorResponse, axiosInstance } from '@/api/interceptor';
import { postLogout } from '@/api/member';
import { PATH } from '@/constants/path';
import { useNewDispatch } from '@/store';
import { tokenActions } from '@/store/auth';
+import { deleteCookie } from '@/utils/cookie';
import { useMutation } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
@@ -14,7 +17,9 @@ export const useLogoutMutation = () => {
onSuccess: () => {
// TODO: λ°±μλμμ 리νλ μ¬ ν ν° μΏ ν€μ μ μ₯μν€λ©΄, ν΄λΉ μ½λ μ κ±°
localStorage.removeItem('accessToken');
- localStorage.removeItem('rtk');
+ localStorage.removeItem('refreshToken');
+ deleteCookie('accessToken');
+ deleteCookie('refreshToken');
delete axiosInstance.defaults.headers.Authorization;
dispatch(tokenActions.deleteToken());
diff --git a/src/hooks/api/mypages/useMyInfoQuery.ts b/src/hooks/api/mypages/useMyInfoQuery.ts
index 4621ffbb..41302d63 100644
--- a/src/hooks/api/mypages/useMyInfoQuery.ts
+++ b/src/hooks/api/mypages/useMyInfoQuery.ts
@@ -4,11 +4,20 @@ import { SideBar } from '@/types/mypages';
import { Id } from '@/types/api';
export const useMyInfoQuery = (memberId: Id) => {
- const { data: memberInfo, isLoading } = useQuery({
+ const { data, isLoading } = useQuery({
queryKey: ['memberInfo', memberId],
queryFn: () => getMyInfo(memberId),
enabled: !!memberId,
});
+ const memberInfo = {
+ id: data?.id ?? 0,
+ nickname: data?.nickname ?? '',
+ profileImageUrl: data?.profileImageUrl ?? '',
+ createdAt: data?.createdAt ?? '',
+ postsCount: data?.postsCount ?? 0,
+ bookmarkedPostsCount: data?.bookmarkedPostsCount ?? 0,
+ };
+
return { memberInfo, isLoading };
};
diff --git a/src/hooks/api/mypages/useObserver.ts b/src/hooks/api/mypages/useObserver.ts
index 28656ba1..cd5bbe0c 100644
--- a/src/hooks/api/mypages/useObserver.ts
+++ b/src/hooks/api/mypages/useObserver.ts
@@ -4,7 +4,7 @@ import { useInView } from 'react-intersection-observer';
type InfiniteQueryType = {
hasNextPage: boolean;
isFetchingNextPage: boolean;
- fetchNextPage: () => Promise;
+ fetchNextPage: () => Promise;
};
export const useObserver = (queries: Record) => {
@@ -17,7 +17,7 @@ export const useObserver = (queries: Record) => {
Object.values(queries).forEach(
({ hasNextPage, isFetchingNextPage, fetchNextPage }) => {
if (hasNextPage && !isFetchingNextPage) {
- fetchNextPage();
+ void fetchNextPage();
}
},
);
diff --git a/src/hooks/api/search/useGameResultQuery.ts b/src/hooks/api/search/useGameResultQuery.ts
index 9bfeb9cb..b834924f 100644
--- a/src/hooks/api/search/useGameResultQuery.ts
+++ b/src/hooks/api/search/useGameResultQuery.ts
@@ -1,16 +1,19 @@
import { useQuery } from '@tanstack/react-query';
import { getGameResults } from '@/api/search';
import { GameResult } from '@/types/search';
+import { ToggleGroupValue } from '@/types/toggle';
export const useGameResultQuery = (
query: string,
page: number,
size: number,
- sort: string,
+ sort: ToggleGroupValue,
) => {
+ const sortParam = `${sort.field},${sort.order}`;
+
const { data: gameResults, isLoading } = useQuery({
- queryKey: ['gameResults', query, page, size, sort],
- queryFn: () => getGameResults(query, page, size, sort),
+ queryKey: ['gameResults', query, page, size, sortParam],
+ queryFn: () => getGameResults(query, page, size, sortParam),
});
const content = gameResults?.content || [];
diff --git a/src/hooks/api/search/useTalkPickResultQuery.ts b/src/hooks/api/search/useTalkPickResultQuery.ts
index cf9adc6b..cb2355cd 100644
--- a/src/hooks/api/search/useTalkPickResultQuery.ts
+++ b/src/hooks/api/search/useTalkPickResultQuery.ts
@@ -1,16 +1,19 @@
import { useQuery } from '@tanstack/react-query';
import { getTalkPickResults } from '@/api/search';
import { TalkPickResult } from '@/types/search';
+import { ToggleGroupValue } from '@/types/toggle';
export const useTalkPickResultQuery = (
query: string,
page: number,
size: number,
- sort: string,
+ sort: ToggleGroupValue,
) => {
+ const sortParam = `${sort.field},${sort.order}`;
+
const { data: talkPickResults, isLoading } = useQuery({
- queryKey: ['talkPickResults', query, page, size, sort],
- queryFn: () => getTalkPickResults(query, page, size, sort),
+ queryKey: ['talkPickResults', query, page, size, sortParam],
+ queryFn: () => getTalkPickResults(query, page, size, sortParam),
});
const content = talkPickResults?.content || [];
diff --git a/src/hooks/common/useIsMobile.ts b/src/hooks/common/useIsMobile.ts
new file mode 100644
index 00000000..fb3293b0
--- /dev/null
+++ b/src/hooks/common/useIsMobile.ts
@@ -0,0 +1,21 @@
+import { useEffect, useState } from 'react';
+
+function useIsMobile() {
+ const [isMobile, setIsMobile] = useState(false);
+
+ useEffect(() => {
+ const checkIsMobile = () => {
+ const mobile = window.matchMedia('(max-width: 430px)').matches;
+ setIsMobile(
+ mobile || ('ontouchstart' in window && window.innerWidth <= 430),
+ );
+ };
+
+ checkIsMobile();
+ window.addEventListener('resize', checkIsMobile);
+ return () => window.removeEventListener('resize', checkIsMobile);
+ }, []);
+
+ return isMobile;
+}
+export default useIsMobile;
diff --git a/src/hooks/common/useTokenRefresh.ts b/src/hooks/common/useTokenRefresh.ts
index f0df5b70..50dfbbd2 100644
--- a/src/hooks/common/useTokenRefresh.ts
+++ b/src/hooks/common/useTokenRefresh.ts
@@ -9,7 +9,7 @@ import { useParseJwt } from './useParseJwt';
export const useTokenRefresh = () => {
const accessToken = useNewSelector(selectAccessToken);
// TODO
- const refreshToken = localStorage.getItem('rtk');
+ const refreshToken = localStorage.getItem('refreshToken');
const localstorageAccessToken = localStorage.getItem('accessToken');
const dispatch = useNewDispatch();
const navigate = useNavigate();
@@ -19,7 +19,7 @@ export const useTokenRefresh = () => {
if (!accessToken && refreshToken) {
if (isTimeLimit(useParseJwt(localstorageAccessToken).exp)) {
localStorage.removeItem('accessToken');
- localStorage.removeItem('rtk');
+ localStorage.removeItem('refreshToken');
delete axiosInstance.defaults.headers.Authorization;
dispatch(tokenActions.deleteToken());
alert('λ‘κ·ΈμΈ μκ°μ΄ λ§λ£λμμ΅λλ€. λ€μ λ‘κ·ΈμΈν΄μ£ΌμΈμ.');
diff --git a/src/hooks/game/useBalanceGameCreation.ts b/src/hooks/game/useBalanceGameCreation.ts
index d1b2d688..e8788041 100644
--- a/src/hooks/game/useBalanceGameCreation.ts
+++ b/src/hooks/game/useBalanceGameCreation.ts
@@ -1,20 +1,25 @@
-import React, { useEffect, useState } from 'react';
+import { useEffect, useState, useRef } from 'react';
import { BalanceGameOption, BalanceGameSet } from '@/types/game';
import {
createInitialGameStages,
updateOptionInGameSets,
} from '@/utils/balanceGameUtils';
+import { ERROR } from '@/constants/message';
export const useBalanceGameCreation = (
- currentStage: number,
- loadedGames?: BalanceGameSet[],
+ showToast: (message: string) => void,
totalStage: number = 10,
+ loadedGames?: BalanceGameSet[],
) => {
const [games, setGames] = useState(
loadedGames || createInitialGameStages(totalStage),
);
+ const [currentStage, setCurrentStage] = useState(0);
const [currentOptions, setCurrentOptions] = useState([]);
const [currentDescription, setCurrentDescription] = useState('');
+ const [clearInput, setClearInput] = useState(false);
+
+ const timerRef = useRef(null);
useEffect(() => {
if (loadedGames) {
@@ -28,6 +33,24 @@ export const useBalanceGameCreation = (
setCurrentDescription(stage.description);
}, [currentStage, games]);
+ useEffect(() => {
+ if (clearInput) {
+ if (timerRef.current !== null) {
+ clearTimeout(timerRef.current);
+ }
+
+ timerRef.current = setTimeout(() => {
+ setClearInput(false);
+ }, 500);
+ }
+
+ return () => {
+ if (timerRef.current !== null) {
+ clearTimeout(timerRef.current);
+ }
+ };
+ }, [clearInput]);
+
const updateOption = (
stageIndex: number,
optionType: 'A' | 'B',
@@ -42,6 +65,11 @@ export const useBalanceGameCreation = (
optionType,
newOption,
);
+
+ if (idx === currentStage) {
+ setCurrentOptions(updatedOptions);
+ }
+
return {
...game,
gameOptions: updatedOptions,
@@ -50,17 +78,40 @@ export const useBalanceGameCreation = (
);
};
- const handleOptionChange =
- (optionType: 'A' | 'B') => (event: React.ChangeEvent) => {
- updateOption(currentStage, optionType, { name: event.target.value });
- };
+ const validateStage = (): true | string => {
+ if (!currentOptions[0]?.name.trim() || !currentOptions[1]?.name.trim()) {
+ return ERROR.VALIDATE.OPTION;
+ }
- const handleDescriptionChange = (
- optionType: 'A' | 'B',
- event: React.ChangeEvent,
- ) => {
- const { value } = event.target;
- updateOption(currentStage, optionType, { description: value });
+ const hasBothImages =
+ currentOptions[0]?.imgUrl.trim() && currentOptions[1]?.imgUrl.trim();
+ const hasNoImages =
+ !currentOptions[0]?.imgUrl.trim() && !currentOptions[1]?.imgUrl.trim();
+
+ if (!(hasBothImages || hasNoImages)) {
+ return ERROR.VALIDATE.GAME_IMAGE;
+ }
+
+ return true;
+ };
+
+ const handleNextStage = () => {
+ const validationResult = validateStage();
+ if (currentStage < totalStage - 1) {
+ if (validationResult === true) {
+ setClearInput(true);
+ setCurrentStage((prev) => prev + 1);
+ } else {
+ showToast(validationResult);
+ }
+ }
+ };
+
+ const handlePrevStage = () => {
+ if (currentStage > 0) {
+ setClearInput(true);
+ setCurrentStage((prev) => prev - 1);
+ }
};
const handleStageDescriptionChange = (newDescription: string) => {
@@ -73,12 +124,24 @@ export const useBalanceGameCreation = (
);
};
+ const handleOptionUpdate = (
+ optionType: 'A' | 'B',
+ field: 'name' | 'description',
+ value: string,
+ ) => {
+ updateOption(currentStage, optionType, { [field]: value });
+ };
+
return {
games,
+ currentStage,
currentOptions,
currentDescription,
- handleOptionChange,
- handleDescriptionChange,
+ clearInput,
+ handleNextStage,
+ handlePrevStage,
handleStageDescriptionChange,
+ handleOptionUpdate,
+ validateStage,
};
};
diff --git a/src/hooks/game/useStageNavigation.ts b/src/hooks/game/useStageNavigation.ts
deleted file mode 100644
index 062842f0..00000000
--- a/src/hooks/game/useStageNavigation.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { useEffect, useRef, useState } from 'react';
-
-export const useStageNavigation = (totalStage: number) => {
- const [currentStage, setCurrentStage] = useState(0);
- const [clearInput, setClearInput] = useState(false);
- const timerRef = useRef(null);
-
- useEffect(() => {
- if (clearInput) {
- if (timerRef.current !== null) {
- clearTimeout(timerRef.current);
- }
-
- timerRef.current = setTimeout(() => {
- setClearInput(false);
- }, 500);
-
- return () => {
- if (timerRef.current !== null) {
- clearTimeout(timerRef.current);
- }
- };
- }
- }, [currentStage, clearInput]);
-
- const handleNextStage = () => {
- if (currentStage < totalStage - 1) {
- setClearInput(true);
- setCurrentStage((prev) => prev + 1);
- }
- };
-
- const handlePrevStage = () => {
- if (currentStage > 0) {
- setClearInput(true);
- setCurrentStage((prev) => prev - 1);
- }
- };
-
- return {
- currentStage,
- clearInput,
- handleNextStage,
- handlePrevStage,
- setClearInput,
- };
-};
diff --git a/src/hooks/login/useLoginForm.ts b/src/hooks/login/useLoginForm.ts
index 813db56a..d5c25272 100644
--- a/src/hooks/login/useLoginForm.ts
+++ b/src/hooks/login/useLoginForm.ts
@@ -1,4 +1,3 @@
-import { ChangeEvent, useState } from 'react';
import { AxiosErrorResponse, axiosInstance } from '@/api/interceptor';
import { postLogin } from '@/api/member';
import { HTTP_STATUS_CODE } from '@/constants/api';
@@ -6,6 +5,7 @@ import { useNewDispatch } from '@/store';
import { tokenActions } from '@/store/auth';
import { MemberForm } from '@/types/member';
import { useMutation } from '@tanstack/react-query';
+import { ChangeEvent, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { PATH } from '@/constants/path';
import { ERROR, SUCCESS } from '../../constants/message';
@@ -51,7 +51,7 @@ export const useLoginForm = (
axiosInstance.defaults.headers.Authorization = `Bearer ${res}`;
localStorage.setItem('accessToken', res);
- localStorage.setItem('rtk', 'rtk');
+ localStorage.setItem('refreshToken', 'refreshToken');
localStorage.setItem('savedEmail', form.email);
showToastModal(SUCCESS.LOGIN, () => {
diff --git a/src/hooks/mypages/useMyPageOptions.ts b/src/hooks/mypages/useMyPageOptions.ts
new file mode 100644
index 00000000..7b9bd917
--- /dev/null
+++ b/src/hooks/mypages/useMyPageOptions.ts
@@ -0,0 +1,62 @@
+import { useState, useEffect, useCallback } from 'react';
+import { useSearchParams } from 'react-router-dom';
+import { OptionKeys, optionSets } from '@/constants/optionSets';
+import { validateUrlParam } from '@/utils/validateUrlParam';
+
+const isValidOptionKey = (value: string): boolean => {
+ return Object.values(OptionKeys).includes(value as OptionKeys);
+};
+
+export const useMyPageOptions = () => {
+ const [searchParams, setSearchParams] = useSearchParams();
+
+ const initialGroup = validateUrlParam(
+ searchParams.get('group'),
+ OptionKeys.TALK_PICK,
+ isValidOptionKey,
+ );
+ const initialOption =
+ searchParams.get('option') ?? optionSets[initialGroup][0].value;
+
+ const [selectedGroup, setSelectedGroup] = useState(initialGroup);
+ const [selectedOption, setSelectedOption] = useState(initialOption);
+
+ useEffect(() => {
+ const group = validateUrlParam(
+ searchParams.get('group'),
+ OptionKeys.TALK_PICK,
+ isValidOptionKey,
+ );
+ const option = searchParams.get('option') ?? optionSets[group][0].value;
+ setSelectedGroup(group);
+ setSelectedOption(option);
+ }, [searchParams]);
+
+ const handleGroupSelect = useCallback(
+ (group: OptionKeys) => {
+ const firstOption = optionSets[group][0].value;
+ setSelectedGroup(group);
+ setSelectedOption(firstOption);
+ setSearchParams({ group });
+ },
+ [setSearchParams],
+ );
+
+ const handleOptionSelect = useCallback(
+ (option: string) => {
+ setSelectedOption(option);
+ setSearchParams({ group: selectedGroup, option });
+ },
+ [selectedGroup, setSearchParams],
+ );
+
+ const options = optionSets[selectedGroup];
+
+ return {
+ selectedGroup,
+ selectedOption,
+ options,
+ handleGroupSelect,
+ handleOptionSelect,
+ };
+};
diff --git a/src/hooks/search/usePagination.ts b/src/hooks/search/usePagination.ts
index 1a29a9cc..774ed3d7 100644
--- a/src/hooks/search/usePagination.ts
+++ b/src/hooks/search/usePagination.ts
@@ -1,11 +1,11 @@
import { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
-const usePagination = (defaultPage = 0) => {
+const usePagination = (defaultPage = 1) => {
const [searchParams, setSearchParams] = useSearchParams();
const initialPage =
- parseInt(searchParams.get('page') || `${defaultPage}`, 10) || 0;
+ parseInt(searchParams.get('page') || `${defaultPage}`, 10) || 1;
const [page, setPage] = useState(initialPage);
useEffect(() => {
@@ -16,7 +16,7 @@ const usePagination = (defaultPage = 0) => {
}, [page, setSearchParams]);
const handlePageChange = (newPage: number) => {
- setPage(newPage - 1);
+ setPage(newPage);
};
return { page, handlePageChange };
diff --git a/src/hooks/search/useSort.ts b/src/hooks/search/useSort.ts
index 253cb6e4..46c78c8d 100644
--- a/src/hooks/search/useSort.ts
+++ b/src/hooks/search/useSort.ts
@@ -1,9 +1,12 @@
import { useState } from 'react';
+import { ToggleGroupValue } from '@/types/toggle';
-const useSort = (defaultSort = 'views') => {
- const [sort, setSort] = useState(defaultSort);
+const useSort = (
+ defaultSort: ToggleGroupValue = { field: 'views', order: 'desc' },
+) => {
+ const [sort, setSort] = useState(defaultSort);
- const handleSortChange = (newSort: string) => {
+ const handleSortChange = (newSort: ToggleGroupValue) => {
setSort(newSort);
};
diff --git a/src/layout/layout.tsx b/src/layout/layout.tsx
index f579616b..afcbbe0d 100644
--- a/src/layout/layout.tsx
+++ b/src/layout/layout.tsx
@@ -3,20 +3,25 @@ import { css } from '@emotion/react';
import { Outlet } from 'react-router-dom';
import Header from '@/components/organisms/Header/Header';
import Footer from '@/components/organisms/Footer/Footer';
+import useIsMobile from '@/hooks/common/useIsMobile';
// import Sidebar from '../pages/MyPage/sections/Sidebar/Sidebar';
export const Layout = () => {
+ const isMobile = useIsMobile();
return (
<>
-
+ {isMobile ? null : }
>
);
};
@@ -32,6 +37,9 @@ export const LayoutNoSearch = () => {
alignItems: 'center',
height: '100vh',
paddingTop: '100px',
+ '@media (max-width: 430px)': {
+ paddingTop: '55px',
+ },
})}
>
diff --git a/src/pages/BalanceGameCreationPage/BalanceGameCreationPage.tsx b/src/pages/BalanceGameCreationPage/BalanceGameCreationPage.tsx
index b4f3ccd9..8bfb745a 100644
--- a/src/pages/BalanceGameCreationPage/BalanceGameCreationPage.tsx
+++ b/src/pages/BalanceGameCreationPage/BalanceGameCreationPage.tsx
@@ -17,8 +17,9 @@ import TextModal from '@/components/molecules/TextModal/TextModal';
import { useNavigate } from 'react-router-dom';
import { useSaveTempGameMutation } from '@/hooks/api/game/useSaveTempGameMutation';
import { createInitialGameStages } from '@/utils/balanceGameUtils';
-import { useLoadTempGameQuery } from '@/hooks/api/game/useLoadTempGameQuery';
import { resizeImage } from '@/utils/imageUtils';
+import { useLoadTempGameQuery } from '@/hooks/api/game/useLoadTempGameQuery';
+import { SUCCESS, ERROR } from '@/constants/message';
import * as S from './BalanceGameCreationPage.style';
const BalanceGameCreationPage = () => {
@@ -44,11 +45,7 @@ const BalanceGameCreationPage = () => {
const handleDraftLoad = () => {
if (isSuccess && tempGame) {
- console.log('μμ μ μ₯ λΆλ¬μ€κΈ° μμ');
- console.log('λΆλ¬μ¨ μμ μ μ₯ λ°μ΄ν°:', tempGame);
const initialStages = createInitialGameStages(10);
- console.log('μμ±λ μ΄κΈ° μ€ν
μ΄μ§ λ°μ΄ν°:', initialStages);
-
const mappedGames: BalanceGameSet[] = initialStages.map((stage, idx) => ({
description: tempGame.tempGames[idx]?.description || stage.description,
gameOptions: stage.gameOptions.map((option, optionIdx) => ({
@@ -56,13 +53,12 @@ const BalanceGameCreationPage = () => {
...tempGame.tempGames[idx]?.tempGameOptions[optionIdx],
})),
}));
- console.log('λ³ν©λ κ²μ λ°μ΄ν°:', mappedGames);
setTitle(tempGame.title);
setLoadedGames(mappedGames);
- showToastModal('μμ μ μ₯ λ°μ΄ν°λ₯Ό λΆλ¬μμ΅λλ€!');
+ showToastModal(SUCCESS.TEMPGAME.LOAD);
} else {
- showToastModal('μμ μ μ₯ λ°μ΄ν°λ₯Ό λΆλ¬μ€λ λ° μ€ν¨νμ΅λλ€.');
+ showToastModal(ERROR.TEMPGAME.LOAD);
}
};
@@ -87,7 +83,6 @@ const BalanceGameCreationPage = () => {
const { imgUrls, fileIds } = response;
return { imgUrl: imgUrls[0], fileId: fileIds[0] };
} catch (error) {
- console.error('API νΈμΆ μλ¬:', error);
throw new Error('μ΄λ―Έμ§ μ
λ‘λ μ€ν¨');
}
};
@@ -112,8 +107,7 @@ const BalanceGameCreationPage = () => {
return updatedGames;
});
} catch (error) {
- console.error('onImageChange μλ¬:', error);
- alert('μ΄λ―Έμ§ μ
λ‘λμ μ€ν¨νμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.');
+ alert(ERROR.IMAGE.UPLOAD);
}
};
@@ -134,7 +128,7 @@ const BalanceGameCreationPage = () => {
};
return updatedGames;
});
- showToastModal('μ΄λ―Έμ§κ° μμ λμμ΅λλ€.');
+ showToastModal(SUCCESS.IMAGE.DELETE);
}
setPopupData(null);
setIsTextModalOpen(false);
@@ -154,7 +148,7 @@ const BalanceGameCreationPage = () => {
selectedSubTag: string,
) => {
if (!games.length) {
- showToastModal('κ²μ λ°μ΄ν°κ° μμ΅λλ€.');
+ showToastModal(ERROR.CREATEGAME.EMPTY_DATA);
return;
}
@@ -167,13 +161,11 @@ const BalanceGameCreationPage = () => {
try {
const gameId = await handleCreateBalanceGame(gameData);
- console.log('κ²μ μμ± μλ£, κ²μ ID:', gameId);
- showToastModal('λ±λ‘λμμ΅λλ€!', () => {
+ showToastModal(SUCCESS.CREATEGAME.CREATE, () => {
navigate(`/balancegame/${gameId}`);
});
} catch (error) {
- console.error('κ²μ μμ± μ€ν¨:', error);
- showToastModal('κ²μ μμ±μ μ€ν¨νμ΅λλ€.');
+ showToastModal(ERROR.CREATEGAME.FAIL);
}
};
@@ -197,13 +189,12 @@ const BalanceGameCreationPage = () => {
isLoaded: false,
tempGames: convertToTempGameSets(games),
};
- console.log('μμ μ μ₯ μ€ν λ°μ΄ν°:', tempGameData);
saveTempGame(tempGameData, {
onSuccess: () => {
- showToastModal('μμ μ μ₯μ΄ μλ£λμμ΅λλ€!');
+ showToastModal(SUCCESS.TEMPGAME.SAVE);
},
onError: () => {
- showToastModal('μμ μ μ₯μ μ€ν¨νμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.');
+ showToastModal(ERROR.TEMPGAME.SAVE);
},
});
};
diff --git a/src/pages/LandingPage/LandingPage.style.ts b/src/pages/LandingPage/LandingPage.style.ts
index 6b625747..3768f3f2 100644
--- a/src/pages/LandingPage/LandingPage.style.ts
+++ b/src/pages/LandingPage/LandingPage.style.ts
@@ -1,5 +1,6 @@
import { css } from '@emotion/react';
import color from '@/styles/color';
+import typo from '@/styles/typo';
export const contentWrapStyle = css({
display: 'flex',
@@ -8,16 +9,44 @@ export const contentWrapStyle = css({
width: '100%',
background: color.WT,
padding: '113px 388px 95px 374px',
+ '@media (max-width: 430px)': {
+ padding: '18px 20px',
+ },
+});
+
+export const pageWrapperStyle = css({
+ position: 'relative',
+});
+
+export const floatingDropdownStyle = css({
+ position: 'fixed',
+ bottom: '16px',
+ right: '16px',
+ zIndex: 50,
});
export const categoryBoxStyle = css({
margin: '109px 0 137px 0',
});
+export const searchBoxStyle = css({
+ margin: '30px 0',
+ gap: '14px',
+ display: 'flex',
+ flexDirection: 'column',
+});
+
+export const searchBoxTitleStyle = css(typo.Mobile.Text.Bold_16, {
+ color: color.BK,
+});
+
export const toastModalStyling = css({
position: 'fixed',
top: '110px',
left: '50%',
transform: 'translate(-50%)',
zIndex: '1000',
+ '@media (max-width: 430px)': {
+ top: '65px',
+ },
});
diff --git a/src/pages/LandingPage/LandingPage.tsx b/src/pages/LandingPage/LandingPage.tsx
index 2a592249..7979912d 100644
--- a/src/pages/LandingPage/LandingPage.tsx
+++ b/src/pages/LandingPage/LandingPage.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState } from 'react';
import TopBanner from '@/components/molecules/TopBanner/TopBanner';
import SearchTagBar from '@/components/molecules/SearchTagBar/SearchTagBar';
import CategoryBox from '@/components/molecules/CategoryBox/CategoryBox';
@@ -6,40 +6,35 @@ import BalanceGameList from '@/components/organisms/BalanceGameList/BalanceGameL
import { useTodayTalkPickQuery } from '@/hooks/api/talk-pick/useTodayTalkPickQuery';
import { useNavigate } from 'react-router-dom';
import ToastModal from '@/components/atoms/ToastModal/ToastModal';
-import { GameContent } from '@/types/game';
import { useBestGameList } from '@/hooks/api/game/useBestGameListQuery';
import { useLatestGameList } from '@/hooks/api/game/useLatestGameListQuery';
+import { ToggleGroupValue } from '@/types/toggle';
import { NOTICE } from '@/constants/message';
+import FloatingMenuButton from '@/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton';
+import useIsMobile from '@/hooks/common/useIsMobile';
import * as S from './LandingPage.style';
const LandingPage = () => {
+ const isMobile = useIsMobile();
const { todayTalkPick } = useTodayTalkPickQuery();
const [isServicePreparing, setIsServicePreparing] = useState(false);
- const [selectedValue, setSelectedValue] = useState('views');
+ const [selectedValue, setSelectedValue] = useState({
+ field: 'views',
+ order: 'desc',
+ });
const [activeTab, setActiveTab] = useState<
'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅'
>('μΈκΈ°');
- const { bestGames, isLoading: isBestLoading } = useBestGameList(activeTab);
- const { latestGames, isLoading: isLatestLoading } =
- useLatestGameList(activeTab);
+ const isBestGamesEnabled =
+ activeTab === 'μΈκΈ°' || selectedValue.field === 'views';
+ const isLatestGamesEnabled =
+ activeTab !== 'μΈκΈ°' && selectedValue.field !== 'views';
- const [contents, setContents] = useState([]);
+ const { bestGames } = useBestGameList(activeTab, isBestGamesEnabled);
+ const { latestGames } = useLatestGameList(activeTab, isLatestGamesEnabled);
- useEffect(() => {
- if (selectedValue === 'views') {
- setContents(bestGames || []);
- } else if (selectedValue === 'createdAt') {
- setContents(latestGames || []);
- }
- }, [
- selectedValue,
- activeTab,
- bestGames,
- latestGames,
- isBestLoading,
- isLatestLoading,
- ]);
+ const contents = bestGames || latestGames || [];
const handleService = () => {
setIsServicePreparing(true);
@@ -56,27 +51,48 @@ const LandingPage = () => {
};
return (
-
+
{isServicePreparing && (
{NOTICE.STATUS.NOT_READY}
)}
-
+ {isMobile ? (
+
+
+
+
μ΄λ€ μ½ν
μΈ λ₯Ό μ°Ύμλ³ΌκΉμ?
+
+
+
+
+
+
+
+ ) : (
+
+ )}
);
};
diff --git a/src/pages/MyPage/MyPage.tsx b/src/pages/MyPage/MyPage.tsx
index fd669a3a..c4c01e7f 100644
--- a/src/pages/MyPage/MyPage.tsx
+++ b/src/pages/MyPage/MyPage.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useMemo, useEffect } from 'react';
+import React, { useMemo } from 'react';
import SideBar from '@/components/organisms/SideBar/SideBar';
import OptionBar from '@/components/organisms/OptionBar/OptionBar';
import MyContentList, {
@@ -8,7 +8,7 @@ import InfoList, { InfoItem } from '@/components/organisms/InfoList/InfoList';
import MyBalanceGameList, {
MyBalanceGameItem,
} from '@/components/organisms/MyBalanceGameList/MyBalanceGameList';
-import { OptionKeys, optionSets } from '@/constants/optionSets';
+import { OptionKeys } from '@/constants/optionSets';
import { useMyVotesQuery } from '@/hooks/api/mypages/useMyVotesQuery';
import { useMyCommentsQuery } from '@/hooks/api/mypages/useMyCommentsQuery';
import { useMyWrittensQuery } from '@/hooks/api/mypages/useMyWrittensQuery';
@@ -24,13 +24,21 @@ import { useMemberQuery } from '@/hooks/api/member/useMemberQuery';
import { useParseJwt } from '@/hooks/common/useParseJwt';
import MypageListSkeleton from '@/components/atoms/MypageListSkeleton/MypageListSkeleton';
import MypageCardSkeleton from '@/components/atoms/MypageCardSkeleton/MypageCardSkeleton';
+import { useMyPageOptions } from '@/hooks/mypages/useMyPageOptions';
import * as S from './MyPage.style';
const MyPage = () => {
+ const {
+ selectedGroup,
+ selectedOption,
+ options,
+ handleGroupSelect,
+ handleOptionSelect,
+ } = useMyPageOptions();
+
const accessToken = useNewSelector(selectAccessToken);
const { member } = useMemberQuery(useParseJwt(accessToken).memberId);
const memberId: number = member!.id;
-
const { memberInfo, isLoading } = useMyInfoQuery(memberId);
const myBookmarksQuery = useMyBookmarksQuery();
const myVotesQuery = useMyVotesQuery();
@@ -54,38 +62,29 @@ const MyPage = () => {
(query) => query.isLoading,
);
- const { ref, isFetchingAnyNextPage } = useObserver(queries);
-
- const [selectedGroup, setSelectedGroup] = useState
(
- OptionKeys.TALK_PICK,
- );
- const [selectedOption, setSelectedOption] = useState(
- optionSets[selectedGroup][0],
- );
-
- useEffect(() => {
- setSelectedOption(optionSets[selectedGroup][0]);
- }, [selectedGroup]);
+ const { ref } = useObserver(queries);
const queryResult = useMemo(() => {
if (selectedGroup === OptionKeys.TALK_PICK) {
switch (selectedOption) {
- case 'λ΄κ° μ μ₯ν':
+ case 'bookmarks':
return queries.myBookmarks.myBookmarks;
- case 'λ΄κ° ν¬νν':
+ case 'votes':
return queries.myVotes.myVote;
- case 'λ΄κ° λκΈλ¨':
+ case 'comments':
return queries.myComments.myComments;
- case 'λ΄κ° μμ±ν':
+ case 'written':
return queries.myWrittens.myWritten;
+ default:
+ return null;
}
} else if (selectedGroup === OptionKeys.BALANCE_GAME) {
switch (selectedOption) {
- case 'λ΄κ° μ μ₯ν':
+ case 'bookmarks':
return queries.gameBookmarks.gameBookmark;
- case 'λ΄κ° ν¬νν':
+ case 'votes':
return queries.gameVotes.gameVote;
- case 'λ΄κ° λ§λ ':
+ case 'written':
return queries.gameWrittens.gameWritten;
default:
return null;
@@ -95,13 +94,13 @@ const MyPage = () => {
}, [
selectedGroup,
selectedOption,
- myBookmarksQuery,
- myVotesQuery,
- myCommentsQuery,
- myWrittensQuery,
- gameBookmarksQuery,
- gameVotesQuery,
- gameWrittensQuery,
+ queries.myBookmarks.myBookmarks,
+ queries.myVotes.myVote,
+ queries.myComments.myComments,
+ queries.myWrittens.myWritten,
+ queries.gameBookmarks.gameBookmark,
+ queries.gameVotes.gameVote,
+ queries.gameWrittens.gameWritten,
]);
const renderContent = () => {
@@ -116,21 +115,15 @@ const MyPage = () => {
}
if (!queryResult) {
- return νμν νμ΄μ§κ° μμ΅λλ€
;
+ return null;
}
if (selectedGroup === OptionKeys.TALK_PICK) {
- if (
- selectedOption === 'λ΄κ° μ μ₯ν' ||
- selectedOption === 'λ΄κ° μμ±ν'
- ) {
+ if (selectedOption === 'bookmarks' || selectedOption === 'written') {
const content = queryResult.content as MyContentItem[];
return ;
}
- if (
- selectedOption === 'λ΄κ° ν¬νν' ||
- selectedOption === 'λ΄κ° λκΈλ¨'
- ) {
+ if (selectedOption === 'votes' || selectedOption === 'comments') {
const content = queryResult.content as InfoItem[];
return ;
}
@@ -139,7 +132,7 @@ const MyPage = () => {
return ;
}
- return νμν νμ΄μ§κ° μμ΅λλ€
;
+ return null;
};
return (
@@ -147,30 +140,18 @@ const MyPage = () => {
{isLoading ? (
) : (
- memberInfo && (
-
- )
+
)}
{renderContent()}
-
- {isFetchingAnyNextPage &&
Loading...
}
-
+
);
diff --git a/src/pages/SearchResultsPage/SearchGamePage.tsx b/src/pages/SearchResultsPage/SearchGamePage.tsx
index 84e7372d..f0ee4117 100644
--- a/src/pages/SearchResultsPage/SearchGamePage.tsx
+++ b/src/pages/SearchResultsPage/SearchGamePage.tsx
@@ -13,14 +13,14 @@ const SearchGamePage = () => {
const { query, handleSearch } = useSearchQuery();
const { selectedTag, handleTagClick } = useTagFilter('game');
const { page, handlePageChange } = usePagination();
- const { sort, handleSortChange } = useSort();
+ const { sort, handleSortChange } = useSort({ field: 'views', order: 'desc' });
const size = 9;
const {
content: gameResults,
totalPages: gameTotalPages,
isLoading,
- } = useGameResultQuery(query, page, size, sort);
+ } = useGameResultQuery(query, page - 1, size, sort);
return (
@@ -36,7 +36,7 @@ const SearchGamePage = () => {
{
const { query, handleSearch } = useSearchQuery();
const { selectedTag, handleTagClick } = useTagFilter('all');
+ const { sort } = useSort({ field: 'views', order: 'desc' });
const page = 0;
const size = 4;
- const sort = 'all';
const { content: talkPickResults, isLoading: isTalkPickLoading } =
useTalkPickResultQuery(query, page, size, sort);
diff --git a/src/pages/SearchResultsPage/SearchTalkPickPage.tsx b/src/pages/SearchResultsPage/SearchTalkPickPage.tsx
index 712edc79..39dab989 100644
--- a/src/pages/SearchResultsPage/SearchTalkPickPage.tsx
+++ b/src/pages/SearchResultsPage/SearchTalkPickPage.tsx
@@ -13,14 +13,14 @@ const SearchTalkPickPage = () => {
const { query, handleSearch } = useSearchQuery();
const { selectedTag, handleTagClick } = useTagFilter('talkpick');
const { page, handlePageChange } = usePagination();
- const { sort, handleSortChange } = useSort();
+ const { sort, handleSortChange } = useSort({ field: 'views', order: 'desc' });
const size = 10;
const {
content: talkPickResults,
totalPages: talkPickTotalPages,
isLoading,
- } = useTalkPickResultQuery(query, page, size, sort);
+ } = useTalkPickResultQuery(query, page - 1, size, sort);
return (
@@ -36,7 +36,7 @@ const SearchTalkPickPage = () => {
{
const [currentPage, setCurrentPage] = useState(1);
- const [selectedValue, setSelectedValue] = useState('trend');
+ const [selectedValue, setSelectedValue] = useState({
+ field: 'views',
+ order: 'desc',
+ });
const accessToken = useNewSelector(selectAccessToken);
const { member } = useMemberQuery(useParseJwt(accessToken).memberId);
@@ -36,11 +39,11 @@ const TalkPickPage = () => {
const toggleItem: ToggleGroupItem[] = [
{
label: 'μΈκΈ°μ',
- value: 'trend',
+ value: { field: 'views', order: 'desc' },
},
{
label: 'μ΅μ μ',
- value: 'recent',
+ value: { field: 'createdAt', order: 'desc' },
},
];
@@ -77,7 +80,9 @@ const TalkPickPage = () => {
{
- const [searchParams, setSearchParams] = useSearchParams();
- const [selectedValue, setSelectedValue] = useState('views');
-
- const initialPage = parseInt(searchParams.get('page') ?? '1', 10) || 1;
- const [currentPage, setCurrentPage] = useState(initialPage);
-
- useEffect(() => {
- setSearchParams((prevParams) => ({
- ...Object.fromEntries(prevParams.entries()),
- page: currentPage.toString(),
- }));
- }, [currentPage, setSearchParams]);
-
- const handlePageChange = (newPage: number) => {
- setCurrentPage(newPage);
- };
+ const { page, handlePageChange } = usePagination();
+ const [selectedValue, setSelectedValue] = useState({
+ field: 'views',
+ order: 'desc',
+ });
const { bestTalkPick } = useBestTalkPickListQuery();
const { talkPickList } = useTalkPickListQuery({
- page: currentPage - 1,
+ page: page - 1,
size: 20,
- sort: selectedValue,
+ sort: `${selectedValue.field},${selectedValue.order}`,
});
useEffect(() => {
window.scrollTo(0, 0);
- }, [currentPage, selectedValue]);
+ }, [page, selectedValue]);
return (
@@ -50,7 +40,7 @@ const TalkPickPlacePage = () => {
talkPickList={talkPickList}
selectedValue={selectedValue}
setToggleValue={setSelectedValue}
- selectedPage={currentPage}
+ selectedPage={page}
handlePageChange={handlePageChange}
/>
diff --git a/src/stories/atoms/Bookmark.stories.tsx b/src/stories/atoms/Bookmark.stories.tsx
index b5134678..5a26c915 100644
--- a/src/stories/atoms/Bookmark.stories.tsx
+++ b/src/stories/atoms/Bookmark.stories.tsx
@@ -11,10 +11,10 @@ const meta: Meta = {
},
tags: ['autodocs'],
argTypes: {
- bookmarkState: { control: 'boolean' },
+ bookmarked: { control: 'boolean' },
},
args: {
- bookmarkState: false,
+ bookmarked: false,
},
};
@@ -23,7 +23,7 @@ type Story = StoryObj;
export const Default: Story = {
args: {
- bookmarkState: false,
+ bookmarked: false,
},
};
@@ -32,10 +32,10 @@ export const All: Story = {
Default State
-
+
Pressed State
-
+
),
diff --git a/src/stories/atoms/CategoryButton.stories.tsx b/src/stories/atoms/CategoryButton.stories.tsx
index 737567bc..effcff4c 100644
--- a/src/stories/atoms/CategoryButton.stories.tsx
+++ b/src/stories/atoms/CategoryButton.stories.tsx
@@ -8,18 +8,20 @@ const meta: Meta = {
component: CategoryButton,
parameters: {
layout: 'centered',
+ viewport: { defaultViewport: 'tablet' },
},
- tags: ['autodocs'],
argTypes: {
imageType: {
options: ['PickVote', 'RandomGame', 'TodayPick'],
control: { type: 'radio' },
},
label: { control: { type: 'text' } },
+ isMobile: { control: { type: 'boolean' } },
},
args: {
imageType: 'PickVote',
label: 'Category Label',
+ isMobile: false,
},
};
@@ -46,3 +48,27 @@ export const All: Story = {
),
};
+
+export const Mobile: Story = {
+ parameters: {
+ viewport: {
+ defaultViewport: 'mobile',
+ },
+ },
+ render: () => (
+
+ -
+
λͺ¨λ°μΌ ν‘&ν½ νλ μ΄μ€
+
+
+ -
+
λͺ¨λ°μΌ λλ€ λ°Έλ°μ€ κ²μ
+
+
+
+ ),
+};
diff --git a/src/stories/atoms/SelectGroup.stories.tsx b/src/stories/atoms/SelectGroup.stories.tsx
index 6fb4d141..3938cb67 100644
--- a/src/stories/atoms/SelectGroup.stories.tsx
+++ b/src/stories/atoms/SelectGroup.stories.tsx
@@ -1,6 +1,8 @@
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-import SelectGroup from '@/components/atoms/SelectGroup/SelectGroup';
+import SelectGroup, {
+ SelectGroupItem,
+} from '@/components/atoms/SelectGroup/SelectGroup';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const meta = {
@@ -9,7 +11,6 @@ const meta = {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
argTypes: {
selectedValue: { control: 'text' },
onSelect: { action: 'selected' },
@@ -24,7 +25,7 @@ export const Default: Story = {
items: [
{ label: 'ν‘ν½', value: 'talkpick' },
{ label: 'λ°Έλ°μ€ κ²μ', value: 'balance' },
- ],
+ ] as [SelectGroupItem, SelectGroupItem],
selectedValue: 'talkpick',
},
};
@@ -34,7 +35,7 @@ export const All: Story = {
items: [
{ label: 'ν‘ν½', value: 'talkpick' },
{ label: 'λ°Έλ°μ€ κ²μ', value: 'balance' },
- ],
+ ] as [SelectGroupItem, SelectGroupItem],
selectedValue: 'talkpick',
},
render: (args) => {
diff --git a/src/stories/atoms/ToggleGroup.stories.tsx b/src/stories/atoms/ToggleGroup.stories.tsx
index 7fc7e4fc..67e30533 100644
--- a/src/stories/atoms/ToggleGroup.stories.tsx
+++ b/src/stories/atoms/ToggleGroup.stories.tsx
@@ -1,30 +1,28 @@
import React, { useState } from 'react';
-import ToggleGroup, {
- ToggleGroupItem,
- ToggleGroupProps,
-} from '@/components/atoms/ToggleGroup/ToggleGroup';
+import ToggleGroup from '@/components/atoms/ToggleGroup/ToggleGroup';
+import { ToggleGroupItem, ToggleGroupProps } from '@/types/toggle';
import type { Meta, StoryObj } from '@storybook/react';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const toggleOneTwo: ToggleGroupItem[] = [
{
label: 'ONE',
- value: 'ONE',
+ value: { field: 'one', order: 'asc' },
},
{
label: 'TWO',
- value: 'TWO',
+ value: { field: 'two', order: 'desc' },
},
];
const toggleItem: ToggleGroupItem[] = [
{
label: 'μΈκΈ°μ',
- value: 'views',
+ value: { field: 'views', order: 'desc' },
},
{
label: 'μ΅μ μ',
- value: 'createdAt',
+ value: { field: 'createdAt', order: 'desc' },
},
];
@@ -36,7 +34,7 @@ const meta = {
},
argTypes: {
selectedValue: {
- options: toggleOneTwo.map((item) => item.value),
+ options: toggleOneTwo.map((item) => item.value.field),
control: { type: 'radio' },
},
},
@@ -57,8 +55,9 @@ export const Default: Story = {
export const All: Story = {
render: () => {
- const [selectedValue, setSelectedValue] =
- useState('views');
+ const [selectedValue, setSelectedValue] = useState<
+ ToggleGroupProps['selectedValue']
+ >({ field: 'views', order: 'desc' });
return (
@@ -72,9 +71,9 @@ export const All: Story = {
-
Trend
-
+
Recent
-
+
);
diff --git a/src/stories/mobile/atoms/Button.stories.tsx b/src/stories/mobile/atoms/Button.stories.tsx
new file mode 100644
index 00000000..bc20c521
--- /dev/null
+++ b/src/stories/mobile/atoms/Button.stories.tsx
@@ -0,0 +1,76 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import Button from '@/components/mobile/atoms/Button/Button';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta = {
+ title: 'mobile/atoms/Button',
+ component: Button,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ size: {
+ options: ['large', 'medium'],
+ control: { type: 'radio' },
+ },
+ variant: {
+ options: ['primary', 'roundPrimary', 'Primary2', 'outlineShadow'],
+ control: { type: 'radio' },
+ },
+ active: { control: 'boolean' },
+ children: { control: { type: 'text' } },
+ },
+ args: {
+ variant: 'primary',
+ size: 'large',
+ children: 'Button',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ variant: 'primary',
+ size: 'large',
+ },
+};
+
+export const All: Story = {
+ render: () => (
+
+ -
+
Primary
+
+
+ roundPrimary
+
+ Primary2
+
+ outlineShadow
+
+
+ -
+
disabled
+
+
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/DraftSaveButton.stories.tsx b/src/stories/mobile/atoms/DraftSaveButton.stories.tsx
new file mode 100644
index 00000000..6212a3de
--- /dev/null
+++ b/src/stories/mobile/atoms/DraftSaveButton.stories.tsx
@@ -0,0 +1,28 @@
+/* eslint-disable no-console */
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import DraftSaveButton from '@/components/mobile/atoms/DraftSaveButton/DraftSaveButton';
+import { BrowserRouter } from 'react-router-dom';
+
+const meta: Meta = {
+ title: 'mobile/atoms/DraftSaveButton',
+ component: DraftSaveButton,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ onClick: { action: 'ν΄λ¦ μ΄λ²€νΈ λ°μ' },
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/atoms/FloatingButton.stories.tsx b/src/stories/mobile/atoms/FloatingButton.stories.tsx
new file mode 100644
index 00000000..85de7f04
--- /dev/null
+++ b/src/stories/mobile/atoms/FloatingButton.stories.tsx
@@ -0,0 +1,47 @@
+/* eslint-disable no-console */
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import FloatingButton from '@/components/mobile/atoms/FloatingButton/FloatingButton';
+import { BrowserRouter } from 'react-router-dom';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta: Meta = {
+ title: 'mobile/atoms/FloatingButton',
+ component: FloatingButton,
+ parameters: {
+ layout: 'centered',
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const All: Story = {
+ render: () => (
+
+ -
+
ν‘ν½
+ console.log('TalkPick button clicked')}
+ />
+
+ -
+
λ°Έλ°μ€ κ²μ
+ console.log('Game button clicked')}
+ />
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/GameStageLabel.stories.tsx b/src/stories/mobile/atoms/GameStageLabel.stories.tsx
new file mode 100644
index 00000000..e589dee9
--- /dev/null
+++ b/src/stories/mobile/atoms/GameStageLabel.stories.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import GameStageLabel from '@/components/mobile/atoms/GameStageLabel/GameStageLabel';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta = {
+ title: 'mobile/atoms/GameStageLabel',
+ component: GameStageLabel,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ color: {
+ options: ['main', 'default'],
+ control: { type: 'radio' },
+ },
+ stage: {
+ control: { type: 'range', min: 0, max: 9 },
+ },
+ },
+ args: {
+ stage: 3,
+ color: 'default',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const All: Story = {
+ render: (args) => (
+
+ -
+
default
+
+ main
+
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/GameTag.stories.tsx b/src/stories/mobile/atoms/GameTag.stories.tsx
new file mode 100644
index 00000000..6512e241
--- /dev/null
+++ b/src/stories/mobile/atoms/GameTag.stories.tsx
@@ -0,0 +1,21 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import GameTag from '@/components/mobile/atoms/GameTag/GameTag';
+
+const meta = {
+ title: 'mobile/atoms/GameTag',
+ component: GameTag,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ tag: { control: { type: 'text' } },
+ },
+ args: {
+ tag: '컀ν',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/atoms/GameTagChip.stories.tsx b/src/stories/mobile/atoms/GameTagChip.stories.tsx
new file mode 100644
index 00000000..3517e87c
--- /dev/null
+++ b/src/stories/mobile/atoms/GameTagChip.stories.tsx
@@ -0,0 +1,21 @@
+import type { Meta, StoryObj } from '@storybook/react';
+import GameTagChip from '@/components/mobile/atoms/GameTagChip/GameTagChip';
+
+const meta = {
+ title: 'mobile/atoms/GameTagChip',
+ component: GameTagChip,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ tag: { control: { type: 'text' } },
+ },
+ args: {
+ tag: 'νκ·Έ',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/atoms/IconButton.stories.tsx b/src/stories/mobile/atoms/IconButton.stories.tsx
new file mode 100644
index 00000000..67f2244a
--- /dev/null
+++ b/src/stories/mobile/atoms/IconButton.stories.tsx
@@ -0,0 +1,51 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import { MobileBookmarkDF, MobileShare } from '@/assets';
+import IconButton from '@/components/mobile/atoms/IconButton/IconButton';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta = {
+ title: 'mobile/atoms/IconButton',
+ component: IconButton,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ icon: {
+ control: { type: 'select' },
+ options: ['BookmarkDF', 'Share'],
+ mapping: {
+ BookmarkDF: ,
+ Share: ,
+ },
+ defaultValue: 'BookmarkDF',
+ },
+ },
+ args: {
+ icon: 'BookmarkDF',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ icon: ,
+ },
+};
+
+export const All: Story = {
+ render: (args) => (
+
+ -
+
λΆλ§ν¬ λ²νΌ
+
+
+ -
+
곡μ λ²νΌ
+ } />
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/InteractionButton.stories.tsx b/src/stories/mobile/atoms/InteractionButton.stories.tsx
new file mode 100644
index 00000000..7975aa57
--- /dev/null
+++ b/src/stories/mobile/atoms/InteractionButton.stories.tsx
@@ -0,0 +1,64 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import InteractionButton from '@/components/mobile/atoms/InteractionButton/InteractionButton';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+import { MobileBookmarkDF, MobileShare } from '@/assets';
+
+const meta = {
+ title: 'mobile/atoms/InteractionButton',
+ component: InteractionButton,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ buttonLabel: {
+ control: { type: 'text' },
+ defaultValue: 'μ΄ κ²μ μ λ² νΌμ΄ μ’μ?',
+ },
+ icon: {
+ control: { type: 'select' },
+ options: ['BookmarkDF', 'Share'],
+ mapping: {
+ BookmarkDF: ,
+ Share: ,
+ },
+ defaultValue: 'BookmarkDF',
+ },
+ iconLabel: { control: { type: 'text' }, defaultValue: 'μ μ₯νκΈ°' },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ buttonLabel: 'μ΄ κ²μ μ λ² νΌμ΄ μ’μ?',
+ icon: ,
+ iconLabel: 'μ μ₯νκΈ°',
+ },
+};
+
+export const All: Story = {
+ args: {
+ buttonLabel: 'μ΄ κ²μ μ λ² νΌμ΄ μ’μ?',
+ icon: ,
+ iconLabel: 'μ μ₯νκΈ°',
+ },
+ render: (args) => (
+
+ -
+
μ μ₯νκΈ° λ²νΌ
+
+
+ -
+
곡μ νκΈ° λ²νΌ
+ }
+ iconLabel="곡μ νκΈ°"
+ />
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/MobileSideMenu.stories.tsx b/src/stories/mobile/atoms/MobileSideMenu.stories.tsx
new file mode 100644
index 00000000..b9238b81
--- /dev/null
+++ b/src/stories/mobile/atoms/MobileSideMenu.stories.tsx
@@ -0,0 +1,33 @@
+/* eslint-disable no-console */
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import MobileSideMenu from '@/components/mobile/atoms/MobileSideMenu/MobileSideMenu';
+import { BrowserRouter } from 'react-router-dom';
+
+const meta: Meta = {
+ title: 'mobile/atoms/MobileSideMenu',
+ component: MobileSideMenu,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ isOpen: { type: 'boolean' },
+ accessToken: { type: 'string' },
+ handleLoginButton: { action: 'button clicked' },
+ setIsOpen: { action: 'setIsOpen called' },
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/atoms/MobileToggleGroup.stories.tsx b/src/stories/mobile/atoms/MobileToggleGroup.stories.tsx
new file mode 100644
index 00000000..c7698f9c
--- /dev/null
+++ b/src/stories/mobile/atoms/MobileToggleGroup.stories.tsx
@@ -0,0 +1,29 @@
+/* eslint-disable no-console */
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import MobileToggleGroup from '@/components/mobile/atoms/MobileToggleGroup/MobileToggleGroup';
+import { BrowserRouter } from 'react-router-dom';
+
+const meta = {
+ title: 'mobile/atoms/MobileToggleGroup',
+ component: MobileToggleGroup,
+ parameters: {
+ layout: 'centered',
+ },
+ args: {
+ selectedValue: { field: 'views', order: 'desc' },
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/atoms/Modal.stories.tsx b/src/stories/mobile/atoms/Modal.stories.tsx
new file mode 100644
index 00000000..bb564d99
--- /dev/null
+++ b/src/stories/mobile/atoms/Modal.stories.tsx
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import Modal from '@/components/mobile/atoms/Modal/Modal';
+import type { Meta, StoryObj } from '@storybook/react';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta = {
+ title: 'mobile/atoms/Modal',
+ component: Modal,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ action: {
+ options: ['share', 'tag', 'tempGame'],
+ control: { type: 'radio' },
+ },
+ isOpen: { control: { type: 'boolean' } },
+ hasCloseButton: { control: { type: 'boolean' } },
+ children: { control: { type: 'text' } },
+ },
+ args: {
+ isOpen: true,
+ children: 'Modal',
+ hasCloseButton: true,
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ isOpen: true,
+ action: 'share',
+ hasCloseButton: true,
+ },
+};
+
+export const All: Story = {
+ render: (args) => {
+ const [modalOpen, setModalOpen] = useState(true);
+ const handleCloseModal = () => setModalOpen(!modalOpen);
+
+ return (
+
+ -
+
Close Modal
+
+ Close Modal
+
+
+ -
+
Share
+
+ Share Modal
+
+ Tag
+
+ Tag Modal
+
+ TempGame
+
+ TempGame Modal
+
+
+
+ );
+ },
+};
diff --git a/src/stories/mobile/atoms/TempGameButton.stories.tsx b/src/stories/mobile/atoms/TempGameButton.stories.tsx
new file mode 100644
index 00000000..e68d7508
--- /dev/null
+++ b/src/stories/mobile/atoms/TempGameButton.stories.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import type { Meta, StoryObj } from '@storybook/react';
+import TempGameButton from '@/components/mobile/atoms/TempGameButton/TempGameButton';
+import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+
+const meta = {
+ title: 'mobile/atoms/TempGameButton',
+ component: TempGameButton,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ action: {
+ options: ['save', 'get'],
+ control: { type: 'radio' },
+ },
+ },
+ args: {
+ action: 'save',
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const All: Story = {
+ render: (args) => (
+
+ -
+
μμμ μ₯νκΈ°
+
+ μμμ μ₯ λΆλ¬μ€κΈ°
+
+
+
+ ),
+};
diff --git a/src/stories/mobile/atoms/TitleDescriptionField.stories.tsx b/src/stories/mobile/atoms/TitleDescriptionField.stories.tsx
new file mode 100644
index 00000000..4c62449f
--- /dev/null
+++ b/src/stories/mobile/atoms/TitleDescriptionField.stories.tsx
@@ -0,0 +1,24 @@
+/* eslint-disable no-console */
+import type { Meta, StoryObj } from '@storybook/react';
+import TitleDescriptionField from '@/components/mobile/atoms/TitleDescriptionField/TitleDescriptionField';
+
+const meta = {
+ title: 'mobile/atoms/TitleDescriptionField',
+ component: TitleDescriptionField,
+ parameters: { layout: 'centered' },
+ args: {
+ title: '100μ΅ λΆμ μ λ³μ¬ VS 무μΌνΌ μ°¨μμ°',
+ description: '',
+ onTitleChange: (e) => {
+ console.log('Title:', e.target.value);
+ },
+ onDescriptionChange: (e) => {
+ console.log('Description:', e.target.value);
+ },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/molecules/FloatingMenuButton.stories.tsx b/src/stories/mobile/molecules/FloatingMenuButton.stories.tsx
new file mode 100644
index 00000000..03c82c78
--- /dev/null
+++ b/src/stories/mobile/molecules/FloatingMenuButton.stories.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import store from '@/store';
+import type { Meta, StoryObj } from '@storybook/react';
+import { BrowserRouter as Router } from 'react-router-dom';
+import FloatingMenuButton from '@/components/mobile/molecules/FloatingMenuButton/FloatingMenuButton';
+import ReactQueryProvider from '@/providers/ReactQueryProvider';
+import { Provider } from 'react-redux';
+
+const meta = {
+ title: 'mobile/molecules/FloatingMenuButton',
+ component: FloatingMenuButton,
+ parameters: {
+ layout: 'centered',
+ },
+ decorators: [
+ (Story) => (
+
+
+
+
+
+
+
+ ),
+ ],
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/mobile/molecules/GameTagModal.stories.tsx b/src/stories/mobile/molecules/GameTagModal.stories.tsx
new file mode 100644
index 00000000..1b3d2c2c
--- /dev/null
+++ b/src/stories/mobile/molecules/GameTagModal.stories.tsx
@@ -0,0 +1,26 @@
+/* eslint-disable no-console */
+import GameTagModal from '@/components/mobile/molecules/GameTagModal/GameTagModal';
+import type { Meta, StoryObj } from '@storybook/react';
+
+const meta = {
+ title: 'mobile/molecules/GameTagModal',
+ component: GameTagModal,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ onTagSubmit: { action: 'tagSubmit' },
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ isOpen: true,
+ onTagSubmit: (mainTag: string, subTag: string) => {
+ console.log(`λ©μΈ νκ·Έ : ${mainTag}, μλΈ νκ·Έ : ${subTag}`);
+ },
+ },
+};
diff --git a/src/stories/mobile/molecules/ShareModal.stories.tsx b/src/stories/mobile/molecules/ShareModal.stories.tsx
new file mode 100644
index 00000000..689d842d
--- /dev/null
+++ b/src/stories/mobile/molecules/ShareModal.stories.tsx
@@ -0,0 +1,25 @@
+import ShareModal from '@/components/mobile/molecules/ShareModal/ShareModal';
+import type { Meta, StoryObj } from '@storybook/react';
+
+const meta = {
+ title: 'mobile/molecules/ShareModal',
+ component: ShareModal,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ isOpen: { control: { type: 'boolean' } },
+ },
+ args: {
+ isOpen: true,
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ isOpen: true,
+ },
+};
diff --git a/src/stories/mobile/molecules/TempGameModal.stories.tsx b/src/stories/mobile/molecules/TempGameModal.stories.tsx
new file mode 100644
index 00000000..ea8d3343
--- /dev/null
+++ b/src/stories/mobile/molecules/TempGameModal.stories.tsx
@@ -0,0 +1,23 @@
+import TempGameModal from '@/components/mobile/molecules/TempGameModal/TempGameModal';
+import type { Meta, StoryObj } from '@storybook/react';
+
+const meta = {
+ title: 'mobile/molecules/TempGameModal',
+ component: TempGameModal,
+ parameters: {
+ layout: 'centered',
+ },
+ argTypes: {
+ isOpen: { control: { type: 'boolean' } },
+ },
+ args: {
+ isOpen: true,
+ onGetGame: () => {},
+ onSaveGame: () => {},
+ },
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
diff --git a/src/stories/molecules/ActionBox.stories.tsx b/src/stories/molecules/ActionBox.stories.tsx
index 5e4ab985..95b0bb53 100644
--- a/src/stories/molecules/ActionBox.stories.tsx
+++ b/src/stories/molecules/ActionBox.stories.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { MemoryRouter } from 'react-router-dom';
import ActionBox from '@/components/molecules/ActionBox/ActionBox';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
@@ -15,15 +16,23 @@ const meta = {
export default meta;
type Story = StoryObj;
-export const Default: Story = {};
+export const Default: Story = {
+ render: () => (
+
+
+
+ ),
+};
export const All: Story = {
render: () => (
-
-
-
νλ λ΄μ, νμμ 보 μμ , νμνν΄ λ²νΌ
-
+
+
+
+
νλ λ΄μ, νμμ 보 μμ , νμνν΄ λ²νΌ
+
+
-
+
),
};
diff --git a/src/stories/molecules/ContentsButton.stories.tsx b/src/stories/molecules/ContentsButton.stories.tsx
index 6d92cb92..4d8623e0 100644
--- a/src/stories/molecules/ContentsButton.stories.tsx
+++ b/src/stories/molecules/ContentsButton.stories.tsx
@@ -10,7 +10,6 @@ const meta: Meta
= {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
argTypes: {
title: { control: 'text' },
mainTag: { control: 'text' },
@@ -18,6 +17,7 @@ const meta: Meta = {
bookmarked: { control: 'boolean' },
showBookmark: { control: 'boolean' },
size: { control: { type: 'radio' }, options: ['large', 'medium', 'small'] },
+ onClick: { action: 'ν΄λ¦ μ΄λ²€νΈ λ°μ' },
},
args: {
title: 'μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°',
diff --git a/src/stories/molecules/InfoBox.stories.tsx b/src/stories/molecules/InfoBox.stories.tsx
index 145b1a2f..fb3f13b5 100644
--- a/src/stories/molecules/InfoBox.stories.tsx
+++ b/src/stories/molecules/InfoBox.stories.tsx
@@ -9,13 +9,13 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
argTypes: {
title: { control: { type: 'text' } },
prefix: { control: { type: 'text' } },
commentContent: { control: { type: 'text' } },
commentCount: { control: { type: 'number' } },
bookmarks: { control: { type: 'number' } },
+ onClick: { action: 'ν΄λ¦ μ΄λ²€νΈ λ°μ' },
},
args: {
title: '맨λ μΌκ·Ό μκΈ 500 λκΈ°μ
VS μ£Ό4μΌ μκΈ 250 μΉΌν΄κ·Ό μ€μ',
@@ -40,10 +40,11 @@ export const Default: Story = {
};
export const All: Story = {
- render: () => (
+ render: (args) => (
-
-
= {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
argTypes: {
title: { control: { type: 'text' } },
commentCount: { control: { type: 'number' } },
bookmarks: { control: { type: 'number' } },
showBookmark: { control: { type: 'boolean' } },
bookmarked: { control: { type: 'boolean' } },
+ onClick: { action: 'ν΄λ¦ μ΄λ²€νΈ λ°μ' },
},
args: {
title: 'λ΄κ° μμ±ν κ²μκΈ',
@@ -40,10 +40,11 @@ export const Default: Story = {
};
export const All: Story = {
- render: () => (
+ render: (args) => (
= {
title: 'molecules/OptionSelector',
component: OptionSelector,
- tags: ['autodocs'],
argTypes: {
options: {
control: { type: 'object' },
},
selectedOption: {
control: { type: 'radio' },
- options: ['λ΄κ° μ μ₯ν', 'λ΄κ° ν¬νν', 'λ΄κ° λκΈλ¨', 'λ΄κ° μμ±ν'],
+ options: ['bookmarks', 'votes', 'comments', 'written'],
},
+ onSelect: { action: 'Option μ νλ¨' },
},
args: {
- options: ['λ΄κ° μ μ₯ν', 'λ΄κ° ν¬νν', 'λ΄κ° λκΈλ¨', 'λ΄κ° μμ±ν'],
- selectedOption: 'λ΄κ° λκΈλ¨',
- onSelect: (option: string) => console.log(`μ νλ νλͺ©μ ${option} μ
λλ€`),
+ options: [
+ { label: 'λ΄κ° μ μ₯ν', value: 'bookmarks' },
+ { label: 'λ΄κ° ν¬νν', value: 'votes' },
+ { label: 'λ΄κ° λκΈλ¨', value: 'comments' },
+ { label: 'λ΄κ° μμ±ν', value: 'written' },
+ ],
+ selectedOption: 'comments',
},
-} satisfies Meta;
+};
export default meta;
type Story = StoryObj;
export const Default: Story = {
args: {
- options: ['λ΄κ° μ μ₯ν', 'λ΄κ° ν¬νν', 'λ΄κ° λκΈλ¨', 'λ΄κ° μμ±ν'],
- selectedOption: 'λ΄κ° λκΈλ¨',
- onSelect: (option: string) => console.log(`μ νλ νλͺ©μ ${option} μ
λλ€`),
+ options: [
+ { label: 'λ΄κ° μ μ₯ν', value: 'bookmarks' },
+ { label: 'λ΄κ° ν¬νν', value: 'votes' },
+ { label: 'λ΄κ° λκΈλ¨', value: 'comments' },
+ { label: 'λ΄κ° μμ±ν', value: 'written' },
+ ],
+ selectedOption: 'comments',
},
};
export const All: Story = {
args: {
- options: ['λ΄κ° μ μ₯ν', 'λ΄κ° ν¬νν', 'λ΄κ° λκΈλ¨', 'λ΄κ° μμ±ν'],
- onSelect: (option: string) => console.log(`μ νλ νλͺ©μ ${option} μ
λλ€`),
+ options: [
+ { label: 'λ΄κ° μ μ₯ν', value: 'bookmarks' },
+ { label: 'λ΄κ° ν¬νν', value: 'votes' },
+ { label: 'λ΄κ° λκΈλ¨', value: 'comments' },
+ { label: 'λ΄κ° μμ±ν', value: 'written' },
+ ],
},
render: (args) => (
-
λ΄κ° μ μ₯ν Tab
-
+
-
λ΄κ° ν¬νν Tab
-
+
-
λ΄κ° λκΈλ¨ Tab
-
+
-
λ΄κ° μμ±ν Tab
-
+
),
diff --git a/src/stories/molecules/SearchGameList.stories.tsx b/src/stories/molecules/SearchGameList.stories.tsx
index c7be86f4..42441da3 100644
--- a/src/stories/molecules/SearchGameList.stories.tsx
+++ b/src/stories/molecules/SearchGameList.stories.tsx
@@ -1,6 +1,8 @@
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import SearchGameList from '@/components/molecules/SearchGameList/SearchGameList';
import { SampleFirst, SampleSecond } from '@/assets';
+import { MemoryRouter } from 'react-router-dom';
const meta: Meta = {
title: 'molecules/SearchGameList',
@@ -8,14 +10,12 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
};
export default meta;
type Story = StoryObj;
const gameListSample = {
- id: '',
optionAImg: SampleFirst,
optionBImg: SampleSecond,
title: 'μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°',
@@ -23,22 +23,42 @@ const gameListSample = {
subTag: 'μΌλ§λ λ§λ 보μ',
};
-export const Default: Story = {
- args: {
- gameList: Array.from({ length: 9 }, (_, index) => ({
- ...gameListSample,
- id: `game-${index + 1}`,
- title: `${index + 1}λ² - μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°`,
- })),
+const gameListDefault = Array.from({ length: 9 }, (_, index) => ({
+ ...gameListSample,
+ id: index + 1,
+ title: `${index + 1}λ² - μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°`,
+}));
+
+const gameListAll = [
+ {
+ ...gameListSample,
+ id: 1,
+ title: 'μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°',
+ },
+ {
+ ...gameListSample,
+ id: 2,
+ title: 'μ§μ₯μΈ VS λνμ μΆκ·Όλ£©',
+ },
+ {
+ ...gameListSample,
+ id: 3,
+ title: 'λ΄ VS κ°μ ν¨μ
μ ν',
},
+];
+
+export const Default: Story = {
+ render: (args) => (
+
+
+
+ ),
};
export const All: Story = {
- args: {
- gameList: Array.from({ length: 9 }, (_, index) => ({
- ...gameListSample,
- id: `game-${index + 1}`,
- title: `${index + 1}λ² - μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°`,
- })),
- },
+ render: (args) => (
+
+
+
+ ),
};
diff --git a/src/stories/molecules/SearchTalkPickList.stories.tsx b/src/stories/molecules/SearchTalkPickList.stories.tsx
index 41c632e2..32d74a02 100644
--- a/src/stories/molecules/SearchTalkPickList.stories.tsx
+++ b/src/stories/molecules/SearchTalkPickList.stories.tsx
@@ -2,90 +2,42 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { BrowserRouter } from 'react-router-dom';
+import { SearchTalkPickListItem } from '@/types/search';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
import SearchTalkPickList from '@/components/molecules/SearchTalkPickList/SearchTalkPickList';
import { SampleWhole } from '@/assets';
+const searchTalkPickSample: SearchTalkPickListItem[] = Array.from(
+ { length: 10 },
+ (_, index) => ({
+ id: 0,
+ title: `ν‘ν½ ${index + 1} - μΈκΈ° μμ`,
+ createdAt: '2024.08.26',
+ content:
+ 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
+ firstImgUrl: SampleWhole,
+ keyword: 'μΈκΈ°',
+ }),
+);
+
const meta = {
title: 'molecules/SearchTalkPickList',
component: SearchTalkPickList,
tags: ['autodocs'],
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
argTypes: {
searchTalkPickList: { control: { type: 'object' } },
},
args: {
- searchTalkPickList: [
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- {
- title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
- createdAt: '2024.08.26',
- content:
- 'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
- firstImgUrl: SampleWhole,
- },
- ],
+ searchTalkPickList: searchTalkPickSample,
+ keyword: 'μ°νν',
},
} satisfies Meta;
@@ -103,13 +55,16 @@ export const Default: Story = {
args: {
searchTalkPickList: [
{
+ id: 0,
title: 'μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°',
createdAt: '2024.08.26',
content:
'μ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°ννμ°νν',
firstImgUrl: SampleWhole,
+ keyword: 'μ°νν',
},
],
+ keyword: 'μ°νν',
},
};
@@ -119,7 +74,10 @@ export const All: Story = {
-
Single SearchTalkPickList
-
+
-
@@ -129,7 +87,7 @@ export const All: Story = {
-
None
-
+
),
diff --git a/src/stories/organisms/BalanceGameList.stories.tsx b/src/stories/organisms/BalanceGameList.stories.tsx
index 308ba1bf..96583ba8 100644
--- a/src/stories/organisms/BalanceGameList.stories.tsx
+++ b/src/stories/organisms/BalanceGameList.stories.tsx
@@ -1,8 +1,9 @@
-/* eslint-disable no-console */
-import React from 'react';
+import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import BalanceGameList from '@/components/organisms/BalanceGameList/BalanceGameList';
import { SampleFirst, SampleSecond } from '@/assets';
+import { MemoryRouter } from 'react-router-dom';
+import { ToggleGroupValue } from '@/types/toggle';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const meta: Meta = {
@@ -11,15 +12,18 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
-
argTypes: {
contents: {
control: 'object',
},
selectedValue: {
control: 'select',
- options: ['trend', 'recent'],
+ options: [
+ { field: 'views', order: 'desc' },
+ { field: 'createdAt', order: 'desc' },
+ ],
},
+
activeTab: {
control: 'select',
options: ['μΈκΈ°', '컀ν', 'μ·¨ν₯', 'μλμ»΅'],
@@ -44,10 +48,6 @@ const meta: Meta = {
bookmarkState: false,
},
],
- selectedValue: 'trend',
- activeTab: 'μΈκΈ°',
- setSelectedValue: (value) => console.log('setSelectedValue:', value),
- setActiveTab: (value) => console.log('setActiveTab:', value),
},
};
@@ -55,105 +55,106 @@ export default meta;
type Story = StoryObj;
export const Default: Story = {
- args: {
- contents: [
- {
- images: [SampleFirst, SampleSecond],
- id: 1,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: true,
- },
- {
- images: [SampleFirst, SampleSecond],
- id: 2,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: false,
- },
- ],
- selectedValue: 'trend',
- activeTab: 'μΈκΈ°',
- setSelectedValue: (value) => console.log('setSelectedValue:', value),
- setActiveTab: (value) => console.log('setActiveTab:', value),
- },
-};
+ render: (args) => {
+ const [selectedValue, setSelectedValue] = useState({
+ field: 'views',
+ order: 'desc',
+ });
+ const [activeTab, setActiveTab] = useState<
+ 'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅'
+ >('μΈκΈ°');
-export const All: Story = {
- render: (args) => (
-
- -
-
νλμ νλͺ©
- console.log('setSelectedValue:', value)}
- activeTab={args.activeTab}
- setActiveTab={(value) => console.log('setActiveTab:', value)}
- />
-
-
- -
-
λ€μμ νλͺ©
+ return (
+
console.log('setSelectedValue:', value)}
- setActiveTab={(value) => console.log('setActiveTab:', value)}
+ selectedValue={selectedValue}
+ setSelectedValue={setSelectedValue}
+ activeTab={activeTab}
+ setActiveTab={setActiveTab}
/>
-
+
+ );
+ },
+};
- -
-
λ΄μ© μμ
- console.log('setSelectedValue:', value)}
- activeTab={args.activeTab}
- setActiveTab={(value) => console.log('setActiveTab:', value)}
- />
-
-
- ),
- args: {
- contents: [
- {
- images: [SampleFirst, SampleSecond],
- id: 1,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: true,
- },
+export const All: Story = {
+ render: (args) => {
+ const [selectedValue, setSelectedValue] = useState({
+ field: 'views',
+ order: 'desc',
+ });
+ const [activeTab, setActiveTab] = useState<
+ 'μΈκΈ°' | '컀ν' | 'μ·¨ν₯' | 'μλμ»΅'
+ >('μΈκΈ°');
+
+ const scenarios = [
{
- images: [SampleFirst, SampleSecond],
- id: 2,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: false,
+ title: 'νλμ νλͺ©',
+ contents: [
+ {
+ images: [SampleFirst, SampleSecond],
+ id: 1,
+ title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
+ mainTag: 'μΈκΈ°',
+ subTag: 'νμ μ μ€μ¬',
+ bookmarkState: true,
+ },
+ ],
},
{
- images: [SampleFirst, SampleSecond],
- id: 3,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: false,
+ title: 'λ€μμ νλͺ©',
+ contents: [
+ {
+ images: [SampleFirst, SampleSecond],
+ id: 1,
+ title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
+ mainTag: 'μΈκΈ°',
+ subTag: 'νμ μ μ€μ¬',
+ bookmarkState: true,
+ },
+ {
+ images: [SampleFirst, SampleSecond],
+ id: 2,
+ title: 'μ’μ λλν λ²μ€ 2μκ° λ±κ΅ VS μμ κ±° 30λΆ λ±κ΅',
+ mainTag: '컀ν',
+ subTag: 'μ νμ κ³ λ―Ό',
+ bookmarkState: false,
+ },
+ {
+ images: [SampleFirst, SampleSecond],
+ id: 3,
+ title: '10λ
ν ν΄μ¬ VS λΉμ₯ ν΄μ¬',
+ mainTag: 'μ·¨ν₯',
+ subTag: 'κ³ λ―Όμ μκ°',
+ bookmarkState: true,
+ },
+ ],
},
{
- images: [SampleFirst, SampleSecond],
- id: 4,
- title: 'λ§μ μ§νμ² 1μκ° λ±κ΅ VS μ’μ λλν λ²μ€ 2μκ° λ±κ΅',
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- bookmarkState: false,
+ title: 'λ΄μ© μμ',
+ contents: [],
},
- ],
- selectedValue: 'trend',
- activeTab: 'μΈκΈ°',
- setSelectedValue: (value) => console.log('setSelectedValue:', value),
- setActiveTab: (value) => console.log('setActiveTab:', value),
+ ];
+
+ return (
+
+
+ {scenarios.map(({ title, contents }) => (
+ -
+
{title}
+
+
+ ))}
+
+
+ );
},
};
diff --git a/src/stories/organisms/CommentsSection.stories.tsx b/src/stories/organisms/CommentsSection.stories.tsx
index bb6d9c9c..eeffeab6 100644
--- a/src/stories/organisms/CommentsSection.stories.tsx
+++ b/src/stories/organisms/CommentsSection.stories.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import { ProfileSample } from '@/assets';
-import { ToggleGroupItem } from '@/components/atoms/ToggleGroup/ToggleGroup';
import type { Meta, StoryObj } from '@storybook/react';
import store from '@/store';
import { Provider } from 'react-redux';
import ReactQueryProvider from '@/providers/ReactQueryProvider';
import { Comment, CommentsPagination } from '@/types/comment';
import CommentsSection from '@/components/organisms/CommentsSection/CommentsSection';
+import { ToggleGroupItem } from '@/types/toggle';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const exampleCommentList: Comment[] = Array.from({ length: 7 }, (_, index) => ({
@@ -61,11 +61,11 @@ const exampleCommentPagination: CommentsPagination = {
const toggleItem: ToggleGroupItem[] = [
{
label: 'μΈκΈ°μ',
- value: 'trend',
+ value: { field: 'trend', order: 'desc' },
},
{
label: 'μ΅μ μ',
- value: 'recent',
+ value: { field: 'recent', order: 'desc' },
},
];
@@ -75,12 +75,11 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
- tags: ['autodocs'],
args: {
commentList: exampleCommentPagination,
voted: true,
toggleItem,
- selectedValue: 'trend',
+ selectedValue: { field: 'trend', order: 'desc' },
setToggleValue: () => {},
},
argTypes: {
diff --git a/src/stories/organisms/InfoList.stories.tsx b/src/stories/organisms/InfoList.stories.tsx
index fb3b0b3b..84c52b7a 100644
--- a/src/stories/organisms/InfoList.stories.tsx
+++ b/src/stories/organisms/InfoList.stories.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import InfoList from '@/components/organisms/InfoList/InfoList';
+import { MemoryRouter } from 'react-router-dom';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const meta = {
title: 'organisms/InfoList',
component: InfoList,
- tags: ['autodocs'],
argTypes: {
items: {
control: { type: 'object' },
@@ -17,7 +17,7 @@ const meta = {
{
id: 1,
editedAt: '2024.08.06',
- title: 'λ§€λ¬ μλ₯΄ μλ£ 500 λκΈ°μ
VS μ£Ό4μΌ μΌκΈ 250 μΉΌν΄κ·Ό μ€μ',
+ title: 'λ§€λ¬ μλ₯΄λ°μ΄νΈ μλ£ 500 λκΈ°μ
VS μ£Ό4μΌ μΌκΈ 250 μΉΌν΄κ·Ό μ€μ',
prefix: 'λ΄ λκΈ',
commentContent: 'λλ λ°λ₯ λ λ¦κ³ μ΄λνλκ² κΏμ΄λΌκ΅¬^^',
commentCount: 172,
@@ -26,9 +26,9 @@ const meta = {
{
id: 2,
editedAt: '2024.08.06',
- title: 'λ§€μΌ 5λ¬λ μμ VS λ§€μΌ μ©λ 10λ§μ μλΉ ',
+ title: 'λ§€μΌ 5λ¬λΌ μλΉ VS λ§€μΌ μ©λ 10λ§μ μλΉ ',
prefix: 'λ΄ λκΈ',
- commentContent: 'μμ κ³ μνμκ³ , 10λ§μμΌλ‘ λ°°λ¬μμ λ¨Ήμκ²μ',
+ commentContent: 'κ°λλ€λΌλ§λ°μ¬',
commentCount: 172,
bookmarks: 172,
},
@@ -41,15 +41,6 @@ const meta = {
commentCount: 172,
bookmarks: 172,
},
- {
- id: 4,
- editedAt: '2024.08.04',
- title: 'λ§μμ λ―Έμκ° μΆμ μ¬μΉ VS λ¨Ήλ°© BJ κΏλ무 μ§λ°₯ μ¬μΉ',
- prefix: 'λ΄ λκΈ',
- commentContent: 'μ§μν μ§λ°₯ μ§μ§ μ«λ€κ΅¬',
- commentCount: 172,
- bookmarks: 172,
- },
],
},
} satisfies Meta;
@@ -57,127 +48,35 @@ const meta = {
export default meta;
type Story = StoryObj;
-export const Default: Story = {
- args: {
+const groupedData = [
+ {
+ date: '2024.08.06',
items: [
{
- id: 1,
+ id: 22,
editedAt: '2024.08.06',
- title: 'λ§€λ¬ μλ₯΄ μλ£ 500 λκΈ°μ
VS μ£Ό4μΌ μΌκΈ 250 μΉΌν΄κ·Ό μ€μ',
+ title: 'λ§€λ¬ μλ₯΄λ°μ΄νΈ μλ£ 500 λκΈ°μ
VS μ£Ό4μΌ μΌκΈ 250 μΉΌν΄κ·Ό μ€μ',
prefix: 'λ΄ λκΈ',
commentContent: 'λλ λ°λ₯ λ λ¦κ³ μ΄λνλκ² κΏμ΄λΌκ΅¬^^',
commentCount: 172,
bookmarks: 172,
},
{
- id: 2,
+ id: 27,
editedAt: '2024.08.06',
- title: 'λ§€μΌ 5λ¬λ μμ VS λ§€μΌ μ©λ 10λ§μ μλΉ ',
- prefix: 'λ΄ λκΈ',
- commentContent: 'μμ κ³ μνμκ³ , 10λ§μμΌλ‘ λ°°λ¬μμ λ¨Ήμκ²μ',
- commentCount: 172,
- bookmarks: 172,
- },
- {
- id: 3,
- editedAt: '2024.08.05',
- title: 'λ§€μΌ μ μ·¨ν λ§μ·¨λ¨μΉ VS μμ μκ² μ·¨ν μμ·¨λ¨μΉ',
+ title: 'λ§€μΌ 5λ¬λΌ μλΉ VS λ§€μΌ μ©λ 10λ§μ μλΉ ',
prefix: 'λ΄ λκΈ',
- commentContent: 'λ§€μΌ λΉμ§ νΈλ¦¬λμ€...',
+ commentContent: 'κ°λλ€λΌλ§λ°μ¬',
commentCount: 172,
bookmarks: 172,
},
],
},
-};
-
-export const All: Story = {
- render: (args) => (
-
- -
-
2024.08.06
-
-
- -
-
2024.08.05
-
-
- -
-
2024.08.04
-
-
-
- ),
- args: {
+ {
+ date: '2024.08.05',
items: [
{
- id: 14,
- editedAt: '2024.08.06',
- title: 'λ§€λ¬ μλ₯΄ μλ£ 500 λκΈ°μ
VS μ£Ό4μΌ μΌκΈ 250 μΉΌν΄κ·Ό μ€μ',
- prefix: 'λ΄ λκΈ',
- commentContent: 'λλ λ°λ₯ λ λ¦κ³ μ΄λνλκ² κΏμ΄λΌκ΅¬^^',
- commentCount: 172,
- bookmarks: 172,
- },
- {
- id: 20,
- editedAt: '2024.08.06',
- title: 'λ§€μΌ 5λ¬λ μμ VS λ§€μΌ μ©λ 10λ§μ μλΉ ',
- prefix: 'λ΄ λκΈ',
- commentContent: 'μμ κ³ μνμκ³ , 10λ§μμΌλ‘ λ°°λ¬μμ λ¨Ήμκ²μ',
- commentCount: 172,
- bookmarks: 172,
- },
- {
- id: 25,
+ id: 29,
editedAt: '2024.08.05',
title: 'λ§€μΌ μ μ·¨ν λ§μ·¨λ¨μΉ VS μμ μκ² μ·¨ν μμ·¨λ¨μΉ',
prefix: 'λ΄ λκΈ',
@@ -185,10 +84,15 @@ export const All: Story = {
commentCount: 172,
bookmarks: 172,
},
+ ],
+ },
+ {
+ date: '2024.08.04',
+ items: [
{
- id: 35,
+ id: 33,
editedAt: '2024.08.04',
- title: 'λ§μμ λ―Έμκ° μΆμ μ¬μΉ VS λ¨Ήλ°© BJ κΏλ무 μ§λ°₯ μ¬μΉ',
+ title: 'λ§μμ λ―Έμκ° μ¬μΉ VS λ¨Ήλ°© BJ κΏλ무 μ§λ°₯ μ¬μΉ',
prefix: 'λ΄ λκΈ',
commentContent: 'μ§μν μ§λ°₯ μ§μ§ μ«λ€κ΅¬',
commentCount: 172,
@@ -196,4 +100,27 @@ export const All: Story = {
},
],
},
+];
+
+export const Default: Story = {
+ render: (args) => (
+
+
+
+ ),
+};
+
+export const All: Story = {
+ render: (args) => (
+
+
+ {groupedData.map(({ date, items }) => (
+ -
+
{date}
+
+
+ ))}
+
+
+ ),
};
diff --git a/src/stories/organisms/MyBalanceGameList.stories.tsx b/src/stories/organisms/MyBalanceGameList.stories.tsx
index a358ecc4..37a4bd91 100644
--- a/src/stories/organisms/MyBalanceGameList.stories.tsx
+++ b/src/stories/organisms/MyBalanceGameList.stories.tsx
@@ -2,12 +2,12 @@ import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import MyBalanceGameList from '@/components/organisms/MyBalanceGameList/MyBalanceGameList';
import { SampleFirst, SampleSecond } from '@/assets';
+import { MemoryRouter } from 'react-router-dom';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
const meta: Meta = {
title: 'organisms/MyBalanceGameList',
component: MyBalanceGameList,
- tags: ['autodocs'],
argTypes: {
items: {
control: { type: 'object' },
@@ -16,34 +16,34 @@ const meta: Meta = {
args: {
items: [
{
- id: 1,
+ gameId: 1,
editedAt: '2024.08.06',
title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
optionAImg: SampleFirst,
optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
+ mainTagName: 'μΈκΈ°',
subTag: 'νμ μ μ€μ¬',
showBookmark: true,
bookmarked: false,
},
{
- id: 2,
+ gameId: 2,
editedAt: '2024.08.06',
title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
optionAImg: SampleFirst,
optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
+ mainTagName: 'μΈκΈ°',
subTag: 'νμ μ μ€μ¬',
showBookmark: true,
bookmarked: true,
},
{
- id: 3,
+ gameId: 3,
editedAt: '2024.08.05',
title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
optionAImg: SampleFirst,
optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
+ mainTagName: 'μΈκΈ°',
subTag: 'νμ μ μ€μ¬',
showBookmark: false,
},
@@ -55,146 +55,77 @@ export default meta;
type Story = StoryObj;
export const Default: Story = {
- args: {
- items: [
- {
- id: 1,
- editedAt: '2024.08.06',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- optionAImg: SampleFirst,
- optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- showBookmark: true,
- bookmarked: false,
- },
- {
- id: 2,
- editedAt: '2024.08.06',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- optionAImg: SampleFirst,
- optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- showBookmark: true,
- bookmarked: true,
- },
- {
- id: 3,
- editedAt: '2024.08.05',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- optionAImg: SampleFirst,
- optionBImg: SampleSecond,
- mainTag: 'μΈκΈ°',
- subTag: 'νμ μ μ€μ¬',
- showBookmark: false,
- },
- ],
- },
+ render: (args) => (
+
+
+
+ ),
};
export const All: Story = {
render: (args) => (
-
-
-
2024.08.06
-
-
-
-
2024.08.05
-
+
+
+
+
2024.08.06
+
+
+
+
2024.08.05
+
+
-
+
),
};
diff --git a/src/stories/organisms/MyContentList.stories.tsx b/src/stories/organisms/MyContentList.stories.tsx
index 6a646c38..ba3225af 100644
--- a/src/stories/organisms/MyContentList.stories.tsx
+++ b/src/stories/organisms/MyContentList.stories.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { MemoryRouter } from 'react-router-dom';
import MyContentList from '@/components/organisms/MyContentList/MyContentList';
-import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
+import { storyContainer } from '@/stories/story.styles';
const meta = {
title: 'organisms/MyContentList',
component: MyContentList,
- tags: ['autodocs'],
argTypes: {
items: {
control: { type: 'object' },
@@ -48,83 +48,11 @@ export default meta;
type Story = StoryObj
;
export const Default: Story = {
- args: {
- items: [
- {
- id: 1,
- editedAt: '2024.08.06',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- commentCount: 172,
- bookmarks: 172,
- showBookmark: true,
- bookmarked: false,
- },
- {
- id: 2,
- editedAt: '2024.08.06',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- commentCount: 250,
- bookmarks: 200,
- showBookmark: true,
- bookmarked: true,
- },
- {
- id: 3,
- editedAt: '2024.08.05',
- title: 'μ μ§ μ¬λ³΅ ν¨μ
VS λ―Όμ§ μ¬λ³΅ ν¨μ
',
- commentCount: 100,
- bookmarks: 50,
- showBookmark: false,
- },
- ],
- },
-};
-
-export const All: Story = {
render: (args) => (
-
- -
-
2024.08.06
-
-
- -
-
2024.08.05
-
-
-
+
+
+
+
+
),
};
diff --git a/src/stories/organisms/OptionBar.stories.tsx b/src/stories/organisms/OptionBar.stories.tsx
index 1d98fb9a..a133ed76 100644
--- a/src/stories/organisms/OptionBar.stories.tsx
+++ b/src/stories/organisms/OptionBar.stories.tsx
@@ -1,20 +1,25 @@
-import React from 'react';
+import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import OptionBar from '@/components/organisms/OptionBar/OptionBar';
-import { OptionKeys } from '@/constants/optionSets';
+import { OptionKeys, optionSets } from '@/constants/optionSets';
const meta: Meta = {
title: 'organisms/OptionBar',
component: OptionBar,
- tags: ['autodocs'],
argTypes: {
- initialSelectedGroupValue: {
+ selectedGroup: {
control: { type: 'radio' },
options: [OptionKeys.TALK_PICK, OptionKeys.BALANCE_GAME],
},
+ selectedOption: {
+ control: { type: 'text' },
+ },
+ onGroupSelect: { action: 'κ·Έλ£Ή λ³κ²½' },
+ onOptionSelect: { action: 'μ΅μ
λ³κ²½' },
},
args: {
- initialSelectedGroupValue: OptionKeys.TALK_PICK,
+ selectedGroup: OptionKeys.TALK_PICK,
+ selectedOption: optionSets[OptionKeys.TALK_PICK][0].value,
},
};
@@ -22,35 +27,49 @@ export default meta;
type Story = StoryObj;
export const Default: Story = {
- args: {
- selectGroupItems: [
- { label: 'ν‘ν½', value: OptionKeys.TALK_PICK },
- { label: 'λ°Έλ°μ€ κ²μ', value: OptionKeys.BALANCE_GAME },
- ],
- initialSelectedGroupValue: OptionKeys.TALK_PICK,
+ render: (args) => {
+ const [selectedGroup, setSelectedGroup] = useState(
+ args.selectedGroup,
+ );
+ const [selectedOption, setSelectedOption] = useState(
+ args.selectedOption,
+ );
+
+ return (
+ {
+ setSelectedGroup(group);
+ setSelectedOption(optionSets[group][0].value);
+ args.onGroupSelect(group);
+ }}
+ onOptionSelect={(option) => {
+ setSelectedOption(option);
+ args.onOptionSelect(option);
+ }}
+ />
+ );
},
};
export const All: Story = {
render: (args) => (
-
ν‘ν½ μ νμ
+ ν‘ν½ μ ν μ
- λ°Έλ°μ€ κ²μ μ νμ
+ λ°Έλ°μ€ κ²μ μ ν μ
),
diff --git a/src/stories/organisms/SearchGameListSection.stories.tsx b/src/stories/organisms/SearchGameListSection.stories.tsx
index bb84bd06..b046ea58 100644
--- a/src/stories/organisms/SearchGameListSection.stories.tsx
+++ b/src/stories/organisms/SearchGameListSection.stories.tsx
@@ -1,7 +1,8 @@
-import React, { useState } from 'react';
+import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import SearchGameListSection from '@/components/organisms/SearchGameListSection/SearchGameListSection';
import { SampleFirst, SampleSecond } from '@/assets';
+import { MemoryRouter } from 'react-router-dom';
const meta: Meta = {
title: 'organisms/SearchGameListSection',
@@ -9,17 +10,28 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
+ argTypes: {
+ onPageChange: { action: 'νμ΄μ§ λ³κ²½' },
+ onSortChange: { action: 'μ λ ¬ λ³κ²½' },
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
};
export default meta;
type Story = StoryObj;
const gameListSample = Array.from({ length: 18 }, (_, index) => ({
- optionAImg: SampleFirst,
- optionBImg: SampleSecond,
+ id: index + 1,
title: `κ²μ ${index + 1} - μ μ§ VS λ―Όμ§ μ¬λ³΅ κ³ λ₯΄κΈ°`,
mainTag: 'μ·¨ν₯',
subTag: 'μΌλ§λ λ§λ 보μ',
+ images: [SampleFirst, SampleSecond],
}));
export const Default: Story = {
@@ -28,61 +40,7 @@ export const Default: Story = {
keyword: 'μμ ν€μλ',
selectedPage: 1,
totalPages: 2,
- sort: 'views',
+ sort: { field: 'views', order: 'desc' },
isLoading: false,
- onPageChange: (page) => console.log(`νμ΄μ§ λ³κ²½: ${page}`),
- onSortChange: (sort) => console.log(`μ λ ¬ λ³κ²½: ${sort}`),
- },
-};
-
-export const All: Story = {
- render: (args) => {
- const [sort, setSort] = useState('views');
-
- const handleSortChange = (newSort: string) => {
- setSort(newSort);
- console.log(`μ λ ¬ λ³κ²½: ${newSort}`);
- };
-
- return (
- <>
-
-
1νμ΄μ§
-
-
-
-
2νμ΄μ§
-
-
-
-
λ‘λ©μ€
-
-
- >
- );
},
};
diff --git a/src/stories/organisms/SearchTalkPickListSection.stories.tsx b/src/stories/organisms/SearchTalkPickListSection.stories.tsx
index e175f846..b4b59911 100644
--- a/src/stories/organisms/SearchTalkPickListSection.stories.tsx
+++ b/src/stories/organisms/SearchTalkPickListSection.stories.tsx
@@ -1,8 +1,10 @@
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { BrowserRouter } from 'react-router-dom';
import SearchTalkPickListSection from '@/components/organisms/SearchTalkPickListSection/SearchTalkPickListSection';
import { SampleWhole } from '@/assets';
-import { SearchTalkPickItemProps } from '@/components/atoms/SearchTalkPickItem/SearchTalkPickItem';
+import { SearchTalkPickListItem } from '@/types/search';
+import { ToggleGroupValue } from '@/types/toggle';
const meta: Meta = {
title: 'organisms/SearchTalkPickListSection',
@@ -10,14 +12,26 @@ const meta: Meta = {
parameters: {
layout: 'centered',
},
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+ argTypes: {
+ onPageChange: { action: 'νμ΄μ§ λ³κ²½' },
+ onSortChange: { action: 'μ λ ¬ λ³κ²½' },
+ },
};
export default meta;
type Story = StoryObj;
-const searchTalkPickSample: SearchTalkPickItemProps[] = Array.from(
+const searchTalkPickSample: SearchTalkPickListItem[] = Array.from(
{ length: 20 },
(_, index) => ({
+ id: 0,
title: `ν‘ν½ ${index + 1} - μΈκΈ° μμ`,
createdAt: '2024.08.26',
content:
@@ -30,22 +44,23 @@ const searchTalkPickSample: SearchTalkPickItemProps[] = Array.from(
export const Default: Story = {
args: {
searchTalkPickList: searchTalkPickSample.slice(0, 10),
- keyword: 'μμ ν€μλ',
+ keyword: 'μΈκΈ°',
selectedPage: 1,
totalPages: 2,
- sort: 'views',
- onPageChange: (page) => console.log(`νμ΄μ§ λ³κ²½: ${page}`),
- onSortChange: (sort) => console.log(`μ λ ¬ λ³κ²½: ${sort}`),
+ sort: { field: 'views', order: 'desc' },
},
};
export const All: Story = {
render: (args) => {
- const [sort, setSort] = useState('views');
+ const [sort, setSort] = useState({
+ field: 'views',
+ order: 'desc',
+ });
- const handleSortChange = (newSort: string) => {
+ const handleSortChange = (newSort: ToggleGroupValue) => {
setSort(newSort);
- console.log(`μ λ ¬ λ³κ²½: ${newSort}`);
+ args.onSortChange?.(newSort);
};
return (
diff --git a/src/stories/organisms/SearchTalkPickResult.stories.tsx b/src/stories/organisms/SearchTalkPickResult.stories.tsx
index 8333b13f..efd99d26 100644
--- a/src/stories/organisms/SearchTalkPickResult.stories.tsx
+++ b/src/stories/organisms/SearchTalkPickResult.stories.tsx
@@ -1,13 +1,14 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { SearchTalkPickListItem } from '@/types/search';
import SearchTalkPickResult from '@/components/organisms/SearchTalkPickResult/SearchTalkPickResult';
import { BrowserRouter } from 'react-router-dom';
import { SampleWhole } from '@/assets';
-import type { SearchTalkPickItemProps } from '@/components/atoms/SearchTalkPickItem/SearchTalkPickItem';
-const SearchTalkPickItems: SearchTalkPickItemProps[] = Array.from(
+const SearchTalkPickItems: SearchTalkPickListItem[] = Array.from(
{ length: 4 },
(_, index) => ({
+ id: 0,
title: `ν‘ν½ ${index + 1} - μν΄ μ κ΅ VS μ‘΄μ μ°¨μμ°`,
createdAt: '2024.08.26',
content: 'μ°ννμ°νν λ΄μ©μ
λλ€.',
diff --git a/src/stories/organisms/SideBar.stories.tsx b/src/stories/organisms/SideBar.stories.tsx
index e60610b6..7d055c68 100644
--- a/src/stories/organisms/SideBar.stories.tsx
+++ b/src/stories/organisms/SideBar.stories.tsx
@@ -1,6 +1,9 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-import SideBar from '@/components/organisms/SideBar/SideBar';
+import { MemoryRouter } from 'react-router-dom';
+import SideBar, {
+ LoadedSideBarProps,
+} from '@/components/organisms/SideBar/SideBar';
import { storyContainer, storyInnerContainer } from '@/stories/story.styles';
import { ProfileInfoSample } from '@/assets';
@@ -32,54 +35,63 @@ export const Default: Story = {
postsCount: 23,
bookmarkedPostsCount: 21,
isLoading: false,
- },
+ } as LoadedSideBarProps,
+ render: (args) => (
+
+
+
+ ),
};
export const All: Story = {
render: (args) => (
-
- -
-
κΈ°λ³Έ SideBar
-
-
- -
-
νλ‘ν μ΄λ―Έμ§ μλ κ²½μ°(settingsλ normalλ‘ μ€μ )
-
-
- -
-
κ²μκΈ μΉ΄μ΄νΈμ μ μ₯ν κΈ μΉ΄μ΄νΈ λ€λ₯Έ κ²½μ°
-
-
- -
-
λ‘λ©μ€μΈ κ²½μ°
-
-
-
+
+
+ -
+
κΈ°λ³Έ SideBar
+
+
+ -
+
νλ‘ν μ΄λ―Έμ§ μλ κ²½μ°
+
+
+ -
+
κ²μκΈ μΉ΄μ΄νΈμ μ μ₯ν κΈ μΉ΄μ΄νΈ λ€λ₯Έ κ²½μ°
+
+
+ -
+
λ‘λ©μ€μΈ κ²½μ°
+
+
+
+
),
args: {
+ isLoading: false,
nickname: 'Aycho',
profileImageUrl: ProfileInfoSample,
postsCount: 23,
bookmarkedPostsCount: 21,
- isLoading: false,
- },
+ } as LoadedSideBarProps,
};
diff --git a/src/stories/organisms/TalkPickListSection.stories.tsx b/src/stories/organisms/TalkPickListSection.stories.tsx
index a6672f71..ab461495 100644
--- a/src/stories/organisms/TalkPickListSection.stories.tsx
+++ b/src/stories/organisms/TalkPickListSection.stories.tsx
@@ -58,7 +58,7 @@ const meta = {
},
args: {
talkPickList: exampleTalkPickPagination,
- selectedValue: 'views',
+ selectedValue: { field: 'views', order: 'desc' },
setToggleValue: () => {},
selectedPage: 1,
handlePageChange: () => {},
diff --git a/src/styles/color.ts b/src/styles/color.ts
index d93c4917..42f3bc75 100644
--- a/src/styles/color.ts
+++ b/src/styles/color.ts
@@ -5,8 +5,8 @@ const color = {
1: '#8C8C8C',
2: '#D9D9D9',
3: '#F1F1F1',
- 4: '#555555',
- 5: '#DEDEDE',
+ 4: '#E6E9EF',
+ 5: '#F6F7F9',
},
WT: '#FFFFFF',
WT_VIOLET: '#F2F3FF',
diff --git a/src/types/game.ts b/src/types/game.ts
index cc4738d9..f20ffee3 100644
--- a/src/types/game.ts
+++ b/src/types/game.ts
@@ -50,6 +50,12 @@ export interface GamesPagination extends PaginationType {
content: GameContent[];
}
+export interface GameParams {
+ page: number;
+ size: number;
+ tagName?: string;
+}
+
export interface BalanceGameOption {
id: number;
name: string;
@@ -76,6 +82,7 @@ export interface TempGameOption {
name: string;
description: string;
fileId?: number | null;
+ imgUrl?: string;
optionType: 'A' | 'B';
}
diff --git a/src/types/mypages.ts b/src/types/mypages.ts
index f48322c0..b6f65cef 100644
--- a/src/types/mypages.ts
+++ b/src/types/mypages.ts
@@ -1,4 +1,3 @@
-import { SideBarProps } from '@/components/organisms/SideBar/SideBar';
import { InfoItem } from '@/components/organisms/InfoList/InfoList';
import { MyContentItem } from '@/components/organisms/MyContentList/MyContentList';
import { MyBalanceGameItem } from '@/components/organisms/MyBalanceGameList/MyBalanceGameList';
@@ -31,4 +30,11 @@ export interface GameBookmark extends PaginationType {
content: MyBalanceGameItem[];
}
-export interface SideBar extends SideBarProps {}
+export interface SideBar {
+ id: number;
+ nickname: string;
+ profileImageUrl: string;
+ createdAt: string;
+ postsCount: number;
+ bookmarkedPostsCount: number;
+}
diff --git a/src/types/search.ts b/src/types/search.ts
index eaa82178..eafd90a5 100644
--- a/src/types/search.ts
+++ b/src/types/search.ts
@@ -1,6 +1,7 @@
import { PaginationType } from '@/types/pagination';
-interface GameItem {
+export interface GameListItem {
+ gameSetId: number;
optionAImg: string;
optionBImg: string;
title: string;
@@ -8,7 +9,8 @@ interface GameItem {
subTag: string;
}
-interface SearchTalkPickItem {
+export interface SearchTalkPickListItem {
+ id: number;
title: string;
createdAt: string;
content: string;
@@ -17,11 +19,11 @@ interface SearchTalkPickItem {
}
export interface TalkPickResult extends PaginationType {
- content: SearchTalkPickItem[];
+ content: SearchTalkPickListItem[];
query: string;
}
export interface GameResult extends PaginationType {
- content: GameItem[];
+ content: GameListItem[];
query: string;
}
diff --git a/src/types/toggle.ts b/src/types/toggle.ts
new file mode 100644
index 00000000..1cd920b2
--- /dev/null
+++ b/src/types/toggle.ts
@@ -0,0 +1,15 @@
+export type ToggleGroupValue = {
+ field: string;
+ order: 'asc' | 'desc';
+};
+
+export type ToggleGroupItem = {
+ label: string;
+ value: ToggleGroupValue;
+};
+
+export interface ToggleGroupProps {
+ items?: ToggleGroupItem[];
+ selectedValue?: ToggleGroupValue;
+ onClick?: (value: ToggleGroupValue) => void;
+}
diff --git a/src/utils/balanceGameUtils.ts b/src/utils/balanceGameUtils.ts
index 42e89054..d3386e98 100644
--- a/src/utils/balanceGameUtils.ts
+++ b/src/utils/balanceGameUtils.ts
@@ -8,7 +8,7 @@ export const createInitialGameStages = (totalStage: number): BalanceGameSet[] =>
id: idx * 2,
name: '',
imgUrl: '',
- fileId: 0,
+ fileId: null,
description: '',
optionType: 'A',
},
@@ -16,7 +16,7 @@ export const createInitialGameStages = (totalStage: number): BalanceGameSet[] =>
id: idx * 2 + 1,
name: '',
imgUrl: '',
- fileId: 0,
+ fileId: null,
description: '',
optionType: 'B',
},
diff --git a/src/utils/cookie.ts b/src/utils/cookie.ts
new file mode 100644
index 00000000..4ec56543
--- /dev/null
+++ b/src/utils/cookie.ts
@@ -0,0 +1,9 @@
+export const getCookie = (name: string): string | null => {
+ const cookies = document.cookie.split('; ');
+ const cookie = cookies.find((c) => c.startsWith(`${name}=`));
+ return cookie ? cookie.split('=')[1] : null;
+};
+
+export const deleteCookie = (name: string): void => {
+ document.cookie = `${name}=; path=/; max-age=0;`;
+};
diff --git a/src/utils/validateUrlParam.ts b/src/utils/validateUrlParam.ts
new file mode 100644
index 00000000..479e1db2
--- /dev/null
+++ b/src/utils/validateUrlParam.ts
@@ -0,0 +1,16 @@
+/**
+ * URLμμ κ°μ Έμ¨ νλΌλ―Έν° κ°μ κ²μ¦νκ³ , μ ν¨νμ§ μμ κ²½μ° κΈ°λ³Έκ°μ λ°νν©λλ€.
+ *
+ * @template T - νλΌλ―Έν° κ°μ νμ
(μ: λ¬Έμμ΄)
+ * @param param - URLμμ κ°μ Έμ¨ νλΌλ―Έν° κ° (string | null)
+ * @param defaultValue - κΈ°λ³Έκ°μΌλ‘ λ°νν κ°
+ * @param isValid - νλΌλ―Έν° κ°μ μ ν¨μ±μ κ²μ¬νλ ν¨μ
+ * @returns κ²μ¦λ νλΌλ―Έν° κ° λλ κΈ°λ³Έκ°
+ */
+export const validateUrlParam = (
+ param: string | null,
+ defaultValue: T,
+ isValid: (value: string) => boolean,
+): T => {
+ return param && isValid(param) ? (param as T) : defaultValue;
+};