From 77c24b62d7b9220dcd4a9ecddec295ff3513721c Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 7 Nov 2024 02:42:41 +0900 Subject: [PATCH 001/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20prettier-plugin?= =?UTF-8?q?-tailwindcss=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc | 3 ++- packages/frontend/package.json | 1 + yarn.lock | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index 572c8dfc..96a79bf3 100644 --- a/.prettierrc +++ b/.prettierrc @@ -6,5 +6,6 @@ "printWidth": 80, "bracketSpacing": true, "endOfLine": "lf", - "useTabs": false + "useTabs": false, + "plugins": ["prettier-plugin-tailwindcss"] } diff --git a/packages/frontend/package.json b/packages/frontend/package.json index ce58b019..16886732 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -27,6 +27,7 @@ "eslint-plugin-react-refresh": "^0.4.14", "globals": "^15.11.0", "postcss": "^8.4.47", + "prettier-plugin-tailwindcss": "^0.6.8", "tailwindcss": "^3.4.14", "typescript": "~5.6.2", "typescript-eslint": "^8.11.0", diff --git a/yarn.lock b/yarn.lock index aee7506c..28e604e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5665,6 +5665,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" +prettier-plugin-tailwindcss@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.8.tgz#8a178e1679e3f941cc9de396f109c6cffea676d8" + integrity sha512-dGu3kdm7SXPkiW4nzeWKCl3uoImdd5CTZEJGxyypEPL37Wj0HT2pLqjrvSei1nTeuQfO4PUfjeW5cTUNRLZ4sA== + prettier@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" From b42e6ff8f18c4e222fb6af4657f36ae827b66129 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 7 Nov 2024 02:43:13 +0900 Subject: [PATCH 002/209] =?UTF-8?q?=E2=9C=A8=20feat:=20typography=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/index.css | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index b5c61c95..5760afac 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -1,3 +1,54 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@font-face { + font-family: 'Pretendard-Regular'; + src: url('https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') + format('woff'); + font-weight: 400; + font-style: normal; +} + +@layer base { + html { + font-family: 'Pretendard-Regular'; + background-color: #f0f0f0; + } +} + +.display-bold24 { + @apply text-2xl font-bold; +} + +.display-bold20 { + @apply text-xl font-bold; +} + +.display-bold16 { + @apply text-base font-bold; +} + +.display-bold14 { + @apply text-sm font-bold; +} + +.display-bold12 { + @apply text-xs font-bold; +} + +.display-medium20 { + @apply text-xl; +} + +.display-medium16 { + @apply text-base; +} + +.display-medium14 { + @apply text-sm; +} + +.display-medium12 { + @apply text-xs; +} From a21ca290f4701711e419c1afe178374917f7c46b Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 7 Nov 2024 02:44:25 +0900 Subject: [PATCH 003/209] =?UTF-8?q?=E2=9C=A8=20feat:=20light=20mode?= =?UTF-8?q?=EC=9D=98=20color=20system=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/tailwind.config.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index d21f1cda..8d518381 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -3,6 +3,18 @@ export default { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: {}, + colors: { + 'light-gray': '#d9d9d9', + gray: '#8c8c8c', + 'dark-gray': '#4f4f4f', + black: '#000000', + 'light-yellow': '#ffdcac', + 'light-orange': '#ffcfac', + orange: '#ffa868', + red: '#eb3636', + green: '#7eeb7e', + blue: '#3675eb', + }, }, plugins: [], }; From 098caa5437be9a000e8f7b1c3703b5a306c4f869 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Sun, 10 Nov 2024 22:05:09 +0900 Subject: [PATCH 004/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=EC=97=90=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80,=20SVG=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/public/logo.png | Bin 0 -> 30746 bytes packages/frontend/public/title.png | Bin 0 -> 4161 bytes packages/frontend/src/assets/bell.svg.tsx | 24 ++++++++++++++++++ .../frontend/src/assets/darkLight.svg.tsx | 20 +++++++++++++++ packages/frontend/src/assets/graph.svg.tsx | 14 ++++++++++ packages/frontend/src/assets/home.svg.tsx | 16 ++++++++++++ packages/frontend/src/assets/search.svg.tsx | 16 ++++++++++++ packages/frontend/src/assets/user.svg.tsx | 16 ++++++++++++ 8 files changed, 106 insertions(+) create mode 100644 packages/frontend/public/logo.png create mode 100644 packages/frontend/public/title.png create mode 100644 packages/frontend/src/assets/bell.svg.tsx create mode 100644 packages/frontend/src/assets/darkLight.svg.tsx create mode 100644 packages/frontend/src/assets/graph.svg.tsx create mode 100644 packages/frontend/src/assets/home.svg.tsx create mode 100644 packages/frontend/src/assets/search.svg.tsx create mode 100644 packages/frontend/src/assets/user.svg.tsx diff --git a/packages/frontend/public/logo.png b/packages/frontend/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4b821503c584bde829af954ce44b38988c7738e6 GIT binary patch literal 30746 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 LNkvXXu0mjfCH^;n literal 0 HcmV?d00001 diff --git a/packages/frontend/src/assets/bell.svg.tsx b/packages/frontend/src/assets/bell.svg.tsx new file mode 100644 index 00000000..f5550f07 --- /dev/null +++ b/packages/frontend/src/assets/bell.svg.tsx @@ -0,0 +1,24 @@ +const BellSvg = () => ( + + {'bell-line'} + + + + +); +export default BellSvg; diff --git a/packages/frontend/src/assets/darkLight.svg.tsx b/packages/frontend/src/assets/darkLight.svg.tsx new file mode 100644 index 00000000..4bab235c --- /dev/null +++ b/packages/frontend/src/assets/darkLight.svg.tsx @@ -0,0 +1,20 @@ +export function DarkLightSVG() { + return ( + + + + + ); +} \ No newline at end of file diff --git a/packages/frontend/src/assets/graph.svg.tsx b/packages/frontend/src/assets/graph.svg.tsx new file mode 100644 index 00000000..55f712a1 --- /dev/null +++ b/packages/frontend/src/assets/graph.svg.tsx @@ -0,0 +1,14 @@ +const Graph = () => ( + + + + +); +export default Graph; \ No newline at end of file diff --git a/packages/frontend/src/assets/home.svg.tsx b/packages/frontend/src/assets/home.svg.tsx new file mode 100644 index 00000000..bda589fa --- /dev/null +++ b/packages/frontend/src/assets/home.svg.tsx @@ -0,0 +1,16 @@ +const HomeSvg = () => ( + + + + + +); +export default HomeSvg; \ No newline at end of file diff --git a/packages/frontend/src/assets/search.svg.tsx b/packages/frontend/src/assets/search.svg.tsx new file mode 100644 index 00000000..4d16aa54 --- /dev/null +++ b/packages/frontend/src/assets/search.svg.tsx @@ -0,0 +1,16 @@ +const SearchSvg = () => ( + + + +); +export default SearchSvg; diff --git a/packages/frontend/src/assets/user.svg.tsx b/packages/frontend/src/assets/user.svg.tsx new file mode 100644 index 00000000..f3c35b32 --- /dev/null +++ b/packages/frontend/src/assets/user.svg.tsx @@ -0,0 +1,16 @@ +export function UserSvg() { + return ( + + + + + + + ); +} \ No newline at end of file From ab4c749b1759f5adffa4dc70b5e81999dea63947 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Sun, 10 Nov 2024 22:05:41 +0900 Subject: [PATCH 005/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/component/navigationBlock.tsx | 45 +++++++++++++++++++ packages/frontend/tailwind.config.js | 1 + 2 files changed, 46 insertions(+) create mode 100644 packages/frontend/src/component/navigationBlock.tsx diff --git a/packages/frontend/src/component/navigationBlock.tsx b/packages/frontend/src/component/navigationBlock.tsx new file mode 100644 index 00000000..30d1b73d --- /dev/null +++ b/packages/frontend/src/component/navigationBlock.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import SearchSvg from '@/assets/search.svg.tsx'; + +interface NavItemProps { + SvgComponent: React.FC; + label: string; + isOpen: boolean; +} + +const boxClassName = + 'hover:bg-orange flex h-full w-full items-center gap-4 rounded-xl transition-colors duration-500'; + +export const NavigationBlock: React.FC = ({ + SvgComponent, + label, + isOpen, +}) => { + return ( +
  • + + + + {label} + + +
  • + ); +}; + +export const SearchBox: React.FC = () => { + return ( +
  • + + + + +
  • + ); +}; \ No newline at end of file diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index 8d518381..9664e646 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -14,6 +14,7 @@ export default { red: '#eb3636', green: '#7eeb7e', blue: '#3675eb', + white: '#ffffff', }, }, plugins: [], From d3b84b15029ea6d453d5614196dbae9c5e0b9d40 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Sun, 10 Nov 2024 22:06:04 +0900 Subject: [PATCH 006/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=84=A4=EB=B9=84?= =?UTF-8?q?=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/component/navigation.tsx | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 packages/frontend/src/component/navigation.tsx diff --git a/packages/frontend/src/component/navigation.tsx b/packages/frontend/src/component/navigation.tsx new file mode 100644 index 00000000..c618c7a8 --- /dev/null +++ b/packages/frontend/src/component/navigation.tsx @@ -0,0 +1,81 @@ +import { useState } from 'react'; +import BellSvg from '@/assets/bell.svg.tsx'; +import { DarkLightSVG } from '@/assets/darkLight.svg.tsx'; +import GraphSvg from '@/assets/graph.svg.tsx'; +import HomeSvg from '@/assets/home.svg.tsx'; +import { UserSvg } from '@/assets/user.svg.tsx'; +import { NavigationBlock, SearchBox } from '@/component/navigationBlock.tsx'; + +export const Navigation = () => { + const [isOpen, setIsOpen] = useState(false); + + const toggleSidebar = () => { + setIsOpen(!isOpen); + }; + return ( +
    + +
    + ); +}; \ No newline at end of file From 0120383962707bfcc7d9edae5df83a01f0229cf4 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:38:54 +0900 Subject: [PATCH 007/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20svg=EB=A5=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=B2=98=EB=9F=BC=20?= =?UTF-8?q?=EB=B6=88=EB=9F=AC=EC=98=AC=20=EC=88=98=20=EC=9E=88=EA=B2=8C=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 3 ++- packages/frontend/src/assets/plus.svg | 3 +++ packages/frontend/src/assets/send.svg | 3 +++ packages/frontend/src/vite-env.d.ts | 1 + packages/frontend/svg.d.ts | 4 ++++ packages/frontend/tsconfig.node.json | 3 ++- packages/frontend/vite.config.ts | 7 ++++--- 7 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 packages/frontend/src/assets/plus.svg create mode 100644 packages/frontend/src/assets/send.svg create mode 100644 packages/frontend/svg.d.ts diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 16886732..f01f0016 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -31,6 +31,7 @@ "tailwindcss": "^3.4.14", "typescript": "~5.6.2", "typescript-eslint": "^8.11.0", - "vite": "^5.4.10" + "vite": "^5.4.10", + "vite-plugin-svgr": "^4.3.0" } } diff --git a/packages/frontend/src/assets/plus.svg b/packages/frontend/src/assets/plus.svg new file mode 100644 index 00000000..66ab1ddc --- /dev/null +++ b/packages/frontend/src/assets/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/assets/send.svg b/packages/frontend/src/assets/send.svg new file mode 100644 index 00000000..a37a73f3 --- /dev/null +++ b/packages/frontend/src/assets/send.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/vite-env.d.ts b/packages/frontend/src/vite-env.d.ts index 11f02fe2..7bdee965 100644 --- a/packages/frontend/src/vite-env.d.ts +++ b/packages/frontend/src/vite-env.d.ts @@ -1 +1,2 @@ /// +/// diff --git a/packages/frontend/svg.d.ts b/packages/frontend/svg.d.ts new file mode 100644 index 00000000..ea669257 --- /dev/null +++ b/packages/frontend/svg.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: React.FC>; + export default content; +} diff --git a/packages/frontend/tsconfig.node.json b/packages/frontend/tsconfig.node.json index abcd7f0d..522b48f8 100644 --- a/packages/frontend/tsconfig.node.json +++ b/packages/frontend/tsconfig.node.json @@ -5,6 +5,7 @@ "lib": ["ES2023"], "module": "ESNext", "skipLibCheck": true, + "types": ["vite-plugin-svgr/client"], /* Bundler mode */ "moduleResolution": "Bundler", @@ -20,5 +21,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["vite.config.ts"] + "include": ["vite.config.ts", "svg.d.ts"] } diff --git a/packages/frontend/vite.config.ts b/packages/frontend/vite.config.ts index 0e1b4b44..9fe89f8d 100644 --- a/packages/frontend/vite.config.ts +++ b/packages/frontend/vite.config.ts @@ -1,10 +1,11 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import path from 'path'; +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; +import svgr from 'vite-plugin-svgr'; // https://vite.dev/config/ export default defineConfig({ - plugins: [react()], + plugins: [react(), svgr()], resolve: { alias: { '@': path.resolve(__dirname, './src'), From 19ebfed95ef3c7e9d638892fc07ab1f25053cb4d Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:39:37 +0900 Subject: [PATCH 008/209] =?UTF-8?q?=E2=9C=A8=20feat:=20button=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 5 +- .../frontend/src/components/ui/Button.tsx | 56 ++++++ packages/frontend/src/components/ui/index.ts | 1 + packages/frontend/src/utils/cn.ts | 6 + yarn.lock | 184 +++++++++++++++++- 5 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 packages/frontend/src/components/ui/Button.tsx create mode 100644 packages/frontend/src/components/ui/index.ts create mode 100644 packages/frontend/src/utils/cn.ts diff --git a/packages/frontend/package.json b/packages/frontend/package.json index f01f0016..7ce0e3b0 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -11,8 +11,11 @@ }, "dependencies": { "@tanstack/react-query": "^5.59.19", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "tailwind-merge": "^2.5.4" }, "devDependencies": { "@eslint/js": "^9.13.0", diff --git a/packages/frontend/src/components/ui/Button.tsx b/packages/frontend/src/components/ui/Button.tsx new file mode 100644 index 00000000..c0cb1c4f --- /dev/null +++ b/packages/frontend/src/components/ui/Button.tsx @@ -0,0 +1,56 @@ +import type { ButtonHTMLAttributes, ReactNode } from 'react'; +import { cva, VariantProps } from 'class-variance-authority'; +import { cn } from '@/utils/cn'; + +export const ButtonVariants = cva( + `display-bold12 border rounded shadow-black`, + { + variants: { + backgroundColor: { + default: 'bg-white', + gray: 'bg-gray', + white: 'bg-white', + }, + textColor: { + default: 'text-white', + orange: 'text-orange', + }, + size: { + default: 'w-24', + sm: 'w-14', + }, + }, + defaultVariants: { + backgroundColor: 'default', + textColor: 'default', + size: 'default', + }, + }, +); + +interface ButtonProps + extends ButtonHTMLAttributes, + VariantProps { + children: ReactNode; +} + +export const Button = ({ + backgroundColor, + textColor, + size, + children, + className, + ...props +}: ButtonProps) => { + return ( + + ); +}; diff --git a/packages/frontend/src/components/ui/index.ts b/packages/frontend/src/components/ui/index.ts new file mode 100644 index 00000000..8b166a86 --- /dev/null +++ b/packages/frontend/src/components/ui/index.ts @@ -0,0 +1 @@ +export * from './Button'; diff --git a/packages/frontend/src/utils/cn.ts b/packages/frontend/src/utils/cn.ts new file mode 100644 index 00000000..ffe21d21 --- /dev/null +++ b/packages/frontend/src/utils/cn.ts @@ -0,0 +1,6 @@ +import { ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export const cn = (...inputs: ClassValue[]) => { + return twMerge(clsx(inputs)); +}; diff --git a/yarn.lock b/yarn.lock index 28e604e3..286136c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -87,7 +87,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== @@ -337,7 +337,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== @@ -1147,6 +1147,15 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@rollup/pluginutils@^5.1.3": + version "5.1.3" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf" + integrity sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^4.0.2" + "@rollup/rollup-android-arm-eabi@4.24.4": version "4.24.4" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz#c460b54c50d42f27f8254c435a4f3b3e01910bc8" @@ -1261,6 +1270,89 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@svgr/babel-plugin-add-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== + +"@svgr/babel-plugin-remove-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== + +"@svgr/babel-plugin-svg-dynamic-title@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== + +"@svgr/babel-plugin-svg-em-dimensions@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== + +"@svgr/babel-plugin-transform-react-native-svg@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== + +"@svgr/babel-plugin-transform-svg-component@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== + +"@svgr/babel-preset@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "8.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "8.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" + "@svgr/babel-plugin-transform-svg-component" "8.0.0" + +"@svgr/core@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + camelcase "^6.2.0" + cosmiconfig "^8.1.3" + snake-case "^3.0.4" + +"@svgr/hast-util-to-babel-ast@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== + dependencies: + "@babel/types" "^7.21.3" + entities "^4.4.0" + +"@svgr/plugin-jsx@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + "@svgr/hast-util-to-babel-ast" "8.0.0" + svg-parser "^2.0.4" + "@tanstack/query-core@5.59.17": version "5.59.17" resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.59.17.tgz#bda3bb678be48e2f6ee692abd1cfc2db3d455e4b" @@ -1353,7 +1445,7 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.5.tgz#14a3e83fa641beb169a2dd8422d91c3c345a9a78" integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== -"@types/estree@1.0.6", "@types/estree@^1.0.5", "@types/estree@^1.0.6": +"@types/estree@1.0.6", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== @@ -2341,6 +2433,13 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== +class-variance-authority@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522" + integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A== + dependencies: + clsx "2.0.0" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -2398,6 +2497,16 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== +clsx@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + +clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -2594,7 +2703,7 @@ cosmiconfig-typescript-loader@^5.0.0: dependencies: jiti "^1.21.6" -cosmiconfig@^8.2.0: +cosmiconfig@^8.1.3, cosmiconfig@^8.2.0: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== @@ -2847,6 +2956,14 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + dot-prop@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -2914,6 +3031,11 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" +entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + env-paths@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -3311,6 +3433,11 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -5032,6 +5159,13 @@ loose-envify@^1.1.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + lru-cache@^10.2.0: version "10.4.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" @@ -5262,6 +5396,14 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + node-abort-controller@^3.0.1: version "3.1.1" resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" @@ -5573,6 +5715,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6137,6 +6284,14 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" @@ -6397,6 +6552,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + symbol-observable@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" @@ -6410,6 +6570,11 @@ synckit@^0.9.1: "@pkgr/core" "^0.1.0" tslib "^2.6.2" +tailwind-merge@^2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.5.4.tgz#4bf574e81fa061adeceba099ae4df56edcee78d1" + integrity sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q== + tailwindcss@^3.4.14: version "3.4.14" resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.14.tgz#6dd23a7f54ec197b19159e91e3bb1e55e7aa73ac" @@ -6642,7 +6807,7 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.6.2: +tslib@^2.0.3, tslib@^2.1.0, tslib@^2.6.2: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -6833,6 +6998,15 @@ vary@^1, vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vite-plugin-svgr@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz#742f16f11375996306c696ec323e4d23f6005075" + integrity sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w== + dependencies: + "@rollup/pluginutils" "^5.1.3" + "@svgr/core" "^8.1.0" + "@svgr/plugin-jsx" "^8.1.0" + vite@^5.4.10: version "5.4.10" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.10.tgz#d358a7bd8beda6cf0f3b7a450a8c7693a4f80c18" From 70cd9690cc8db12872ddfda21189730bf3fb09f6 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:40:17 +0900 Subject: [PATCH 009/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=20=EA=B5=AC=EC=97=AD=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=EC=99=80=20text=20area=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/ChatPanel.tsx | 11 +++++++++++ .../pages/stock-detail/components/TextArea.tsx | 16 ++++++++++++++++ .../src/pages/stock-detail/components/index.ts | 1 + 3 files changed, 28 insertions(+) create mode 100644 packages/frontend/src/pages/stock-detail/ChatPanel.tsx create mode 100644 packages/frontend/src/pages/stock-detail/components/TextArea.tsx create mode 100644 packages/frontend/src/pages/stock-detail/components/index.ts diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx new file mode 100644 index 00000000..b4d808df --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -0,0 +1,11 @@ +import { TextArea } from './components'; + +export const ChatPanel = () => { + return ( +
    +

    채팅

    + + + + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/components/index.ts b/packages/frontend/src/pages/stock-detail/components/index.ts new file mode 100644 index 00000000..4853311c --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/index.ts @@ -0,0 +1 @@ +export * from './TextArea'; From 652d14a1161d90c8e50204a2d4faca82c362f011 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:40:37 +0900 Subject: [PATCH 010/209] =?UTF-8?q?=E2=9C=A8=20feat:=20white=20color=20con?= =?UTF-8?q?fig=EC=97=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/tailwind.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index 8d518381..f83c1f15 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -8,6 +8,7 @@ export default { gray: '#8c8c8c', 'dark-gray': '#4f4f4f', black: '#000000', + white: '#ffffff', 'light-yellow': '#ffdcac', 'light-orange': '#ffcfac', orange: '#ffa868', From c33dd16ec36f77be43dfada34f83ffcc63e948f7 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:41:08 +0900 Subject: [PATCH 011/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=95=8C=EB=A6=BC,?= =?UTF-8?q?=20=EC=95=8C=EB=A6=BC=EC=B6=94=EA=B0=80=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EA=B8=B0=EB=B3=B8=EC=A0=81=EC=9D=B8=20UI=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx | 7 +++++++ .../frontend/src/pages/stock-detail/NotificationPanel.tsx | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx create mode 100644 packages/frontend/src/pages/stock-detail/NotificationPanel.tsx diff --git a/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx new file mode 100644 index 00000000..95715984 --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx @@ -0,0 +1,7 @@ +export const AddAlarmForm = () => { + return ( +
    +

    알림 추가

    +
    + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx b/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx new file mode 100644 index 00000000..e7db6e95 --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx @@ -0,0 +1,7 @@ +export const NotificationPanel = () => { + return ( +
    +

    알림

    +
    + ); +}; From cc4b59793a8be5b3978f03df88645d9d84ed1ee0 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 01:41:46 +0900 Subject: [PATCH 012/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=97=90=20=EB=8C=80=ED=95=9C=20UI=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: #136 --- packages/frontend/src/App.tsx | 21 +------- .../src/pages/stock-detail/StockDetail.tsx | 37 ++++++++++++++ .../pages/stock-detail/StockMetricsPanel.tsx | 51 +++++++++++++++++++ .../frontend/src/pages/stock-detail/index.ts | 5 ++ 4 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 packages/frontend/src/pages/stock-detail/StockDetail.tsx create mode 100644 packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx create mode 100644 packages/frontend/src/pages/stock-detail/index.ts diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index b227abba..56fd60cb 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -1,24 +1,7 @@ -import { useState } from 'react'; +import { StockDetail } from './pages/stock-detail'; const App = () => { - const [count, setCount] = useState(0); - - return ( - <> -

    Vite + React

    -
    - -

    - Edit src/App.tsx and save to test HMR -

    -
    -

    - Click on the Vite and React logos to learn more -

    - - ); + return ; }; export default App; diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx new file mode 100644 index 00000000..9c9db61a --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -0,0 +1,37 @@ +import { + AddAlarmForm, + ChatPanel, + NotificationPanel, + StockMetricsPanel, +} from '.'; +import Plus from '@/assets/plus.svg?react'; +import { Button } from '@/components/ui'; + +export const StockDetail = () => { + return ( +
    +
    +

    삼성전자

    + +
    +
    +
    +
    graph
    + +
    + +
    + + +
    +
    +
    + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx new file mode 100644 index 00000000..dbb81d40 --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx @@ -0,0 +1,51 @@ +import { type ReactNode } from 'react'; + +interface TitleProps { + children: ReactNode; +} + +interface MetricItemProps { + label: string; + value: string; +} + +export const StockMetricsPanel = () => { + return ( +
    +
    + 거래량 + 00.000 +
    +
    + 가격 +
    + + + + +
    +
    +
    + 기업 가치 +
    + + + +
    +
    +
    + ); +}; + +const Title = ({ children }: TitleProps) => { + return

    {children}

    ; +}; + +const MetricItem = ({ label, value }: MetricItemProps) => { + return ( + <> + {label} + {value} + + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/index.ts b/packages/frontend/src/pages/stock-detail/index.ts new file mode 100644 index 00000000..8887d490 --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/index.ts @@ -0,0 +1,5 @@ +export * from './StockDetail'; +export * from './AddAlarmForm'; +export * from './ChatPanel'; +export * from './NotificationPanel'; +export * from './StockMetricsPanel'; From c1efb86546a30a6510c94e903d2c2cfc217b1d79 Mon Sep 17 00:00:00 2001 From: kimminsu Date: Mon, 11 Nov 2024 08:13:20 +0900 Subject: [PATCH 013/209] =?UTF-8?q?=E2=9C=A8=20feat:=20svg=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0,=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=EC=9D=84=20=EC=84=A4=EC=A0=95=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/base.svg.tsx | 32 +++++++++++++++ packages/frontend/src/assets/bell.svg.tsx | 31 +++++--------- .../frontend/src/assets/darkLight.svg.tsx | 41 ++++++++++--------- packages/frontend/src/assets/graph.svg.tsx | 28 +++++++------ packages/frontend/src/assets/home.svg.tsx | 22 +++++----- packages/frontend/src/assets/search.svg.tsx | 16 ++++---- packages/frontend/src/assets/user.svg.tsx | 31 +++++++------- .../frontend/src/component/navigation.tsx | 4 +- .../src/component/navigationBlock.tsx | 25 +++++++---- 9 files changed, 133 insertions(+), 97 deletions(-) create mode 100644 packages/frontend/src/assets/base.svg.tsx diff --git a/packages/frontend/src/assets/base.svg.tsx b/packages/frontend/src/assets/base.svg.tsx new file mode 100644 index 00000000..d922d9d4 --- /dev/null +++ b/packages/frontend/src/assets/base.svg.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +export interface BaseSvgProps { + width: string; + height: string; + viewBox: string; + className?: string; + fill?: string; + children?: React.ReactNode; +} + +export type ChildSvgProps = Omit; + +export const BaseSvg: React.FC = ({ + width, + height, + viewBox, + className, + fill, + children, +}) => ( + + {children} + +); \ No newline at end of file diff --git a/packages/frontend/src/assets/bell.svg.tsx b/packages/frontend/src/assets/bell.svg.tsx index f5550f07..773ad3ca 100644 --- a/packages/frontend/src/assets/bell.svg.tsx +++ b/packages/frontend/src/assets/bell.svg.tsx @@ -1,24 +1,15 @@ -const BellSvg = () => ( - ( + - {'bell-line'} - - - - + + ); + export default BellSvg; diff --git a/packages/frontend/src/assets/darkLight.svg.tsx b/packages/frontend/src/assets/darkLight.svg.tsx index 4bab235c..31b124ee 100644 --- a/packages/frontend/src/assets/darkLight.svg.tsx +++ b/packages/frontend/src/assets/darkLight.svg.tsx @@ -1,20 +1,21 @@ -export function DarkLightSVG() { - return ( - - - - - ); -} \ No newline at end of file +import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; + +export const DarkLightSVG = ({ width, className, height }: ChildSvgProps) => ( + + + + +); diff --git a/packages/frontend/src/assets/graph.svg.tsx b/packages/frontend/src/assets/graph.svg.tsx index 55f712a1..60546911 100644 --- a/packages/frontend/src/assets/graph.svg.tsx +++ b/packages/frontend/src/assets/graph.svg.tsx @@ -1,14 +1,16 @@ -const Graph = () => ( - - - - +import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; + +const GraphSvg = ({ width, className, height }: ChildSvgProps) => ( + + + + ); -export default Graph; \ No newline at end of file + +export default GraphSvg; \ No newline at end of file diff --git a/packages/frontend/src/assets/home.svg.tsx b/packages/frontend/src/assets/home.svg.tsx index bda589fa..a71fe1f1 100644 --- a/packages/frontend/src/assets/home.svg.tsx +++ b/packages/frontend/src/assets/home.svg.tsx @@ -1,16 +1,18 @@ -const HomeSvg = () => ( - ( + - + - + ); export default HomeSvg; \ No newline at end of file diff --git a/packages/frontend/src/assets/search.svg.tsx b/packages/frontend/src/assets/search.svg.tsx index 4d16aa54..a8c97751 100644 --- a/packages/frontend/src/assets/search.svg.tsx +++ b/packages/frontend/src/assets/search.svg.tsx @@ -1,16 +1,16 @@ -const SearchSvg = () => ( - ( + - + ); export default SearchSvg; diff --git a/packages/frontend/src/assets/user.svg.tsx b/packages/frontend/src/assets/user.svg.tsx index f3c35b32..6ee8766b 100644 --- a/packages/frontend/src/assets/user.svg.tsx +++ b/packages/frontend/src/assets/user.svg.tsx @@ -1,16 +1,15 @@ -export function UserSvg() { - return ( - - - - - - - ); -} \ No newline at end of file +import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; + +export const UserSvg = ({ width, className, height }: ChildSvgProps) => ( + + + + + + +); diff --git a/packages/frontend/src/component/navigation.tsx b/packages/frontend/src/component/navigation.tsx index c618c7a8..f605bcca 100644 --- a/packages/frontend/src/component/navigation.tsx +++ b/packages/frontend/src/component/navigation.tsx @@ -41,8 +41,8 @@ export const Navigation = () => {
    -
      - +
        + ; label: string; isOpen: boolean; } +interface SearchBoxProps { + isOpen: boolean; +} + const boxClassName = 'hover:bg-orange flex h-full w-full items-center gap-4 rounded-xl transition-colors duration-500'; @@ -16,11 +21,15 @@ export const NavigationBlock: React.FC = ({ isOpen, }) => { return ( -
      • +
      • - + {label} @@ -29,13 +38,13 @@ export const NavigationBlock: React.FC = ({ ); }; -export const SearchBox: React.FC = () => { +export const SearchBox: React.FC = ({ isOpen }) => { return ( -
      • +
      • - + From c0a29f4f42c637a0cbe429742797a1f8bf074aed Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 16:11:36 +0900 Subject: [PATCH 014/209] =?UTF-8?q?=E2=9C=A8=20feat:=20utility=20class?= =?UTF-8?q?=EB=A5=BC=20@layer=EB=A1=9C=20=EA=B0=90=EC=8B=B8=EC=84=9C=20?= =?UTF-8?q?=EC=9A=B0=EC=84=A0=EC=88=9C=EC=9C=84=20=EB=B6=80=EC=97=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/index.css | 54 +++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index 5760afac..7b68d633 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -17,38 +17,40 @@ } } -.display-bold24 { - @apply text-2xl font-bold; -} +@layer utilities { + .display-bold24 { + @apply text-2xl font-bold; + } -.display-bold20 { - @apply text-xl font-bold; -} + .display-bold20 { + @apply text-xl font-bold; + } -.display-bold16 { - @apply text-base font-bold; -} + .display-bold16 { + @apply text-base font-bold; + } -.display-bold14 { - @apply text-sm font-bold; -} + .display-bold14 { + @apply text-sm font-bold; + } -.display-bold12 { - @apply text-xs font-bold; -} + .display-bold12 { + @apply text-xs font-bold; + } -.display-medium20 { - @apply text-xl; -} + .display-medium20 { + @apply text-xl; + } -.display-medium16 { - @apply text-base; -} + .display-medium16 { + @apply text-base; + } -.display-medium14 { - @apply text-sm; -} + .display-medium14 { + @apply text-sm; + } -.display-medium12 { - @apply text-xs; + .display-medium12 { + @apply text-xs; + } } From 1ec07f66ad4ed55febac4208d4aa954830bf84c0 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 16:12:31 +0900 Subject: [PATCH 015/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5=EB=90=98=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EC=B6=9C,=20mock=20data=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/mocks/data.json | 13 +++++ .../pages/stock-detail/StockMetricsPanel.tsx | 49 +++---------------- .../stock-detail/components/MetricItem.tsx | 13 +++++ .../stock-detail/components/MetricSection.tsx | 20 ++++++++ .../pages/stock-detail/components/Title.tsx | 9 ++++ .../pages/stock-detail/components/index.ts | 3 ++ packages/frontend/tsconfig.app.json | 2 +- 7 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 packages/frontend/src/mocks/data.json create mode 100644 packages/frontend/src/pages/stock-detail/components/MetricItem.tsx create mode 100644 packages/frontend/src/pages/stock-detail/components/MetricSection.tsx create mode 100644 packages/frontend/src/pages/stock-detail/components/Title.tsx diff --git a/packages/frontend/src/mocks/data.json b/packages/frontend/src/mocks/data.json new file mode 100644 index 00000000..f30d80ac --- /dev/null +++ b/packages/frontend/src/mocks/data.json @@ -0,0 +1,13 @@ +{ + "price": [ + { "label": "현재가", "value": "00.000" }, + { "label": "52주 최고가", "value": "00.000" }, + { "label": "변동률", "value": "00.000" }, + { "label": "52주 최저가", "value": "00.000" } + ], + "enterprise value": [ + { "label": "시가총액", "value": "00.000" }, + { "label": "EPS", "value": "00.000" }, + { "label": "PER", "value": "00.000" } + ] +} diff --git a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx index dbb81d40..bc510cb9 100644 --- a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx @@ -1,51 +1,18 @@ -import { type ReactNode } from 'react'; - -interface TitleProps { - children: ReactNode; -} - -interface MetricItemProps { - label: string; - value: string; -} +import { MetricSection, Title } from './components'; +import mockData from '@/mocks/data.json'; export const StockMetricsPanel = () => { return ( -
        +
        거래량 00.000
        -
        - 가격 -
        - - - - -
        -
        -
        - 기업 가치 -
        - - - -
        -
        + +
        ); }; - -const Title = ({ children }: TitleProps) => { - return

        {children}

        ; -}; - -const MetricItem = ({ label, value }: MetricItemProps) => { - return ( - <> - {label} - {value} - - ); -}; diff --git a/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx b/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx new file mode 100644 index 00000000..4e6877ba --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx @@ -0,0 +1,13 @@ +export interface MetricItemProps { + label: string; + value: string; +} + +export const MetricItem = ({ label, value }: MetricItemProps) => { + return ( + <> + {label} + {value} + + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx new file mode 100644 index 00000000..8e06cedd --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx @@ -0,0 +1,20 @@ +import { type MetricItemProps } from './MetricItem'; +import { Title, MetricItem } from '.'; + +interface MetricSectionProps { + title: string; + metricInfo: MetricItemProps[]; +} + +export const MetricSection = ({ title, metricInfo }: MetricSectionProps) => { + return ( +
        + {title} +
        + {metricInfo.map((info) => ( + + ))} +
        +
        + ); +}; diff --git a/packages/frontend/src/pages/stock-detail/components/Title.tsx b/packages/frontend/src/pages/stock-detail/components/Title.tsx new file mode 100644 index 00000000..609ade3a --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/Title.tsx @@ -0,0 +1,9 @@ +import { type ReactNode } from 'react'; + +interface TitleProps { + children: ReactNode; +} + +export const Title = ({ children }: TitleProps) => { + return

        {children}

        ; +}; diff --git a/packages/frontend/src/pages/stock-detail/components/index.ts b/packages/frontend/src/pages/stock-detail/components/index.ts index 4853311c..dd780814 100644 --- a/packages/frontend/src/pages/stock-detail/components/index.ts +++ b/packages/frontend/src/pages/stock-detail/components/index.ts @@ -1 +1,4 @@ export * from './TextArea'; +export * from './MetricItem'; +export * from './MetricSection'; +export * from './Title'; diff --git a/packages/frontend/tsconfig.app.json b/packages/frontend/tsconfig.app.json index b4b522c0..374f7514 100644 --- a/packages/frontend/tsconfig.app.json +++ b/packages/frontend/tsconfig.app.json @@ -25,5 +25,5 @@ "composite": true }, - "include": ["src"] + "include": ["src", "src/**/*.json"] } From e8ead161a0eed7ad879bb99e7a3f6d82e028b776 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 16:12:54 +0900 Subject: [PATCH 016/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EA=B0=80?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EB=A9=94=EB=89=B4=20constants=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/constants/METRIC_ITEM.ts | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/frontend/src/constants/METRIC_ITEM.ts diff --git a/packages/frontend/src/constants/METRIC_ITEM.ts b/packages/frontend/src/constants/METRIC_ITEM.ts new file mode 100644 index 00000000..609ecdf9 --- /dev/null +++ b/packages/frontend/src/constants/METRIC_ITEM.ts @@ -0,0 +1,23 @@ +export type MetricItemValue = { + id: number; + label: string; +}; + +type MetricItem = { + trading_volume: MetricItemValue[]; + enterprise_value: MetricItemValue[]; +}; + +export const METRIC_ITEM: MetricItem = { + trading_volume: [ + { id: 0, label: '현재가' }, + { id: 1, label: '52주 최고가' }, + { id: 2, label: '변동률' }, + { id: 3, label: '52주 최저가' }, + ], + enterprise_value: [ + { id: 0, label: '시가총액' }, + { id: 1, label: 'EPS' }, + { id: 2, label: 'PER' }, + ], +}; From 386c58fcf6188f77088f46cf255f9df0d8dc0a91 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 16:13:17 +0900 Subject: [PATCH 017/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=8B=9C?= =?UTF-8?q?=EB=A7=A8=ED=8B=B1=20=ED=83=9C=EA=B7=B8=20=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B0=98=EB=B3=B5=EB=90=98=EB=8A=94=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=A4=84=EC=9D=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ISSUES CLOSED: #136 --- .../frontend/src/pages/stock-detail/StockDetail.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index 9c9db61a..f5154752 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -10,7 +10,7 @@ import { Button } from '@/components/ui'; export const StockDetail = () => { return (
        -
        +

        삼성전자

        -
        -
        -
        + +
        +
        graph
        -
        +
        From bb5c7783592e6e051757bd98697742ccef5d611f Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 16:56:01 +0900 Subject: [PATCH 018/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=EA=B3=BC=20=EC=95=8C=EB=A6=BC=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B9=84=EC=9C=A8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/StockDetail.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index f5154752..58d94ca4 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -27,7 +27,7 @@ export const StockDetail = () => {
        -
        +
        From be27b679e7fc4cbd0f3a3cf263537421283adda8 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 11 Nov 2024 17:01:13 +0900 Subject: [PATCH 019/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=A3=BC?= =?UTF-8?q?=EC=8B=9D=20=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EB=93=9C=20=EB=B9=84=EC=9C=A8=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/StockDetail.tsx | 2 +- .../src/pages/stock-detail/components/MetricSection.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index 58d94ca4..7b91eca7 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -21,7 +21,7 @@ export const StockDetail = () => { 내 주식 추가 -
        +
        graph
        diff --git a/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx index 8e06cedd..572d2a2a 100644 --- a/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx +++ b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx @@ -8,9 +8,9 @@ interface MetricSectionProps { export const MetricSection = ({ title, metricInfo }: MetricSectionProps) => { return ( -
        +
        {title} -
        +
        {metricInfo.map((info) => ( ))} From 13ef77de0393820a8e14fa53b880b7b3d5b14b6b Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 12 Nov 2024 16:53:53 +0900 Subject: [PATCH 020/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20tailwind=20config?= =?UTF-8?q?=20=EA=B2=B9=EC=B9=98=EB=8A=94=20white=20=EC=86=8D=EC=84=B1=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/tailwind.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index 0c820c46..f83c1f15 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -15,7 +15,6 @@ export default { red: '#eb3636', green: '#7eeb7e', blue: '#3675eb', - white: '#ffffff', }, }, plugins: [], From 41c24342b79a1d870ddbd0b4dc006ac7645dc3b1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 12 Nov 2024 16:54:50 +0900 Subject: [PATCH 021/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20tsx=EA=B0=80=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20svg=20=ED=8C=8C=EC=9D=BC=20=EC=9E=AC?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/base.svg.tsx | 32 ------------------- packages/frontend/src/assets/bell.svg | 4 +++ packages/frontend/src/assets/bell.svg.tsx | 15 --------- .../frontend/src/assets/darkLight.svg.tsx | 21 ------------ packages/frontend/src/assets/graph.svg.tsx | 16 ---------- packages/frontend/src/assets/home.svg | 4 +++ packages/frontend/src/assets/home.svg.tsx | 18 ----------- packages/frontend/src/assets/mode.svg | 4 +++ packages/frontend/src/assets/search.svg | 3 ++ packages/frontend/src/assets/search.svg.tsx | 16 ---------- packages/frontend/src/assets/stock.svg | 14 ++++++++ packages/frontend/src/assets/user.svg | 3 ++ packages/frontend/src/assets/user.svg.tsx | 15 --------- 13 files changed, 32 insertions(+), 133 deletions(-) delete mode 100644 packages/frontend/src/assets/base.svg.tsx create mode 100644 packages/frontend/src/assets/bell.svg delete mode 100644 packages/frontend/src/assets/bell.svg.tsx delete mode 100644 packages/frontend/src/assets/darkLight.svg.tsx delete mode 100644 packages/frontend/src/assets/graph.svg.tsx create mode 100644 packages/frontend/src/assets/home.svg delete mode 100644 packages/frontend/src/assets/home.svg.tsx create mode 100644 packages/frontend/src/assets/mode.svg create mode 100644 packages/frontend/src/assets/search.svg delete mode 100644 packages/frontend/src/assets/search.svg.tsx create mode 100644 packages/frontend/src/assets/stock.svg create mode 100644 packages/frontend/src/assets/user.svg delete mode 100644 packages/frontend/src/assets/user.svg.tsx diff --git a/packages/frontend/src/assets/base.svg.tsx b/packages/frontend/src/assets/base.svg.tsx deleted file mode 100644 index d922d9d4..00000000 --- a/packages/frontend/src/assets/base.svg.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; - -export interface BaseSvgProps { - width: string; - height: string; - viewBox: string; - className?: string; - fill?: string; - children?: React.ReactNode; -} - -export type ChildSvgProps = Omit; - -export const BaseSvg: React.FC = ({ - width, - height, - viewBox, - className, - fill, - children, -}) => ( - - {children} - -); \ No newline at end of file diff --git a/packages/frontend/src/assets/bell.svg b/packages/frontend/src/assets/bell.svg new file mode 100644 index 00000000..c40532f5 --- /dev/null +++ b/packages/frontend/src/assets/bell.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/frontend/src/assets/bell.svg.tsx b/packages/frontend/src/assets/bell.svg.tsx deleted file mode 100644 index 773ad3ca..00000000 --- a/packages/frontend/src/assets/bell.svg.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -const BellSvg = ({ width, className, height }: ChildSvgProps) => ( - - - -); - -export default BellSvg; diff --git a/packages/frontend/src/assets/darkLight.svg.tsx b/packages/frontend/src/assets/darkLight.svg.tsx deleted file mode 100644 index 31b124ee..00000000 --- a/packages/frontend/src/assets/darkLight.svg.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -export const DarkLightSVG = ({ width, className, height }: ChildSvgProps) => ( - - - - -); diff --git a/packages/frontend/src/assets/graph.svg.tsx b/packages/frontend/src/assets/graph.svg.tsx deleted file mode 100644 index 60546911..00000000 --- a/packages/frontend/src/assets/graph.svg.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -const GraphSvg = ({ width, className, height }: ChildSvgProps) => ( - - - - -); - -export default GraphSvg; \ No newline at end of file diff --git a/packages/frontend/src/assets/home.svg b/packages/frontend/src/assets/home.svg new file mode 100644 index 00000000..829f467f --- /dev/null +++ b/packages/frontend/src/assets/home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/frontend/src/assets/home.svg.tsx b/packages/frontend/src/assets/home.svg.tsx deleted file mode 100644 index a71fe1f1..00000000 --- a/packages/frontend/src/assets/home.svg.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -const HomeSvg = ({ width, height, className }: ChildSvgProps) => ( - - - - - -); -export default HomeSvg; \ No newline at end of file diff --git a/packages/frontend/src/assets/mode.svg b/packages/frontend/src/assets/mode.svg new file mode 100644 index 00000000..fee46987 --- /dev/null +++ b/packages/frontend/src/assets/mode.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/frontend/src/assets/search.svg b/packages/frontend/src/assets/search.svg new file mode 100644 index 00000000..ae899f1c --- /dev/null +++ b/packages/frontend/src/assets/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/assets/search.svg.tsx b/packages/frontend/src/assets/search.svg.tsx deleted file mode 100644 index a8c97751..00000000 --- a/packages/frontend/src/assets/search.svg.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -const SearchSvg = ({ width, height, className }: ChildSvgProps) => ( - - - -); -export default SearchSvg; diff --git a/packages/frontend/src/assets/stock.svg b/packages/frontend/src/assets/stock.svg new file mode 100644 index 00000000..99cef5dc --- /dev/null +++ b/packages/frontend/src/assets/stock.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/frontend/src/assets/user.svg b/packages/frontend/src/assets/user.svg new file mode 100644 index 00000000..c8e4da8b --- /dev/null +++ b/packages/frontend/src/assets/user.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/assets/user.svg.tsx b/packages/frontend/src/assets/user.svg.tsx deleted file mode 100644 index 6ee8766b..00000000 --- a/packages/frontend/src/assets/user.svg.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { BaseSvg, ChildSvgProps } from '@/assets/base.svg.tsx'; - -export const UserSvg = ({ width, className, height }: ChildSvgProps) => ( - - - - - - -); From 2e92541d3d80780359d517bd76125ed8d077c05a Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 12 Nov 2024 16:58:42 +0900 Subject: [PATCH 022/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=ED=8F=B4?= =?UTF-8?q?=EB=8D=94=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20svg=20import=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/assets/{mode.svg => modeSwitch.svg} | 0 .../layouts/Navigation.tsx} | 19 +++++++++++-------- .../layouts/NavigationBlock.tsx} | 11 ++--------- 3 files changed, 13 insertions(+), 17 deletions(-) rename packages/frontend/src/assets/{mode.svg => modeSwitch.svg} (100%) rename packages/frontend/src/{component/navigation.tsx => components/layouts/Navigation.tsx} (86%) rename packages/frontend/src/{component/navigationBlock.tsx => components/layouts/NavigationBlock.tsx} (85%) diff --git a/packages/frontend/src/assets/mode.svg b/packages/frontend/src/assets/modeSwitch.svg similarity index 100% rename from packages/frontend/src/assets/mode.svg rename to packages/frontend/src/assets/modeSwitch.svg diff --git a/packages/frontend/src/component/navigation.tsx b/packages/frontend/src/components/layouts/Navigation.tsx similarity index 86% rename from packages/frontend/src/component/navigation.tsx rename to packages/frontend/src/components/layouts/Navigation.tsx index f605bcca..bda2a604 100644 --- a/packages/frontend/src/component/navigation.tsx +++ b/packages/frontend/src/components/layouts/Navigation.tsx @@ -1,10 +1,13 @@ import { useState } from 'react'; -import BellSvg from '@/assets/bell.svg.tsx'; -import { DarkLightSVG } from '@/assets/darkLight.svg.tsx'; -import GraphSvg from '@/assets/graph.svg.tsx'; -import HomeSvg from '@/assets/home.svg.tsx'; -import { UserSvg } from '@/assets/user.svg.tsx'; -import { NavigationBlock, SearchBox } from '@/component/navigationBlock.tsx'; +import BellSvg from '@/assets/bell.svg?react'; +import GraphSvg from '@/assets/graph.svg?react'; +import HomeSvg from '@/assets/home.svg?react'; +import modeSwitch from '@/assets/modeSwitch.svg?react'; +import UserSvg from '@/assets/user.svg?react'; +import { + NavigationBlock, + SearchBox, +} from '@/components/layouts/NavigationBlock'; export const Navigation = () => { const [isOpen, setIsOpen] = useState(false); @@ -63,7 +66,7 @@ export const Navigation = () => {
          @@ -78,4 +81,4 @@ export const Navigation = () => {
        ); -}; \ No newline at end of file +}; diff --git a/packages/frontend/src/component/navigationBlock.tsx b/packages/frontend/src/components/layouts/NavigationBlock.tsx similarity index 85% rename from packages/frontend/src/component/navigationBlock.tsx rename to packages/frontend/src/components/layouts/NavigationBlock.tsx index b1386e7d..65672561 100644 --- a/packages/frontend/src/component/navigationBlock.tsx +++ b/packages/frontend/src/components/layouts/NavigationBlock.tsx @@ -1,12 +1,5 @@ import React from 'react'; -import { ChildSvgProps } from '@/assets/base.svg.tsx'; -import SearchSvg from '@/assets/search.svg.tsx'; - -interface NavItemProps { - SvgComponent: React.FC; - label: string; - isOpen: boolean; -} +import SearchSvg from '@/assets/search.svg'; interface SearchBoxProps { isOpen: boolean; @@ -51,4 +44,4 @@ export const SearchBox: React.FC = ({ isOpen }) => {
      • ); -}; \ No newline at end of file +}; From 921eefb31d38d5105ba48899a023b0cca811a4ba Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:12:30 +0900 Subject: [PATCH 023/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20=EB=A1=9C?= =?UTF-8?q?=EA=B3=A0=20=EC=BA=90=EB=A6=AD=ED=84=B0=20=EC=82=AC=EC=A7=84?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/public/{logo.png => logoCharacter.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/frontend/public/{logo.png => logoCharacter.png} (100%) diff --git a/packages/frontend/public/logo.png b/packages/frontend/public/logoCharacter.png similarity index 100% rename from packages/frontend/public/logo.png rename to packages/frontend/public/logoCharacter.png From bcda7542044dd50b463fb40ef4c3954d261d8109 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:13:18 +0900 Subject: [PATCH 024/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20=ED=83=80?= =?UTF-8?q?=EC=9D=B4=ED=8F=AC=20=EB=A1=9C=EA=B3=A0=EB=A5=BC=20=EB=B0=B0?= =?UTF-8?q?=EA=B2=BD=20=EC=97=86=EB=8A=94=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/public/logoTitle.png | Bin 0 -> 8549 bytes packages/frontend/public/title.png | Bin 4161 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/frontend/public/logoTitle.png delete mode 100644 packages/frontend/public/title.png diff --git a/packages/frontend/public/logoTitle.png b/packages/frontend/public/logoTitle.png new file mode 100644 index 0000000000000000000000000000000000000000..84bf11c39a398d45aa847e66996d6d9b03f3a488 GIT binary patch literal 8549 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 literal 0 HcmV?d00001 diff --git a/packages/frontend/public/title.png b/packages/frontend/public/title.png deleted file mode 100644 index 57a8c83a5786e252f1a3cb986f70f16de78d6fc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4161 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 LNkvXXu0mjfCH^;n From 7fffeb5360b520d63b81f7bbe887ee075cb4c92b Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:13:58 +0900 Subject: [PATCH 025/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20svg=20fill,=20str?= =?UTF-8?q?oke=20=EA=B0=92=EC=9D=84=20current=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/bell.svg | 4 ++-- packages/frontend/src/assets/home.svg | 4 ++-- packages/frontend/src/assets/modeSwitch.svg | 4 ---- packages/frontend/src/assets/search.svg | 5 +++-- packages/frontend/src/assets/stock.svg | 17 ++++------------- packages/frontend/src/assets/theme.svg | 3 +++ packages/frontend/src/assets/user.svg | 4 ++-- 7 files changed, 16 insertions(+), 25 deletions(-) delete mode 100644 packages/frontend/src/assets/modeSwitch.svg create mode 100644 packages/frontend/src/assets/theme.svg diff --git a/packages/frontend/src/assets/bell.svg b/packages/frontend/src/assets/bell.svg index c40532f5..fdaadf88 100644 --- a/packages/frontend/src/assets/bell.svg +++ b/packages/frontend/src/assets/bell.svg @@ -1,4 +1,4 @@ - - + + diff --git a/packages/frontend/src/assets/home.svg b/packages/frontend/src/assets/home.svg index 829f467f..6dfeb2fb 100644 --- a/packages/frontend/src/assets/home.svg +++ b/packages/frontend/src/assets/home.svg @@ -1,4 +1,4 @@ - - + + diff --git a/packages/frontend/src/assets/modeSwitch.svg b/packages/frontend/src/assets/modeSwitch.svg deleted file mode 100644 index fee46987..00000000 --- a/packages/frontend/src/assets/modeSwitch.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/packages/frontend/src/assets/search.svg b/packages/frontend/src/assets/search.svg index ae899f1c..629bb57d 100644 --- a/packages/frontend/src/assets/search.svg +++ b/packages/frontend/src/assets/search.svg @@ -1,3 +1,4 @@ - - + + + diff --git a/packages/frontend/src/assets/stock.svg b/packages/frontend/src/assets/stock.svg index 99cef5dc..0c069492 100644 --- a/packages/frontend/src/assets/stock.svg +++ b/packages/frontend/src/assets/stock.svg @@ -1,14 +1,5 @@ - - - - - - - - - - - - - + + + + diff --git a/packages/frontend/src/assets/theme.svg b/packages/frontend/src/assets/theme.svg new file mode 100644 index 00000000..601e52de --- /dev/null +++ b/packages/frontend/src/assets/theme.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/assets/user.svg b/packages/frontend/src/assets/user.svg index c8e4da8b..0acf170c 100644 --- a/packages/frontend/src/assets/user.svg +++ b/packages/frontend/src/assets/user.svg @@ -1,3 +1,3 @@ - - + + From fdf03b4186e8d7ec3e6bea0c10c9d5e047c816d8 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:15:07 +0900 Subject: [PATCH 026/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EB=93=9C=EB=B0=94=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/layouts/MenuList.tsx | 59 +++++++++++++ .../src/components/layouts/Navigation.tsx | 84 ------------------- .../components/layouts/NavigationBlock.tsx | 47 ----------- .../src/components/layouts/Sidebar.tsx | 41 +++++++++ packages/frontend/src/constants/menuItems.tsx | 31 +++++++ 5 files changed, 131 insertions(+), 131 deletions(-) create mode 100644 packages/frontend/src/components/layouts/MenuList.tsx delete mode 100644 packages/frontend/src/components/layouts/Navigation.tsx delete mode 100644 packages/frontend/src/components/layouts/NavigationBlock.tsx create mode 100644 packages/frontend/src/components/layouts/Sidebar.tsx create mode 100644 packages/frontend/src/constants/menuItems.tsx diff --git a/packages/frontend/src/components/layouts/MenuList.tsx b/packages/frontend/src/components/layouts/MenuList.tsx new file mode 100644 index 00000000..dc1940c2 --- /dev/null +++ b/packages/frontend/src/components/layouts/MenuList.tsx @@ -0,0 +1,59 @@ +import { type ReactNode } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { type MenuItemData } from '@/constants/menuItems'; +import { cn } from '@/utils/cn'; + +interface MenuListProps { + items: MenuItemData[]; + isHovered: boolean; +} + +interface MenuItemProps { + icon: ReactNode; + text: string; + isHovered: boolean; + onClick?: () => void; +} + +export const MenuList = ({ items, isHovered }: MenuListProps) => { + const navigate = useNavigate(); + + return ( +
          + {items.map((menu) => { + const { id, icon, text, url } = menu; + return ( + url && navigate(url)} + /> + ); + })} +
        + ); +}; + +const MenuItem = ({ icon, text, onClick, isHovered }: MenuItemProps) => { + return ( +
      • + +

        + {text} +

        +
      • + ); +}; diff --git a/packages/frontend/src/components/layouts/Navigation.tsx b/packages/frontend/src/components/layouts/Navigation.tsx deleted file mode 100644 index bda2a604..00000000 --- a/packages/frontend/src/components/layouts/Navigation.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { useState } from 'react'; -import BellSvg from '@/assets/bell.svg?react'; -import GraphSvg from '@/assets/graph.svg?react'; -import HomeSvg from '@/assets/home.svg?react'; -import modeSwitch from '@/assets/modeSwitch.svg?react'; -import UserSvg from '@/assets/user.svg?react'; -import { - NavigationBlock, - SearchBox, -} from '@/components/layouts/NavigationBlock'; - -export const Navigation = () => { - const [isOpen, setIsOpen] = useState(false); - - const toggleSidebar = () => { - setIsOpen(!isOpen); - }; - return ( -
        - -
        - ); -}; diff --git a/packages/frontend/src/components/layouts/NavigationBlock.tsx b/packages/frontend/src/components/layouts/NavigationBlock.tsx deleted file mode 100644 index 65672561..00000000 --- a/packages/frontend/src/components/layouts/NavigationBlock.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import SearchSvg from '@/assets/search.svg'; - -interface SearchBoxProps { - isOpen: boolean; -} - -const boxClassName = - 'hover:bg-orange flex h-full w-full items-center gap-4 rounded-xl transition-colors duration-500'; - -export const NavigationBlock: React.FC = ({ - SvgComponent, - label, - isOpen, -}) => { - return ( -
      • - - - - {label} - - -
      • - ); -}; - -export const SearchBox: React.FC = ({ isOpen }) => { - return ( -
      • - - - - -
      • - ); -}; diff --git a/packages/frontend/src/components/layouts/Sidebar.tsx b/packages/frontend/src/components/layouts/Sidebar.tsx new file mode 100644 index 00000000..651ed531 --- /dev/null +++ b/packages/frontend/src/components/layouts/Sidebar.tsx @@ -0,0 +1,41 @@ +import { useState } from 'react'; +import logoCharacter from '/logoCharacter.png'; +import logoTitle from '/logoTitle.png'; +import { MenuList } from './MenuList'; +import { bottomMenuItems, topMenuItems } from '@/constants/menuItems'; +import { cn } from '@/utils/cn'; + +export const Sidebar = () => { + const [isHovered, setIsHovered] = useState(false); + + return ( + + ); +}; diff --git a/packages/frontend/src/constants/menuItems.tsx b/packages/frontend/src/constants/menuItems.tsx new file mode 100644 index 00000000..abedf45f --- /dev/null +++ b/packages/frontend/src/constants/menuItems.tsx @@ -0,0 +1,31 @@ +import { type ReactElement } from 'react'; +import Bell from '@/assets/bell.svg?react'; +import Home from '@/assets/home.svg?react'; +import Search from '@/assets/search.svg?react'; +import Stock from '@/assets/stock.svg?react'; +import Theme from '@/assets/theme.svg?react'; +import User from '@/assets/user.svg?react'; + +export interface MenuItemData { + icon: ReactElement; + text: string; + id: number; + url?: string; +} + +export const topMenuItems: MenuItemData[] = [ + { icon: , text: '검색', id: 1 }, + { icon: , text: '홈', id: 2, url: '/' }, + { icon: , text: '주식', id: 3, url: '/stocks' }, + { icon: , text: '알림', id: 4 }, +]; + +export const bottomMenuItems: MenuItemData[] = [ + { icon: , text: '다크모드', id: 1 }, + { + icon: , + text: '마이페이지', + id: 2, + url: '/my-page', + }, +]; From ff1bc4a2c367a10968a520ec557001dc86d3d345 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:16:07 +0900 Subject: [PATCH 027/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20=EC=B9=B4?= =?UTF-8?q?=EB=A9=9C=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A1=9C=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/constants/{METRIC_ITEM.ts => metricItem.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/frontend/src/constants/{METRIC_ITEM.ts => metricItem.ts} (100%) diff --git a/packages/frontend/src/constants/METRIC_ITEM.ts b/packages/frontend/src/constants/metricItem.ts similarity index 100% rename from packages/frontend/src/constants/METRIC_ITEM.ts rename to packages/frontend/src/constants/metricItem.ts From 6da01cb36f8417463a7b987ee7ba149c2ed0411e Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:16:31 +0900 Subject: [PATCH 028/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20react-router=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 1 + yarn.lock | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 7ce0e3b0..75b22af7 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -15,6 +15,7 @@ "clsx": "^2.1.1", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-router-dom": "^6.28.0", "tailwind-merge": "^2.5.4" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 286136c6..c7dda2ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1147,6 +1147,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@remix-run/router@1.21.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" + integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== + "@rollup/pluginutils@^5.1.3": version "5.1.3" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf" @@ -5914,6 +5919,21 @@ react-refresh@^0.14.2: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== +react-router-dom@^6.28.0: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6" + integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg== + dependencies: + "@remix-run/router" "1.21.0" + react-router "6.28.0" + +react-router@6.28.0: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d" + integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg== + dependencies: + "@remix-run/router" "1.21.0" + react@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" From 990f152447762e3eb4be3e45583206f199718a73 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:17:08 +0900 Subject: [PATCH 029/209] =?UTF-8?q?=E2=9C=A8=20feat:=20sidebar=EB=A5=BC=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=ED=95=9C=20=EC=A0=84=EC=B2=B4=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/layouts/Layout.tsx | 13 +++++++++++++ packages/frontend/src/components/layouts/index.ts | 3 +++ 2 files changed, 16 insertions(+) create mode 100644 packages/frontend/src/components/layouts/Layout.tsx create mode 100644 packages/frontend/src/components/layouts/index.ts diff --git a/packages/frontend/src/components/layouts/Layout.tsx b/packages/frontend/src/components/layouts/Layout.tsx new file mode 100644 index 00000000..e37b3f2a --- /dev/null +++ b/packages/frontend/src/components/layouts/Layout.tsx @@ -0,0 +1,13 @@ +import { Outlet } from 'react-router-dom'; +import { Sidebar } from './Sidebar'; + +export const Layout = () => { + return ( +
        + +
        + +
        +
        + ); +}; diff --git a/packages/frontend/src/components/layouts/index.ts b/packages/frontend/src/components/layouts/index.ts new file mode 100644 index 00000000..a4ffcee9 --- /dev/null +++ b/packages/frontend/src/components/layouts/index.ts @@ -0,0 +1,3 @@ +export * from './Layout'; +export * from './MenuList'; +export * from './Sidebar'; From 2dd3da208e2408609d912878a1cc6adab6bf4ae0 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 00:17:35 +0900 Subject: [PATCH 030/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=99=88,=20?= =?UTF-8?q?=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4=EC=A7=80,=20=EC=A3=BC?= =?UTF-8?q?=EC=8B=9D=20=EC=83=81=EC=84=B8=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/App.tsx | 13 ++++++++-- packages/frontend/src/pages/home/Home.tsx | 3 +++ packages/frontend/src/pages/home/index.ts | 1 + .../frontend/src/pages/my-page/MyPage.tsx | 3 +++ packages/frontend/src/pages/my-page/index.ts | 1 + .../src/pages/stock-detail/StockDetail.tsx | 2 +- packages/frontend/src/routes/index.tsx | 26 +++++++++++++++++++ 7 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 packages/frontend/src/pages/home/Home.tsx create mode 100644 packages/frontend/src/pages/home/index.ts create mode 100644 packages/frontend/src/pages/my-page/MyPage.tsx create mode 100644 packages/frontend/src/pages/my-page/index.ts create mode 100644 packages/frontend/src/routes/index.tsx diff --git a/packages/frontend/src/App.tsx b/packages/frontend/src/App.tsx index 56fd60cb..c54b6c2e 100644 --- a/packages/frontend/src/App.tsx +++ b/packages/frontend/src/App.tsx @@ -1,7 +1,16 @@ -import { StockDetail } from './pages/stock-detail'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { RouterProvider } from 'react-router-dom'; +import { router } from './routes'; const App = () => { - return ; + const queryClient = new QueryClient(); + + return ( + + + {/* TODO:react query devtools 설치 */} + + ); }; export default App; diff --git a/packages/frontend/src/pages/home/Home.tsx b/packages/frontend/src/pages/home/Home.tsx new file mode 100644 index 00000000..d31605bc --- /dev/null +++ b/packages/frontend/src/pages/home/Home.tsx @@ -0,0 +1,3 @@ +export const Home = () => { + return
        ; +}; diff --git a/packages/frontend/src/pages/home/index.ts b/packages/frontend/src/pages/home/index.ts new file mode 100644 index 00000000..6fd0b5ba --- /dev/null +++ b/packages/frontend/src/pages/home/index.ts @@ -0,0 +1 @@ +export * from './Home'; diff --git a/packages/frontend/src/pages/my-page/MyPage.tsx b/packages/frontend/src/pages/my-page/MyPage.tsx new file mode 100644 index 00000000..b56bab0f --- /dev/null +++ b/packages/frontend/src/pages/my-page/MyPage.tsx @@ -0,0 +1,3 @@ +export const MyPage = () => { + return
        마이페이지
        ; +}; diff --git a/packages/frontend/src/pages/my-page/index.ts b/packages/frontend/src/pages/my-page/index.ts new file mode 100644 index 00000000..7780682b --- /dev/null +++ b/packages/frontend/src/pages/my-page/index.ts @@ -0,0 +1 @@ +export * from './MyPage'; diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index 7b91eca7..24cb754d 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -9,7 +9,7 @@ import { Button } from '@/components/ui'; export const StockDetail = () => { return ( -
        +

        삼성전자

        -
        graph
        +
        + +
        diff --git a/packages/frontend/src/pages/stock-detail/TradingChart.tsx b/packages/frontend/src/pages/stock-detail/TradingChart.tsx new file mode 100644 index 00000000..fd3053b2 --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/TradingChart.tsx @@ -0,0 +1,17 @@ +import { useRef } from 'react'; +import { useChart } from './hooks/useChart'; +import { useChartResize } from './hooks/useChartResize'; +import { ChartTheme, darkTheme } from '@/styles/theme'; + +interface TradingChartProps { + theme?: ChartTheme; +} + +export const TradingChart = ({ theme = darkTheme }: TradingChartProps) => { + const containerRef = useRef(null); + const chart = useChart({ containerRef, theme }); + + useChartResize({ containerRef, chart }); + + return
        ; +}; From 15131ba4f246aca6d71fb20b601364198ec086a8 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 15:54:38 +0900 Subject: [PATCH 036/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=ED=94=84=20=EC=BA=94=EB=93=A4=20=EC=8A=A4=ED=8B=B1=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/styles/theme/darkTheme.ts | 10 +++++----- packages/frontend/src/styles/theme/lightTheme.ts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/frontend/src/styles/theme/darkTheme.ts b/packages/frontend/src/styles/theme/darkTheme.ts index 954cb488..946b082b 100644 --- a/packages/frontend/src/styles/theme/darkTheme.ts +++ b/packages/frontend/src/styles/theme/darkTheme.ts @@ -2,14 +2,14 @@ import { ChartTheme } from '.'; export const darkTheme: ChartTheme = { background: '#1a1a1a', - textColor: 'rgba(255, 255, 255, 0.9)', + textColor: '#ffffffe6', gridLines: '#334158', borderColor: '#485c7b', candlestick: { - upColor: '#4bffb5', - downColor: '#ff4976', - borderUpColor: '#4bffb5', - borderDownColor: '#ff4976', + upColor: '#ff4d4d', + downColor: '#1a75ff', + borderUpColor: '#ff4d4d', + borderDownColor: '#1a75ff', wickUpColor: '#838ca1', wickDownColor: '#838ca1', }, diff --git a/packages/frontend/src/styles/theme/lightTheme.ts b/packages/frontend/src/styles/theme/lightTheme.ts index e927c492..75e2313b 100644 --- a/packages/frontend/src/styles/theme/lightTheme.ts +++ b/packages/frontend/src/styles/theme/lightTheme.ts @@ -2,14 +2,14 @@ import { ChartTheme } from '.'; export const lightTheme: ChartTheme = { background: '#ffffff', - textColor: 'rgba(0, 0, 0, 0.9)', + textColor: '#000000e6', gridLines: '#e0e3eb', borderColor: '#d6dcde', candlestick: { - upColor: '#26a69a', - downColor: '#ef5350', - borderUpColor: '#26a69a', - borderDownColor: '#ef5350', + upColor: '#ff4d4d', + downColor: '#1a75ff', + borderUpColor: '#ff4d4d', + borderDownColor: '#1a75ff', wickUpColor: '#737375', wickDownColor: '#737375', }, From f2f23c1a9b1caa14225251dd7e0a0511cefb4baf Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 16:04:00 +0900 Subject: [PATCH 037/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=BA=94?= =?UTF-8?q?=EB=93=A4=20=EC=B0=A8=ED=8A=B8=EC=99=80=20=ED=9E=88=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EA=B7=B8=EB=9E=A8=EC=9D=84=20=EA=B7=B9=EB=AA=85?= =?UTF-8?q?=ED=95=98=EA=B2=8C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/hooks/useChart.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts index 3039f56b..39405736 100644 --- a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts +++ b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts @@ -29,6 +29,12 @@ export const useChart = ({ containerRef, theme }: UseChartProps) => { const volumeSeries = chart.current.addHistogramSeries( createVolumeOptions(theme), ); + volumeSeries.priceScale().applyOptions({ + scaleMargins: { + top: 0.9, + bottom: 0, + }, + }); volumeSeries.setData(volumeData.data); const candleSeries = chart.current.addCandlestickSeries( From 61d908dc3f8182b5a6dd3698f4582c12a627e122 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 16:33:53 +0900 Subject: [PATCH 038/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20red,=20blue=20?= =?UTF-8?q?=EC=97=B0=ED=95=98=EA=B2=8C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?colorConfig=EB=A1=9C=20=ED=95=A0=EB=8B=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/styles/theme/darkTheme.ts | 15 ++++++++------- .../frontend/src/styles/theme/lightTheme.ts | 17 +++++++++-------- packages/frontend/tailwind.config.js | 4 ++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/frontend/src/styles/theme/darkTheme.ts b/packages/frontend/src/styles/theme/darkTheme.ts index 946b082b..2ea53c4e 100644 --- a/packages/frontend/src/styles/theme/darkTheme.ts +++ b/packages/frontend/src/styles/theme/darkTheme.ts @@ -1,4 +1,8 @@ +import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; +import tailwindConfig from '@/../tailwind.config.js'; + +const colorConfig = resolveConfig(tailwindConfig).theme.colors; export const darkTheme: ChartTheme = { background: '#1a1a1a', @@ -6,14 +10,11 @@ export const darkTheme: ChartTheme = { gridLines: '#334158', borderColor: '#485c7b', candlestick: { - upColor: '#ff4d4d', - downColor: '#1a75ff', - borderUpColor: '#ff4d4d', - borderDownColor: '#1a75ff', + upColor: colorConfig.red, + downColor: colorConfig.blue, + borderUpColor: colorConfig.red, + borderDownColor: colorConfig.blue, wickUpColor: '#838ca1', wickDownColor: '#838ca1', }, - volume: { - color: '#888b90', - }, }; diff --git a/packages/frontend/src/styles/theme/lightTheme.ts b/packages/frontend/src/styles/theme/lightTheme.ts index 75e2313b..94b9e2c1 100644 --- a/packages/frontend/src/styles/theme/lightTheme.ts +++ b/packages/frontend/src/styles/theme/lightTheme.ts @@ -1,19 +1,20 @@ +import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; +import tailwindConfig from '@/../tailwind.config.js'; + +const colorConfig = resolveConfig(tailwindConfig).theme.colors; export const lightTheme: ChartTheme = { - background: '#ffffff', + background: colorConfig.white, textColor: '#000000e6', gridLines: '#e0e3eb', borderColor: '#d6dcde', candlestick: { - upColor: '#ff4d4d', - downColor: '#1a75ff', - borderUpColor: '#ff4d4d', - borderDownColor: '#1a75ff', + upColor: colorConfig.red, + downColor: colorConfig.blue, + borderUpColor: colorConfig.red, + borderDownColor: colorConfig.blue, wickUpColor: '#737375', wickDownColor: '#737375', }, - volume: { - color: '#adaeb2', - }, }; diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.js index f83c1f15..69c2addd 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.js @@ -12,9 +12,9 @@ export default { 'light-yellow': '#ffdcac', 'light-orange': '#ffcfac', orange: '#ffa868', - red: '#eb3636', + red: '#ff4d4d', green: '#7eeb7e', - blue: '#3675eb', + blue: '#1a75ff', }, }, plugins: [], From 8500a2faa5a1bd614417a982d12285d1e6ec816f Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 16:34:40 +0900 Subject: [PATCH 039/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=ED=9E=88=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EA=B7=B8=EB=9E=A8=EC=97=90=EC=84=9C=20=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=20=EA=B0=92=EA=B3=BC=20=EB=B9=84=EA=B5=90=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EC=83=89=EC=83=81=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/hooks/useChart.ts | 4 +++- .../src/utils/getHistogramColorData.ts | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/utils/getHistogramColorData.ts diff --git a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts index 39405736..d279aaa7 100644 --- a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts +++ b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts @@ -8,6 +8,7 @@ import { createChartOptions, createVolumeOptions, } from '@/utils/createChartOptions'; +import { getHistogramColorData } from '@/utils/getHistogramColorData'; interface UseChartProps { containerRef: RefObject; @@ -35,7 +36,8 @@ export const useChart = ({ containerRef, theme }: UseChartProps) => { bottom: 0, }, }); - volumeSeries.setData(volumeData.data); + const histogramData = getHistogramColorData(volumeData.data); + volumeSeries.setData(histogramData); const candleSeries = chart.current.addCandlestickSeries( createCandlestickOptions(theme), diff --git a/packages/frontend/src/utils/getHistogramColorData.ts b/packages/frontend/src/utils/getHistogramColorData.ts new file mode 100644 index 00000000..0a347645 --- /dev/null +++ b/packages/frontend/src/utils/getHistogramColorData.ts @@ -0,0 +1,21 @@ +import resolveConfig from 'tailwindcss/resolveConfig'; +import tailwindConfig from '@/../tailwind.config.js'; + +// TODO: api 나오면 객체/위치 수정 +interface VolumeData { + time: string; + value: number; +} + +const colorConfig = resolveConfig(tailwindConfig).theme.colors; + +export const getHistogramColorData = (data: VolumeData[]) => { + return data.map((item, index) => { + const color = + index === 0 || item.value >= data[index - 1].value + ? colorConfig.red + : colorConfig.blue; + + return { time: item.time, value: item.value, color }; + }); +}; From 87c4a94778b5326259a56051d77f227db239e3c8 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 16:35:01 +0900 Subject: [PATCH 040/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20volume=20color=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/styles/theme/types.ts | 3 --- packages/frontend/src/utils/createChartOptions.ts | 7 +++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/styles/theme/types.ts b/packages/frontend/src/styles/theme/types.ts index fbac10c5..4a9ea7a1 100644 --- a/packages/frontend/src/styles/theme/types.ts +++ b/packages/frontend/src/styles/theme/types.ts @@ -13,7 +13,4 @@ export interface ChartTheme extends DeepPartial { wickUpColor: string; wickDownColor: string; }; - volume: { - color: string; - }; } diff --git a/packages/frontend/src/utils/createChartOptions.ts b/packages/frontend/src/utils/createChartOptions.ts index 92764919..b6618aa8 100644 --- a/packages/frontend/src/utils/createChartOptions.ts +++ b/packages/frontend/src/utils/createChartOptions.ts @@ -32,10 +32,9 @@ export const createChartOptions = (theme: ChartTheme) => { }; }; -export const createVolumeOptions = ( - theme: ChartTheme, -): DeepPartial => ({ - color: theme.volume.color, +export const createVolumeOptions = (): DeepPartial< + HistogramStyleOptions & SeriesOptionsCommon +> => ({ priceLineWidth: 2, priceFormat: { type: 'volume', From 46e6a5c68b3ae429d08d17c7860ff938399d4e21 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 18:10:16 +0900 Subject: [PATCH 041/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20scaleMargins=20?= =?UTF-8?q?=EB=B2=94=EC=9C=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/hooks/useChart.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts index d279aaa7..eecff959 100644 --- a/packages/frontend/src/pages/stock-detail/hooks/useChart.ts +++ b/packages/frontend/src/pages/stock-detail/hooks/useChart.ts @@ -28,11 +28,11 @@ export const useChart = ({ containerRef, theme }: UseChartProps) => { }); const volumeSeries = chart.current.addHistogramSeries( - createVolumeOptions(theme), + createVolumeOptions(), ); volumeSeries.priceScale().applyOptions({ scaleMargins: { - top: 0.9, + top: 0.93, bottom: 0, }, }); From 4101fe4790b1434cdfbe21eb7a0d745656bdb7ac Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 22:44:58 +0900 Subject: [PATCH 042/209] =?UTF-8?q?=E2=9C=A8=20feat:=20tooltip=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/ui/Tooltip.tsx | 22 +++++++++++++++++++ packages/frontend/src/components/ui/index.ts | 1 + 2 files changed, 23 insertions(+) create mode 100644 packages/frontend/src/components/ui/Tooltip.tsx diff --git a/packages/frontend/src/components/ui/Tooltip.tsx b/packages/frontend/src/components/ui/Tooltip.tsx new file mode 100644 index 00000000..c59cf959 --- /dev/null +++ b/packages/frontend/src/components/ui/Tooltip.tsx @@ -0,0 +1,22 @@ +import { type ReactNode } from 'react'; +import { cn } from '@/utils/cn'; + +interface TooltipProps { + className?: string; + children?: ReactNode; +} + +export const Tooltip = ({ className, children }: TooltipProps) => { + return ( +
        + {children} +
        +
        + ); +}; diff --git a/packages/frontend/src/components/ui/index.ts b/packages/frontend/src/components/ui/index.ts index 8b166a86..4860d437 100644 --- a/packages/frontend/src/components/ui/index.ts +++ b/packages/frontend/src/components/ui/index.ts @@ -1 +1,2 @@ export * from './Button'; +export * from './Tooltip'; From 9d3536b2c3df63503df7fa2d546e2a713fbeb85b Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 22:45:27 +0900 Subject: [PATCH 043/209] =?UTF-8?q?=E2=9C=A8=20feat:=20metric=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=A0=95=EB=B3=B4=20=EA=B0=9D=EC=B2=B4=EB=A5=BC=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/constants/METRIC_DETAILS.ts | 38 +++++++++++++++++++ packages/frontend/src/mocks/data.json | 13 ------- 2 files changed, 38 insertions(+), 13 deletions(-) create mode 100644 packages/frontend/src/constants/METRIC_DETAILS.ts delete mode 100644 packages/frontend/src/mocks/data.json diff --git a/packages/frontend/src/constants/METRIC_DETAILS.ts b/packages/frontend/src/constants/METRIC_DETAILS.ts new file mode 100644 index 00000000..2f5150e8 --- /dev/null +++ b/packages/frontend/src/constants/METRIC_DETAILS.ts @@ -0,0 +1,38 @@ +export const METRIC_DETAILS = { + tradingVolume: { + name: '거래량', + message: '특정 기간 동안 거래된 주식의 수량이에요.', + }, + price: { + currentPrice: { + name: '현재가', + message: '현재 주식의 거래 가격이에요.', + }, + tradingVolume: { + name: '거래량', + message: '해당 기간 동안 거래된 주식의 수량이에요.', + }, + fluctuationRate: { + name: '변동률', + message: '전일 대비 주가 변동 비율이에요.', + }, + fiftyTwoWeekRange: { + name: '52주 최고/최저가', + message: '최근 52주 동안의 최고/최저 주가예요.', + }, + }, + enterpriseValue: { + marketCap: { + name: '시가총액', + message: '발행 주식 수와 현재 가격을 곱한 값으로, 기업가치를 나타내요.', + }, + per: { + name: 'PER', + message: '주가/주당순이익으로, 주식의 투자 매력도를 나타내요.', + }, + eps: { + name: 'EPS', + message: '주당순이익으로, 기업의 수익성을 보여줘요.', + }, + }, +}; diff --git a/packages/frontend/src/mocks/data.json b/packages/frontend/src/mocks/data.json deleted file mode 100644 index f30d80ac..00000000 --- a/packages/frontend/src/mocks/data.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "price": [ - { "label": "현재가", "value": "00.000" }, - { "label": "52주 최고가", "value": "00.000" }, - { "label": "변동률", "value": "00.000" }, - { "label": "52주 최저가", "value": "00.000" } - ], - "enterprise value": [ - { "label": "시가총액", "value": "00.000" }, - { "label": "EPS", "value": "00.000" }, - { "label": "PER", "value": "00.000" } - ] -} From b4a1523698dd9207af16f5e1f5401354bfd231c6 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 22:46:00 +0900 Subject: [PATCH 044/209] =?UTF-8?q?=E2=9C=A8=20feat:=20metric=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EC=97=90=20hover=20=EB=90=90=EC=9D=84=20=EB=95=8C=20m?= =?UTF-8?q?essage=20=EC=B6=9C=EB=A0=A5=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/stock-detail/StockMetricsPanel.tsx | 19 ++++++++++++++----- .../stock-detail/components/MetricItem.tsx | 17 ++++++++++++----- .../stock-detail/components/MetricSection.tsx | 7 +++---- .../pages/stock-detail/components/Title.tsx | 4 +++- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx index bc510cb9..3cbc0026 100644 --- a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx @@ -1,17 +1,26 @@ import { MetricSection, Title } from './components'; -import mockData from '@/mocks/data.json'; +import { Tooltip } from '@/components/ui'; +import { METRIC_DETAILS } from '@/constants/METRIC_DETAILS'; export const StockMetricsPanel = () => { return (
        -
        - 거래량 +
        +
        + + {METRIC_DETAILS.tradingVolume.message} + + {METRIC_DETAILS.tradingVolume.name} +
        00.000
        - +
        ); diff --git a/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx b/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx index 4e6877ba..6ee7342e 100644 --- a/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx +++ b/packages/frontend/src/pages/stock-detail/components/MetricItem.tsx @@ -1,13 +1,20 @@ +import { Tooltip } from '@/components/ui'; + export interface MetricItemProps { - label: string; - value: string; + name: string; + message: string; } -export const MetricItem = ({ label, value }: MetricItemProps) => { +export const MetricItem = ({ name, message }: MetricItemProps) => { return ( <> - {label} - {value} +
        + {message} + + {name} + +
        + 00.000 ); }; diff --git a/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx index 572d2a2a..ec057170 100644 --- a/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx +++ b/packages/frontend/src/pages/stock-detail/components/MetricSection.tsx @@ -1,5 +1,4 @@ -import { type MetricItemProps } from './MetricItem'; -import { Title, MetricItem } from '.'; +import { Title, MetricItem, type MetricItemProps } from '.'; interface MetricSectionProps { title: string; @@ -11,8 +10,8 @@ export const MetricSection = ({ title, metricInfo }: MetricSectionProps) => {
        {title}
        - {metricInfo.map((info) => ( - + {Object.values(metricInfo).map((info) => ( + ))}
        diff --git a/packages/frontend/src/pages/stock-detail/components/Title.tsx b/packages/frontend/src/pages/stock-detail/components/Title.tsx index 609ade3a..2aab6a93 100644 --- a/packages/frontend/src/pages/stock-detail/components/Title.tsx +++ b/packages/frontend/src/pages/stock-detail/components/Title.tsx @@ -5,5 +5,7 @@ interface TitleProps { } export const Title = ({ children }: TitleProps) => { - return

        {children}

        ; + return ( +

        {children}

        + ); }; From 609494d6e1b7cab3f16b459cea45bb37c706f4dd Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 14:52:02 +0900 Subject: [PATCH 045/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EB=B6=81=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/.gitignore | 2 + packages/frontend/.storybook/main.ts | 28 + packages/frontend/.storybook/preview.ts | 11 + packages/frontend/package.json | 20 +- yarn.lock | 1024 ++++++++++++++++++++++- 5 files changed, 1064 insertions(+), 21 deletions(-) create mode 100644 packages/frontend/.storybook/main.ts create mode 100644 packages/frontend/.storybook/preview.ts diff --git a/packages/frontend/.gitignore b/packages/frontend/.gitignore index a547bf36..f940a995 100644 --- a/packages/frontend/.gitignore +++ b/packages/frontend/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? + +*storybook.log diff --git a/packages/frontend/.storybook/main.ts b/packages/frontend/.storybook/main.ts new file mode 100644 index 00000000..9240670a --- /dev/null +++ b/packages/frontend/.storybook/main.ts @@ -0,0 +1,28 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +import { join, dirname } from 'path'; + +/** + * This function is used to resolve the absolute path of a package. + * It is needed in projects that use Yarn PnP or are set up within a monorepo. + */ +function getAbsolutePath(value: string) { + return dirname(require.resolve(join(value, 'package.json'))); +} +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + getAbsolutePath('@storybook/addon-onboarding'), + getAbsolutePath('@storybook/addon-essentials'), + getAbsolutePath('@chromatic-com/storybook'), + getAbsolutePath('@storybook/addon-interactions'), + ], + framework: { + name: getAbsolutePath('@storybook/react-vite'), + options: {}, + }, + core: { + builder: getAbsolutePath('@storybook/builder-vite'), + }, +}; +export default config; diff --git a/packages/frontend/.storybook/preview.ts b/packages/frontend/.storybook/preview.ts new file mode 100644 index 00000000..b20bf8b4 --- /dev/null +++ b/packages/frontend/.storybook/preview.ts @@ -0,0 +1,11 @@ +import '@/index.css'; + +export const parameters = { + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, +}; diff --git a/packages/frontend/package.json b/packages/frontend/package.json index aefde7c1..067b43c4 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -7,7 +7,9 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "dependencies": { "@tanstack/react-query": "^5.59.19", @@ -20,7 +22,16 @@ "tailwind-merge": "^2.5.4" }, "devDependencies": { + "@chromatic-com/storybook": "3.2.2", "@eslint/js": "^9.13.0", + "@storybook/addon-essentials": "8.4.3", + "@storybook/addon-interactions": "8.4.3", + "@storybook/addon-onboarding": "8.4.3", + "@storybook/blocks": "8.4.3", + "@storybook/builder-vite": "^8.4.3", + "@storybook/react": "8.4.3", + "@storybook/react-vite": "8.4.3", + "@storybook/test": "8.4.3", "@types/node": "^22.8.7", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", @@ -30,13 +41,20 @@ "eslint-plugin-import": "^2.31.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", + "eslint-plugin-storybook": "^0.11.0", "globals": "^15.11.0", "postcss": "^8.4.47", "prettier-plugin-tailwindcss": "^0.6.8", + "storybook": "8.4.3", "tailwindcss": "^3.4.14", "typescript": "~5.6.2", "typescript-eslint": "^8.11.0", "vite": "^5.4.10", "vite-plugin-svgr": "^4.3.0" + }, + "eslintConfig": { + "extends": [ + "plugin:storybook/recommended" + ] } } diff --git a/yarn.lock b/yarn.lock index 47956924..7612ff5b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.0.tgz#728c484f4e10df03d5a3acd0d8adcbbebff8ad63" + integrity sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ== + "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" @@ -73,7 +78,7 @@ ora "5.4.1" rxjs "7.8.1" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== @@ -87,7 +92,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.25.2": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== @@ -315,6 +320,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.9" +"@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.25.9", "@babel/template@^7.3.3": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" @@ -324,7 +336,7 @@ "@babel/parser" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/traverse@^7.25.9": +"@babel/traverse@^7.18.9", "@babel/traverse@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== @@ -337,7 +349,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.18.9", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.3.3": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== @@ -350,6 +362,17 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@chromatic-com/storybook@3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@chromatic-com/storybook/-/storybook-3.2.2.tgz#08754443de55618f802f88450c35266fd6d25db5" + integrity sha512-xmXt/GW0hAPbzNTrxYuVo43Adrtjue4DeVrsoIIEeJdGaPNNeNf+DHMlJKOBdlHmCnFUoe9R/0mLM9zUp5bKWw== + dependencies: + chromatic "^11.15.0" + filesize "^10.0.12" + jsonfile "^6.1.0" + react-confetti "^6.1.0" + strip-ansi "^7.1.0" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -522,116 +545,236 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== +"@esbuild/aix-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.0.tgz#b57697945b50e99007b4c2521507dc613d4a648c" + integrity sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw== + "@esbuild/android-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== +"@esbuild/android-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.0.tgz#1add7e0af67acefd556e407f8497e81fddad79c0" + integrity sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w== + "@esbuild/android-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== +"@esbuild/android-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.0.tgz#ab7263045fa8e090833a8e3c393b60d59a789810" + integrity sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew== + "@esbuild/android-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== +"@esbuild/android-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.0.tgz#e8f8b196cfdfdd5aeaebbdb0110983460440e705" + integrity sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ== + "@esbuild/darwin-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== +"@esbuild/darwin-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.0.tgz#2d0d9414f2acbffd2d86e98253914fca603a53dd" + integrity sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw== + "@esbuild/darwin-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== +"@esbuild/darwin-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.0.tgz#33087aab31a1eb64c89daf3d2cf8ce1775656107" + integrity sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA== + "@esbuild/freebsd-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== +"@esbuild/freebsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.0.tgz#bb76e5ea9e97fa3c753472f19421075d3a33e8a7" + integrity sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA== + "@esbuild/freebsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== +"@esbuild/freebsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.0.tgz#e0e2ce9249fdf6ee29e5dc3d420c7007fa579b93" + integrity sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ== + "@esbuild/linux-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== +"@esbuild/linux-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.0.tgz#d1b2aa58085f73ecf45533c07c82d81235388e75" + integrity sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g== + "@esbuild/linux-arm@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== +"@esbuild/linux-arm@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.0.tgz#8e4915df8ea3e12b690a057e77a47b1d5935ef6d" + integrity sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw== + "@esbuild/linux-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== +"@esbuild/linux-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.0.tgz#8200b1110666c39ab316572324b7af63d82013fb" + integrity sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA== + "@esbuild/linux-loong64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== +"@esbuild/linux-loong64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.0.tgz#6ff0c99cf647504df321d0640f0d32e557da745c" + integrity sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g== + "@esbuild/linux-mips64el@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== +"@esbuild/linux-mips64el@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.0.tgz#3f720ccd4d59bfeb4c2ce276a46b77ad380fa1f3" + integrity sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA== + "@esbuild/linux-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== +"@esbuild/linux-ppc64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.0.tgz#9d6b188b15c25afd2e213474bf5f31e42e3aa09e" + integrity sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ== + "@esbuild/linux-riscv64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== +"@esbuild/linux-riscv64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.0.tgz#f989fdc9752dfda286c9cd87c46248e4dfecbc25" + integrity sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw== + "@esbuild/linux-s390x@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== +"@esbuild/linux-s390x@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.0.tgz#29ebf87e4132ea659c1489fce63cd8509d1c7319" + integrity sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g== + "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== +"@esbuild/linux-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.0.tgz#4af48c5c0479569b1f359ffbce22d15f261c0cef" + integrity sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA== + "@esbuild/netbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== +"@esbuild/netbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.0.tgz#1ae73d23cc044a0ebd4f198334416fb26c31366c" + integrity sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg== + +"@esbuild/openbsd-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.0.tgz#5d904a4f5158c89859fd902c427f96d6a9e632e2" + integrity sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg== + "@esbuild/openbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== +"@esbuild/openbsd-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.0.tgz#4c8aa88c49187c601bae2971e71c6dc5e0ad1cdf" + integrity sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q== + "@esbuild/sunos-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== +"@esbuild/sunos-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.0.tgz#8ddc35a0ea38575fa44eda30a5ee01ae2fa54dd4" + integrity sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA== + "@esbuild/win32-arm64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== +"@esbuild/win32-arm64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.0.tgz#6e79c8543f282c4539db684a207ae0e174a9007b" + integrity sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA== + "@esbuild/win32-ia32@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== +"@esbuild/win32-ia32@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.0.tgz#057af345da256b7192d18b676a02e95d0fa39103" + integrity sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw== + "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== +"@esbuild/win32-x64@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.0.tgz#168ab1c7e1c318b922637fad8f339d48b01e1244" + integrity sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" @@ -972,6 +1115,16 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@joshwooding/vite-plugin-react-docgen-typescript@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.3.0.tgz#67599fca260c2eafdaf234a944f9d471e6d53b08" + integrity sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA== + dependencies: + glob "^7.2.0" + glob-promise "^4.2.0" + magic-string "^0.27.0" + react-docgen-typescript "^2.2.2" + "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -999,7 +1152,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== @@ -1032,6 +1185,13 @@ resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe" integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA== +"@mdx-js/react@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed" + integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ== + dependencies: + "@types/mdx" "^2.0.0" + "@nestjs/cli@^10.0.0": version "10.4.5" resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-10.4.5.tgz#d6563b87e8ca1d0f256c19a7847dbcc96c76a88e" @@ -1152,7 +1312,7 @@ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== -"@rollup/pluginutils@^5.1.3": +"@rollup/pluginutils@^5.0.2", "@rollup/pluginutils@^5.1.3": version "5.1.3" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz#3001bf1a03f3ad24457591f2c259c8e514e0dbdf" integrity sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A== @@ -1275,6 +1435,250 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@storybook/addon-actions@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.4.3.tgz#1645b5bd5e11cab64debf4e113238a4b84212f64" + integrity sha512-3lPiMszzxi7YWouIiWSLELCQNFLY2ABmD7O1u2+i/0ZXZZeHqIrhdNoVCj9j0qMisAe9neYzDWLfyKX5yv226g== + dependencies: + "@storybook/global" "^5.0.0" + "@types/uuid" "^9.0.1" + dequal "^2.0.2" + polished "^4.2.2" + uuid "^9.0.0" + +"@storybook/addon-backgrounds@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.4.3.tgz#3ab3dbf4314d1fe8b66e77bb9468d642413a6734" + integrity sha512-m3kTxtn+GgO1dj+qVUYV8LnYEVbeITUk+iXJlCBoYQptmWOmOry0KBSk3m/eWlWPeI42X6btwrLtXzMziC2RGA== + dependencies: + "@storybook/global" "^5.0.0" + memoizerific "^1.11.3" + ts-dedent "^2.0.0" + +"@storybook/addon-controls@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.4.3.tgz#fd72beb60ba0c6de5db17038a05fe93e84263fd6" + integrity sha512-KPX1IxI60C0iLNYlkGVuRT+YKbSdbdy//pc2eDHWktxY0TnDymc3VWaSxNvIOpZK8N7ut1/UP/qb+sH/ckW7SA== + dependencies: + "@storybook/global" "^5.0.0" + dequal "^2.0.2" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.4.3.tgz#6c2ffdb3a03cb015edf590e9a5beac8d381bdebb" + integrity sha512-3xSYtbg+pjZiQIzJJOKlSXgxxRvRSdQYMQbAZoJVizGpb2y5OpEKiAoP1wuOaYTD8t2wlBgpi/aEx7qHAWaDbA== + dependencies: + "@mdx-js/react" "^3.0.0" + "@storybook/blocks" "8.4.3" + "@storybook/csf-plugin" "8.4.3" + "@storybook/react-dom-shim" "8.4.3" + react "^16.8.0 || ^17.0.0 || ^18.0.0" + react-dom "^16.8.0 || ^17.0.0 || ^18.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-essentials@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.4.3.tgz#1d5b283ef72492dc15a1985f4e98508a72a99f6a" + integrity sha512-5SOC8FUJHVhicbLlaD9D+BKa556Zc0XnsXgkFWgeXhNSXRcM1ZrhUFWxVYGMAyXBZ3lmeYHNo/mYxDBnD2fWPQ== + dependencies: + "@storybook/addon-actions" "8.4.3" + "@storybook/addon-backgrounds" "8.4.3" + "@storybook/addon-controls" "8.4.3" + "@storybook/addon-docs" "8.4.3" + "@storybook/addon-highlight" "8.4.3" + "@storybook/addon-measure" "8.4.3" + "@storybook/addon-outline" "8.4.3" + "@storybook/addon-toolbars" "8.4.3" + "@storybook/addon-viewport" "8.4.3" + ts-dedent "^2.0.0" + +"@storybook/addon-highlight@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.4.3.tgz#8f5a74ee9aff68b9ded18506673da3c99259611f" + integrity sha512-MfBvokTJkbynHBceA2SgvFvS7Tpdv6FxzSZbeVtJHyYBqXrobj8llpo4n2IqAo/f3otcapN64wK82Jl4u8dYVg== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/addon-interactions@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-8.4.3.tgz#7e1dc73f81e53891e2e497b419692fb3a847cf09" + integrity sha512-PLc5qM5/CtVcSSVmoyS+dgJNvLN3Z99PwcbDb7y0a2/tSd+LGQ6pEB02OtHWyJepkzKulMV7k9SwpywD2XsToA== + dependencies: + "@storybook/global" "^5.0.0" + "@storybook/instrumenter" "8.4.3" + "@storybook/test" "8.4.3" + polished "^4.2.2" + ts-dedent "^2.2.0" + +"@storybook/addon-measure@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.4.3.tgz#14e9024c77c00db4386fec3728f5afa3a826a8a2" + integrity sha512-R9m71P6LDNr7cUtDgWWPBRB/GQfv8hdDjWbD/HfqPkGi49RtBXf/zzFr7OrzgwaT9A73VEM74FGOhCZyHz5Qtg== + dependencies: + "@storybook/global" "^5.0.0" + tiny-invariant "^1.3.1" + +"@storybook/addon-onboarding@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-onboarding/-/addon-onboarding-8.4.3.tgz#e87b01cd4798e7fe12d329e8e0f3ea91ba7b6177" + integrity sha512-GR384uns/cb0nhjEab+woOrWDiZYJeq5RLEfHoLePvSm75cmZ785U9jxirUh8uX+/RxRok7b/TjGmd5EMxYhfg== + dependencies: + react-confetti "^6.1.0" + +"@storybook/addon-outline@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.4.3.tgz#77c20fdab16327761c74a195e3c73f3e15dda319" + integrity sha512-9dMmh6uQrlJUlKvH+rxEvvo8BCYznRa/YxLoGtgNzh5EbbSR03IVqgfZPpE4ewZidsfCL3Jf3cPjwSuWs3dxLA== + dependencies: + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-toolbars@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.4.3.tgz#13617fe0b6ab8d6c11338ac8a98a9cf96f0a1dce" + integrity sha512-lW7p7VPeUDIqS0RAXY4yRQ4LCQWGzGdw64moU20NpeVfedfDc4EeCisLD54sU/xA6kMnxoFNYsdHfpkHvJA/Cg== + +"@storybook/addon-viewport@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.4.3.tgz#2231e6ee739be100f1922855219606cae404e4bb" + integrity sha512-KUstpUx++5cWXMXlz9jBhM6qDW9rwtKMvTyJV24TmhYIDmynset2ILRknIqLbVdBixop40+I67O3SF/ydU4E0w== + dependencies: + memoizerific "^1.11.3" + +"@storybook/blocks@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.4.3.tgz#03017dd47349b7014f5bc15d3451a95c4b4ddcc8" + integrity sha512-PPC+RXievuHKYlL+oO4ygllT59YzpESklNfeHUkeyuSo0nr04UwSrbfdsQlYJo3nRP0wNKyj/NkYDvzMJ5RlTg== + dependencies: + "@storybook/csf" "^0.1.11" + "@storybook/icons" "^1.2.12" + ts-dedent "^2.0.0" + +"@storybook/builder-vite@8.4.3", "@storybook/builder-vite@^8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-8.4.3.tgz#f0df25908272851113fcee3b234b3931b8eed6af" + integrity sha512-kLM2vPKOo/yAavYmQgt0qO8kU/vDYuHRq3/AH9g4AvU155u9NeY5u5p8V4KtEHIDxWNmIOD2C09nDkk7DA22sw== + dependencies: + "@storybook/csf-plugin" "8.4.3" + browser-assert "^1.2.1" + ts-dedent "^2.0.0" + +"@storybook/components@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.4.3.tgz#830f91317da80ffe6b9ab7321a90b3afe2602585" + integrity sha512-5+krpYrKC0aLUlkfhKLR78Yrai0S9AP7SR3jXMpyuWIny0fIKn+Ak2IQ721A6RGW+zP02GR6/wLHI+A7CDpcAg== + +"@storybook/core@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-8.4.3.tgz#218b68087c955d6ee6eaf1d454855e87da45087a" + integrity sha512-Ly4sR2gU2Xxu+O0qR4RJpq+Bs45Kv0JPlzdkoTDKQD8B2ozRAdvQLgBHjnBbUYw9jUPzC96uusqTJIBxIdBi7w== + 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" + +"@storybook/csf-plugin@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.4.3.tgz#90355a4cb8958de82b459b7c1489424b8fefc9b5" + integrity sha512-lS3qJ1qBZk7ddu3O+1hmmp+eDsQ/pOTKuTCJY7Zaoyze97LnLtYRs3FbfPhievVWiIoPdnXtK+mcssR9N9AHMw== + dependencies: + unplugin "^1.3.1" + +"@storybook/csf@^0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.11.tgz#ad685a4fe564a47a6b73571c2e7c07b526f4f71b" + integrity sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg== + dependencies: + type-fest "^2.19.0" + +"@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + +"@storybook/icons@^1.2.12": + version "1.2.12" + resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.12.tgz#3e4c939113b67df7ab17b78f805dbb57f4acf0db" + integrity sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q== + +"@storybook/instrumenter@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-8.4.3.tgz#1cf2200334efda87d5e876fcdef5241310a1ee28" + integrity sha512-jEMi3CFlyeMQv6V/WWPnL10Qgqn5j03pXXnfLylGcrvLnl1pa1A6sDWqeB6XR2L1HuW96XelkMecCvp5pYXAdQ== + dependencies: + "@storybook/global" "^5.0.0" + "@vitest/utils" "^2.1.1" + +"@storybook/manager-api@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.4.3.tgz#a2a3e2b2f8e6654bff6f732808c6a8e3d9c5c3d6" + integrity sha512-b09FHQLHrc3VGdodgV+EkA6V8VhpgadygDn9aVIXUULHXMQCfzzsSK9kiunFGVjH5r4BtdanucBXoBRFAi9D/g== + +"@storybook/preview-api@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.4.3.tgz#c48c524f4eee79d0ed2458d88a8d6ee2f6518530" + integrity sha512-SQPiGJ5iNk/RMZTfTQZe27MaZz16XfIgb1GTDWuaSrDBWVcelHRCZdh8Ps+9X5Mre6GeZ9wMQ56l+hQf/DO9Ug== + +"@storybook/react-dom-shim@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.4.3.tgz#8515c782df8d59e3381266bff5fddaf4b903190e" + integrity sha512-0zFfPJsDzqEMXk6CEHOIPRR8BcST/X4UbZDZmQBVrzOlmJWdyx1nFK7BT9bbJvb6N9v2Qy6yHL3b2wzZqkDezA== + +"@storybook/react-vite@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-8.4.3.tgz#de306c55114fa2edbdbffeb35b42a6cfd09edc62" + integrity sha512-5M6sZLmD0PogJnhuWNgXySJux/NbRinz7fznj+05to/t8uIgqx6UDu5tZO0LWnSw7K/NsHnvLLwhhzttM3X8zQ== + dependencies: + "@joshwooding/vite-plugin-react-docgen-typescript" "0.3.0" + "@rollup/pluginutils" "^5.0.2" + "@storybook/builder-vite" "8.4.3" + "@storybook/react" "8.4.3" + find-up "^5.0.0" + magic-string "^0.30.0" + react-docgen "^7.0.0" + resolve "^1.22.8" + tsconfig-paths "^4.2.0" + +"@storybook/react@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.4.3.tgz#29a77605344a12c99ea2bdfb7f4de04eac88e961" + integrity sha512-Dz7Kt81lGjS+b4LLOKyLK5Ifp9ZzfD0pwOM2r5QYuBcD5b1I4I6gpRoTfQI/dI6bk5WevVqeOZ2iigZAnaXNGw== + dependencies: + "@storybook/components" "8.4.3" + "@storybook/global" "^5.0.0" + "@storybook/manager-api" "8.4.3" + "@storybook/preview-api" "8.4.3" + "@storybook/react-dom-shim" "8.4.3" + "@storybook/theming" "8.4.3" + +"@storybook/test@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/test/-/test-8.4.3.tgz#c6a737d30f120448c79ec54da0f172b762306d3a" + integrity sha512-R4KMIZE4S7GyFE4AFD9FESv2Ws406lsg9GFrBaiJGrzOlRKe5yJ7w1MWOu76UclqRNlQHzaEOnOE6lEHVISsDQ== + dependencies: + "@storybook/csf" "^0.1.11" + "@storybook/global" "^5.0.0" + "@storybook/instrumenter" "8.4.3" + "@testing-library/dom" "10.4.0" + "@testing-library/jest-dom" "6.5.0" + "@testing-library/user-event" "14.5.2" + "@vitest/expect" "2.0.5" + "@vitest/spy" "2.0.5" + +"@storybook/theming@8.4.3": + version "8.4.3" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.4.3.tgz#c264898c7668457a729c238cc463d7600f2a5f03" + integrity sha512-ORQY2/C488ur5NkQYes6x+fO5rcyRMyh4uX3DlkNhCsA2CJ/Ik3WVGjprrDuLn+9S4+mtXfVUNfvN7xszlT1oA== + "@svgr/babel-plugin-add-jsx-attribute@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" @@ -1370,6 +1774,38 @@ dependencies: "@tanstack/query-core" "5.59.17" +"@testing-library/dom@10.4.0": + version "10.4.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8" + integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz#50484da3f80fb222a853479f618a9ce5c47bfe54" + integrity sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA== + dependencies: + "@adobe/css-tools" "^4.4.0" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.6.3" + lodash "^4.17.21" + redent "^3.0.0" + +"@testing-library/user-event@14.5.2": + version "14.5.2" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.2.tgz#db7257d727c891905947bd1c1a99da20e03c2ebd" + integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== + "@tsconfig/node10@^1.0.7": version "1.0.11" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" @@ -1390,7 +1826,12 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@types/babel__core@^7.1.14", "@types/babel__core@^7.20.5": +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + +"@types/babel__core@^7.1.14", "@types/babel__core@^7.18.0", "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== @@ -1416,7 +1857,7 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6", "@types/babel__traverse@^7.18.0": version "7.20.6" resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== @@ -1450,6 +1891,11 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.5.tgz#14a3e83fa641beb169a2dd8422d91c3c345a9a78" integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== +"@types/doctrine@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" + integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== + "@types/estree@1.0.6", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" @@ -1475,6 +1921,14 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/glob@^7.1.3": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + "@types/graceful-fs@^4.1.3": version "4.1.9" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" @@ -1524,6 +1978,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/mdx@^2.0.0": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== + "@types/methods@^1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@types/methods/-/methods-1.1.4.tgz#d3b7ac30ac47c91054ea951ce9eed07b1051e547" @@ -1534,6 +1993,11 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== +"@types/minimatch@*": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + "@types/node@*", "@types/node@^22.8.7": version "22.8.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.7.tgz#04ab7a073d95b4a6ee899f235d43f3c320a976f4" @@ -1578,6 +2042,11 @@ "@types/prop-types" "*" csstype "^3.0.2" +"@types/resolve@^1.20.2": + version "1.20.6" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" + integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== + "@types/send@*": version "0.17.4" resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" @@ -1618,6 +2087,11 @@ "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -1664,6 +2138,14 @@ "@typescript-eslint/types" "8.12.2" "@typescript-eslint/visitor-keys" "8.12.2" +"@typescript-eslint/scope-manager@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz#01f37c147a735cd78f0ff355e033b9457da1f373" + integrity sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw== + dependencies: + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/visitor-keys" "8.14.0" + "@typescript-eslint/type-utils@8.12.2": version "8.12.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.12.2.tgz#132b0c52d45f6814e6f2e32416c7951ed480b016" @@ -1679,6 +2161,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.12.2.tgz#8d70098c0e90442495b53d0296acdca6d0f3f73c" integrity sha512-VwDwMF1SZ7wPBUZwmMdnDJ6sIFk4K4s+ALKLP6aIQsISkPv8jhiw65sAK6SuWODN/ix+m+HgbYDkH+zLjrzvOA== +"@typescript-eslint/types@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.14.0.tgz#0d33d8d0b08479c424e7d654855fddf2c71e4021" + integrity sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g== + "@typescript-eslint/typescript-estree@8.12.2": version "8.12.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.12.2.tgz#206df9b1cbff212aaa9401985ef99f04daa84da5" @@ -1693,6 +2180,20 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/typescript-estree@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz#a7a3a5a53a6c09313e12fb4531d4ff582ee3c312" + integrity sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ== + dependencies: + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/visitor-keys" "8.14.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/utils@8.12.2": version "8.12.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.12.2.tgz#726cc9f49f5866605bd15bbc1768ffc15637930e" @@ -1703,6 +2204,16 @@ "@typescript-eslint/types" "8.12.2" "@typescript-eslint/typescript-estree" "8.12.2" +"@typescript-eslint/utils@^8.8.1": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.14.0.tgz#ac2506875e03aba24e602364e43b2dfa45529dbd" + integrity sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.14.0" + "@typescript-eslint/types" "8.14.0" + "@typescript-eslint/typescript-estree" "8.14.0" + "@typescript-eslint/visitor-keys@8.12.2": version "8.12.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.12.2.tgz#94d7410f78eb6d134b9fcabaf1eeedb910ba8c38" @@ -1711,6 +2222,14 @@ "@typescript-eslint/types" "8.12.2" eslint-visitor-keys "^3.4.3" +"@typescript-eslint/visitor-keys@8.14.0": + version "8.14.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz#2418d5a54669af9658986ade4e6cfb7767d815ad" + integrity sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ== + dependencies: + "@typescript-eslint/types" "8.14.0" + eslint-visitor-keys "^3.4.3" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -1727,6 +2246,56 @@ "@types/babel__core" "^7.20.5" react-refresh "^0.14.2" +"@vitest/expect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" + integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== + dependencies: + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" + integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.5.tgz#bc79b8826d4a63dc04f2a75d2944694039fa50aa" + integrity sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/spy@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" + integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== + dependencies: + tinyspy "^3.0.0" + +"@vitest/utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" + integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== + dependencies: + "@vitest/pretty-format" "2.0.5" + estree-walker "^3.0.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + +"@vitest/utils@^2.1.1": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.5.tgz#0e19ce677c870830a1573d33ee86b0d6109e9546" + integrity sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg== + dependencies: + "@vitest/pretty-format" "2.1.5" + loupe "^3.1.2" + tinyrainbow "^1.2.0" + "@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" @@ -2039,6 +2608,18 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-query@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +aria-query@^5.0.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" + integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== + array-buffer-byte-length@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" @@ -2125,6 +2706,18 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + +ast-types@^0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" + integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== + dependencies: + tslib "^2.0.1" + async@^3.2.3: version "3.2.6" resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" @@ -2232,6 +2825,13 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +better-opn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" + integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== + dependencies: + open "^8.0.4" + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" @@ -2286,6 +2886,11 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== + browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: version "4.24.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.2.tgz#f5845bc91069dbd55ee89faf9822e1d885d16580" @@ -2376,6 +2981,17 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001669: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f" integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog== +chai@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + chalk@4.1.2, chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2393,6 +3009,14 @@ chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" @@ -2408,6 +3032,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + chokidar@3.6.0, chokidar@^3.5.3: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" @@ -2423,6 +3052,11 @@ chokidar@3.6.0, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chromatic@^11.15.0: + version "11.18.1" + resolved "https://registry.yarnpkg.com/chromatic/-/chromatic-11.18.1.tgz#c8f7b330dbd9be3b45a84abcb924f5217dc6c326" + integrity sha512-hkNT9vA6K9+PnE/khhZYBnRCOm8NonaQDs7RZ8YHFo7/lh1b/x/uFMkTjWjaj/mkM6QOR/evu5VcZMtcaauSlw== + chrome-trace-event@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" @@ -2755,6 +3389,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -2854,6 +3493,11 @@ dedent@^1.0.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -2880,6 +3524,11 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -2899,6 +3548,11 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +dequal@^2.0.2, dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -2961,6 +3615,16 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + +dom-accessibility-api@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" + integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -3154,6 +3818,43 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +esbuild-register@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d" + integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg== + dependencies: + debug "^4.3.4" + +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.0.tgz#f2d470596885fcb2e91c21eb3da3b3c89c0b55e7" + integrity sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.24.0" + "@esbuild/android-arm" "0.24.0" + "@esbuild/android-arm64" "0.24.0" + "@esbuild/android-x64" "0.24.0" + "@esbuild/darwin-arm64" "0.24.0" + "@esbuild/darwin-x64" "0.24.0" + "@esbuild/freebsd-arm64" "0.24.0" + "@esbuild/freebsd-x64" "0.24.0" + "@esbuild/linux-arm" "0.24.0" + "@esbuild/linux-arm64" "0.24.0" + "@esbuild/linux-ia32" "0.24.0" + "@esbuild/linux-loong64" "0.24.0" + "@esbuild/linux-mips64el" "0.24.0" + "@esbuild/linux-ppc64" "0.24.0" + "@esbuild/linux-riscv64" "0.24.0" + "@esbuild/linux-s390x" "0.24.0" + "@esbuild/linux-x64" "0.24.0" + "@esbuild/netbsd-x64" "0.24.0" + "@esbuild/openbsd-arm64" "0.24.0" + "@esbuild/openbsd-x64" "0.24.0" + "@esbuild/sunos-x64" "0.24.0" + "@esbuild/win32-arm64" "0.24.0" + "@esbuild/win32-ia32" "0.24.0" + "@esbuild/win32-x64" "0.24.0" + esbuild@^0.21.3: version "0.21.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" @@ -3272,6 +3973,15 @@ eslint-plugin-react-refresh@^0.4.14: resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz#e3c611ead69bbf7436d01295c853d4abb8c59f68" integrity sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA== +eslint-plugin-storybook@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.11.0.tgz#97adc63512816a6f8b86040d1364af43d3336099" + integrity sha512-MvPJgF+ORwgK04a1CY5itO4pwdAOFIRqczlNEHL62+4Ocvj1d61GWRqIdeX1BNCKno6fdPC6TksUHCZMGsq26g== + dependencies: + "@storybook/csf" "^0.1.11" + "@typescript-eslint/utils" "^8.8.1" + ts-dedent "^2.2.0" + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3409,7 +4119,7 @@ espree@^9.6.0, espree@^9.6.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -3443,6 +4153,13 @@ estree-walker@^2.0.2: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== +estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -3637,6 +4354,11 @@ filelist@^1.0.4: dependencies: minimatch "^5.0.1" +filesize@^10.0.12: + version "10.1.6" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.6.tgz#31194da825ac58689c0bce3948f33ce83aabd361" + integrity sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w== + fill-range@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" @@ -3917,6 +4639,13 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +glob-promise@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-4.2.2.tgz#15f44bcba0e14219cd93af36da6bb905ff007877" + integrity sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw== + dependencies: + "@types/glob" "^7.1.3" + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" @@ -3934,7 +4663,7 @@ glob@10.4.2: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@7.2.3, glob@^7.1.3, glob@^7.1.4: +glob@7.2.3, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -4164,6 +4893,11 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -4283,6 +5017,14 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-array-buffer@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" @@ -4344,6 +5086,11 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4364,6 +5111,13 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -4444,7 +5198,7 @@ is-text-path@^2.0.0: dependencies: text-extensions "^2.0.0" -is-typed-array@^1.1.13: +is-typed-array@^1.1.13, is-typed-array@^1.1.3: version "1.1.13" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== @@ -4473,6 +5227,13 @@ is-windows@^1.0.1: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -4957,6 +5718,11 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" +jsdoc-type-pratt-parser@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113" + integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg== + jsesc@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" @@ -5009,7 +5775,7 @@ jsonc-parser@3.3.1: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== -jsonfile@^6.0.1: +jsonfile@^6.0.1, jsonfile@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== @@ -5176,6 +5942,11 @@ loose-envify@^1.1.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loupe@^3.1.0, loupe@^3.1.1, loupe@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -5195,6 +5966,11 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + magic-string@0.30.8: version "0.30.8" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" @@ -5202,6 +5978,20 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +magic-string@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" + integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + +magic-string@^0.30.0: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -5221,6 +6011,11 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" +map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -5233,6 +6028,13 @@ memfs@^3.4.1: dependencies: fs-monkey "^1.0.4" +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== + dependencies: + map-or-similar "^1.5.0" + meow@^12.0.1: version "12.1.1" resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" @@ -5303,6 +6105,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-indent@^1.0.0, min-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -5553,6 +6360,15 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +open@^8.0.4: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + optionator@^0.9.3: version "0.9.4" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" @@ -5717,6 +6533,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -5759,6 +6580,13 @@ pluralize@8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== +polished@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" + integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== + dependencies: + "@babel/runtime" "^7.17.8" + possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -5839,6 +6667,15 @@ prettier@^3.3.3: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -5853,6 +6690,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -5913,7 +6755,35 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" -react-dom@^18.3.1: +react-confetti@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.1.0.tgz#03dc4340d955acd10b174dbf301f374a06e29ce6" + integrity sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw== + dependencies: + tween-functions "^1.2.0" + +react-docgen-typescript@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" + integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== + +react-docgen@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.1.0.tgz#4b41e557dab939a5157be09ee532fd09c07d99fc" + integrity sha512-APPU8HB2uZnpl6Vt/+0AFoVYgSRtfiP6FLrZgPPTDmqSb2R4qZRbgd0A3VzIFxDt5e+Fozjx79WjLWnF69DK8g== + dependencies: + "@babel/core" "^7.18.9" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@types/babel__core" "^7.18.0" + "@types/babel__traverse" "^7.18.0" + "@types/doctrine" "^0.0.9" + "@types/resolve" "^1.20.2" + doctrine "^3.0.0" + resolve "^1.22.1" + strip-indent "^4.0.0" + +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -5921,6 +6791,11 @@ react-dom@^18.3.1: loose-envify "^1.1.0" scheduler "^0.23.2" +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^18.0.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" @@ -5946,7 +6821,7 @@ react-router@6.28.0: dependencies: "@remix-run/router" "1.21.0" -react@^18.3.1: +"react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -5989,11 +6864,35 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +recast@^0.23.5: + version "0.23.9" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b" + integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q== + dependencies: + ast-types "^0.16.1" + esprima "~4.0.0" + source-map "~0.6.1" + tiny-invariant "^1.3.3" + tslib "^2.0.1" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + reflect-metadata@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regexp.prototype.flags@^1.5.2: version "1.5.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" @@ -6049,7 +6948,7 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.2, resolve@^1.22.4: +resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4, resolve@^1.22.8: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -6206,7 +7105,7 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: +semver@^7.3.4, semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -6350,7 +7249,7 @@ source-map@0.7.4, source-map@^0.7.4: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== -source-map@^0.6.0, source-map@^0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -6377,6 +7276,13 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +storybook@8.4.3: + version "8.4.3" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.4.3.tgz#2e281f54aa54f082aee7ed9c00c7b6504f247791" + integrity sha512-n+6ME+APinsx0zjNTmx3SntJ4iCgoTK7TsxUC8+op/rUAA8hNbD+/NT7Qx/F5peHNchVeVFGtebPDAHU9g1M/Q== + dependencies: + "@storybook/core" "8.4.3" + streamsearch@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" @@ -6495,7 +7401,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -6517,6 +7423,20 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -6707,11 +7627,26 @@ thenify-all@^1.0.0: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + tinyexec@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98" integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -6751,6 +7686,11 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== +ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" @@ -6839,11 +7779,16 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.6.2: +tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.6.2: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +tween-functions@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" + integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -6866,6 +7811,11 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -6979,6 +7929,14 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +unplugin@^1.3.1: + version "1.15.0" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.15.0.tgz#cd1e92e537ab14a03354d6f83f29d536fac2e5a9" + integrity sha512-jTPIs63W+DUEDW207ztbaoO7cQ4p5aVaB823LSlxpsFEU3Mykwxf3ZGC/wzxFJeZlASZYgVrWeo7LgOrqJZ8RA== + dependencies: + acorn "^8.14.0" + webpack-virtual-modules "^0.6.2" + update-browserslist-db@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" @@ -7006,11 +7964,27 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -7087,6 +8061,11 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== +webpack-virtual-modules@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" + integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== + webpack@5.94.0: version "5.94.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" @@ -7135,7 +8114,7 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.14, which-typed-array@^1.1.15: +which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.2: version "1.1.15" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== @@ -7214,6 +8193,11 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" +ws@^8.2.3: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From 27f361163606c235cd0699b9abc7f4180d1f31e4 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 14:53:22 +0900 Subject: [PATCH 046/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20button,=20toolt?= =?UTF-8?q?ip=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/ui/{ => button}/Button.tsx | 8 ++++---- packages/frontend/src/components/ui/button/index.ts | 1 + .../frontend/src/components/ui/{ => tooltip}/Tooltip.tsx | 2 +- .../frontend/src/components/ui/{ => tooltip}/index.ts | 1 - packages/frontend/src/pages/stock-detail/StockDetail.tsx | 4 +--- .../frontend/src/pages/stock-detail/StockMetricsPanel.tsx | 2 +- .../src/pages/stock-detail/components/MetricItem.tsx | 2 +- 7 files changed, 9 insertions(+), 11 deletions(-) rename packages/frontend/src/components/ui/{ => button}/Button.tsx (89%) create mode 100644 packages/frontend/src/components/ui/button/index.ts rename packages/frontend/src/components/ui/{ => tooltip}/Tooltip.tsx (95%) rename packages/frontend/src/components/ui/{ => tooltip}/index.ts (50%) diff --git a/packages/frontend/src/components/ui/Button.tsx b/packages/frontend/src/components/ui/button/Button.tsx similarity index 89% rename from packages/frontend/src/components/ui/Button.tsx rename to packages/frontend/src/components/ui/button/Button.tsx index c0cb1c4f..7000fb44 100644 --- a/packages/frontend/src/components/ui/Button.tsx +++ b/packages/frontend/src/components/ui/button/Button.tsx @@ -9,11 +9,11 @@ export const ButtonVariants = cva( backgroundColor: { default: 'bg-white', gray: 'bg-gray', - white: 'bg-white', + orange: 'bg-orange', }, textColor: { - default: 'text-white', - orange: 'text-orange', + default: 'text-orange', + white: 'text-white', }, size: { default: 'w-24', @@ -28,7 +28,7 @@ export const ButtonVariants = cva( }, ); -interface ButtonProps +export interface ButtonProps extends ButtonHTMLAttributes, VariantProps { children: ReactNode; diff --git a/packages/frontend/src/components/ui/button/index.ts b/packages/frontend/src/components/ui/button/index.ts new file mode 100644 index 00000000..8b166a86 --- /dev/null +++ b/packages/frontend/src/components/ui/button/index.ts @@ -0,0 +1 @@ +export * from './Button'; diff --git a/packages/frontend/src/components/ui/Tooltip.tsx b/packages/frontend/src/components/ui/tooltip/Tooltip.tsx similarity index 95% rename from packages/frontend/src/components/ui/Tooltip.tsx rename to packages/frontend/src/components/ui/tooltip/Tooltip.tsx index c59cf959..8972ce02 100644 --- a/packages/frontend/src/components/ui/Tooltip.tsx +++ b/packages/frontend/src/components/ui/tooltip/Tooltip.tsx @@ -1,7 +1,7 @@ import { type ReactNode } from 'react'; import { cn } from '@/utils/cn'; -interface TooltipProps { +export interface TooltipProps { className?: string; children?: ReactNode; } diff --git a/packages/frontend/src/components/ui/index.ts b/packages/frontend/src/components/ui/tooltip/index.ts similarity index 50% rename from packages/frontend/src/components/ui/index.ts rename to packages/frontend/src/components/ui/tooltip/index.ts index 4860d437..7594a8f0 100644 --- a/packages/frontend/src/components/ui/index.ts +++ b/packages/frontend/src/components/ui/tooltip/index.ts @@ -1,2 +1 @@ -export * from './Button'; export * from './Tooltip'; diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index deac6482..bc636627 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -6,7 +6,7 @@ import { StockMetricsPanel, } from '.'; import Plus from '@/assets/plus.svg?react'; -import { Button } from '@/components/ui'; +import { Button } from '@/components/ui/button'; export const StockDetail = () => { return ( @@ -14,8 +14,6 @@ export const StockDetail = () => {

        삼성전자

        +
        + ); +}; + +const meta: Meta = { + title: 'Example/Tooltip', + component: TooltipWrapper, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + + args: { children: 'Tooltip' }, +}; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = { + args: { + children: 'Tooltip', + }, +}; From bb213a057e310e91d2ffa0fe154f8a434538e196 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 15:20:51 +0900 Subject: [PATCH 048/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20storybook?= =?UTF-8?q?=20=EB=B0=B0=ED=8F=AC=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/storybook.yml diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml new file mode 100644 index 00000000..e794138c --- /dev/null +++ b/.github/workflows/storybook.yml @@ -0,0 +1,58 @@ +name: storybook deploy + +on: + push: + branches: ['dev-fe'] + + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + + steps: + - name: Use repository source + uses: actions/checkout@v3 + + - name: Use node.js + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Cache node_modules + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install dependencies + run: yarn ci + if: steps.cache.outputs.cache-hit != 'true' + + - name: Set PUBLIC_URL + run: | + PUBLIC_URL=$(echo $GITHUB_REPOSITORY | sed -r 's/^.+\/(.+)$/\/\1\//') + echo PUBLIC_URL=$PUBLIC_URL > .env + + - name: Build app + run: | + yarn run build + cp ./build/index.html ./build/404.html + + - name: Build storybook + run: | + yarn run build-storybook + mv ./storybook-static ./build/storybook + - name: Deploy to gh-pages branch + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build From ef72fd03ba63c35d986b94dbf92e965fde6fabb9 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 18:34:38 +0900 Subject: [PATCH 049/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20favicon=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/index.html | 2 +- packages/frontend/public/favicon.ico | Bin 0 -> 158820 bytes packages/frontend/public/vite.svg | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 packages/frontend/public/favicon.ico delete mode 100644 packages/frontend/public/vite.svg diff --git a/packages/frontend/index.html b/packages/frontend/index.html index dd168d8e..f352eb24 100644 --- a/packages/frontend/index.html +++ b/packages/frontend/index.html @@ -2,7 +2,7 @@ - + 주춤주춤 diff --git a/packages/frontend/public/favicon.ico b/packages/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..66260fe1fb1735a94a033aa7aff25e0788442b2e GIT binary patch literal 158820 zcmdRW^;=tQvo0+KTC_lM5?YEBC%99fxLc9pE=5uZE~QX3km3pMuEpI+Dee@96nA$x zeZRfGeXjGp@BRbM59?Z2)(=^E=Dz2dxo4h9n3{?#9yTR58X6j&yxcntG&FSfKNs#( z%s)?RrcV<7+@3kh>A9exk<$NlJ(Aa;JN)zTk&A|`BwE=J_12#cPpl=BCD70+VK}#@ z7-)~}ujJoJXn8!^ZE^o>r~_edRc*0M@~X5X>HlX!d32 zYi0SfRa>8i7SopAwGiP*T--+gTr_ccEKYkYy&)X<+QE&-#Fbo z>a71C(7xCbm>N9!BK7o+|8_cDWGd~$1*0dcbfo+GXykU1{JjeA5V8t*io~-m?d2&UM)ak%e-9WA29*#s; zXnXyWHOG=DoVmj5=RMze*m)B_0b8{8rFn}yA<3v7Dxk!!GS`a2Qy_*8Aj~r2URpz;3VtV_7V0Wo=etC7n-<@{41Xc3> zn-=Gf|87)J?qB61_$`+CqbrN(h#P~ffMzsZ8}7d`&X$#LLc zZ|5doTZ|q*p3&Bk-KhMjq@Xkq8cRe%6nt952$`_n8hsZ@Sr(g@+otaQ3Kn0~CJHl3 z0wRzaN$ewp_km?J%N##EaU<1s-|Rf+-D-Axo>Hje0Ek}f=l2O2Ti+^f4-jnSR_|aCHIGtVgd_3X zAAUz(dmv88yxLfkvtg^6fW&GQc1y?4C}j6<3w&E!E6BM`uT@u4K55pYmVd*_@$zpp zf(QKgu2ig&c9#va@3pi|vWu4YwNWcCf8X9b5vup>F(*BH%dv9$I~G-^rQ0r%w40+H z$N~v6Q{mzlTYAH5*xY`-yCSgZR*jooPjXGyO!_8-M96W14zrg)G@N;KHo?`^qxH|0 z@t5n&VEskhf4irW_g}s`pk(v&bqO-*_>G{JT2JY>CY_k*utZ~8nV_AiCTxFsrlB-Z zMQ*0;qoS!F7OEvvwDD|pw`%rUl53}%YoLZ$UgB{23Gc$`(3K-}GyNnJqk2arccv2N z4nHhz=c0J%aYQA-Xf_t_?-4hAvwX$=_^we7;P48{rTPQf*$eD@DA?siL+9{QNWJOD z>ApFa-KdD0;+b%!nlIkp|8fAM$bb0FCYLIC+#~EntMZacA;)h(sbh9)uhfUOj?-|@ zjN;sVfyVde7gjrGwlhD>;a1jbmBKD$`;Gp)<9^xdfkOm|m8_8wZQw_LTQVE>PzjM9YpAx~8xaDFi-)%qIuE%#w{A;yVod4hw#6n%7GM{srZnbW?AEQji zP$>e|TaS)WlcBW)DZ5-P6mU3N%ro(xm5$ANXL`j~%0HePDw?fy`!oh|UzRiPW(mH+ zR=|U(<5nlU2^SgsTwf-XR;!c0K6;Wu;;9tlp$P$9*_^nMvn)t^0c?)@^Q4X3XVOnJ8X9?})^SmZT z4wBinG{Vl^fw^nlBXRwN@bt1rC9r>mpgh1otc{#Plhs6wNcd}1w}1GHulA@UmBIU3UCZ#RHsgkWj;)Wt zooh8;54Z?9=5$eit2*4jZsKhte_20M%vM?HL_z57!oYVfTJ?Q;1dq}_VJ#tVrp9q9 zNVtX_<#V0dLemC8;&(ZF1CgN}j3;o*BXdt^mW{B(L9^UWEMw)}iLTMVf{(!RKe4gf znMCt_-n^_}RM225(NxZh8ji9f{mxG+S962|&Qw6%K3N=U26E^!TIOj!UH80=qt|P{Gf9tP2WxhaHOkz^YIUP> zA$4ZI;}!<8vN8uM=8n0sS`R|&lb%_zz860V0xs2-dF#Of({F$0m-U+$rDz`i!1Y#@ zoo?~G9SIRTT@Xpo8TgQnjL<15U*#$}kbm%O}?|DQdC#L8-g?@w9y5^iKcrrsv|$i9iBqnxdN% zclZZNH;;Pu#iUeQgw*%c1 zywUx5!EhTqhp5tfkc*LZHUMP5xdsD~@MNsYg;1iWc}zf$`c&)tI)kNYde3#I@Q zj=v`X@Bs4une7)xRsOegjkKP2^DStcbSgjfNwlF1E4X1$O@qDTB@f}WV*+n30$hSi zIOra;&C?sU(`&J?jb@g3&6M;?eK61MOrd#KPX8b^70IIv$@78gttgzP=n<5n4#6a~ znwol!=0%jzwwvp`r4@A-*8aAx@JxybSrbAeKka>zm_Ma`sZx@RGf1;|%e`c$|1vC_ zm#auiKLjPM@N#Cjey7a3n(qK-sX?NN_I_U0|6uw=x12F444=j2)MIvFGh(Dbvo3`f zXFb$8dv}Ls1l`|VCx7a`bfNyN?)Y*M=BM@W!DTRs*FOcRUHqOm?rlZLKe>U2X@(`c ztx}-{|7s`OO#5@jkw$Wb;Dz>zS3IB;7-m5B`~;U&XNncpKm-gBgKI|xBMlPp%l{a?Fm0I(zwzgShOOkz`dQ4}c_nXdeC)`&=szw6E)|@_8kX^Yx>LXF*S3c!(e4esKq>=7IW8H_4|E=P zh;`;WUADTZ-Y%E>ZW5g6MriDjCJ3%!cv4e`L9oi*h+Zu~Lv6Q`xOI?=0jWa4t$$KQ z4KffXDEKNW?N_`A{%Py2V~elTf%xjghxq@+3<7?i1rO;Y<+Ft>Jv2FADpj^SuvR@I zV7Km|Boz)A*f%STM{y=mSed-J2Bva2*HbVxaEki7go?V^J91BJ+wz6LhO#%}RmKN3 zew|J1>T=0f1@mHu@@zr zFfr8@FZ76|{YBBmxMxh;fH@JrQ}$jJ)#<@I(PShiu5tH~ox;ls&MDQiwzF1n|F-$@ zCBegGxziBJ`0i}!K?9g9U(X6N4{8C{OO!xCY*nr${K-O%K)iC_Kq;a3%+-q>?ir&Q z`x{NcO-OKK_4*pe{r=KoB#D3dlP{t{ob3Ojrc7r45*a3#s2{{CqYag*1h-oGwL<7w zBHu&F$;xD+=}k;ZpcSSs+6OF3w14HEi#mMXBsC{e4`yT4WGDlwub2MHK)JGRXA0g? zv6x62A;5jhk_kM?WE-IHth$ZSi{b*U^7q?&ZXmVfO|M=yCqQ}@wlTG2AurQ4xs_~C}PDAF;pEQ2DnsM3H{-VR?SZ`Zn)x31qPjk~FvItokUW`Rn zuISmL`I3wXY$rfM4*{WoOX)9O&qf`n1{ygP?P7Og6dkXpngV==m zmvdpI1NBJ8EL6REbfLV4&fLI6qYuD)x@6R)Fgaeu5YalTK2>SJAVVJ+t9iC^oAE9m zLu%|3y(Y0~5v~NE6r8YQ;H|J#fizqx%lFgyp?gHw=xjNNK^a+jq1GfREni~zGYNdM z$x3dSZ)_sOA=(C?(XTx9N{{U09#p~yIm_^|r$h)~SWIASE%R+F*3&bs}9b zA^Fih`&hv{ycp`J3Ay6UuNFh_ylNktIC#7QqStzVSY48mblB2?t|njpov})#+GiY! zX+oCxB15l-`dYNaKT5!)?jHims2pV5p0(;ae4n+{i?G(4m~%3yf*)M=TA3*pNnu)^ z>#G-y)mFUYetKZ1ts1_r&>yTPKOUxP4FX{`9XBs8n;C=1yu(E;gU@+Sxb`piYK)sD z$>yE8AoPAa@VqtgslA^`?(3DmKKjKcXVV- z4t%%N&nhsRc$lpRGu~mw5_hIT+pwPT#M%B_!Z2=9ii$*qpkjcU{~Oakt;B~>kaej! zw~*F+Fd=(gMME>pWT!uCt5$DTg>51mC^#A2*PaPQXHeL^%ZESZQ+jHz{%vawT3#G}W^gHj$H~eZ ztf&6$36w^~1E}&c-+_l?m6@*!WMsa!J9R#ep=oJ!4!OCgeo&nnGK~7r8xwmhZpc3l z-i6%qwg^PZtOUgUn1<~Fj-qsoUw|5GuRoyc-i7i7pN6%ar5*rO_CRM1@0#Dhx&CGc zqsbp>9$z#cUI^2AF&fO6O-d?|08YO1HM*xnnDeGCHwxwQB8q3k0#lCw7s(Vfb}B?5 z)R(ygF#TEkzfN9h4TLsYCYXY{f1QN;V%e2&gK+GIQib&=WiUL{7R%Mj#JH(X4eYyk7K2T+f^WiXw}SHMJH)TXJl-Mq1-mB2?TrvhM-VkEOx8;p-+Mncn(p! zBW8$=bpN!rwk!mZ62;%jG3D4$%kVS*G56bLnN$VJUk%DSq<-7$PU%U=>*W!%7Q-aB z9dflI@lWFtEsOGLeW^S*uUL^RkH-9CsBK|_%|n3-QBIj&_0kRpLt=%y;fV}D6{Abz z+2$oldMiQH7%`rf&^w6ns`{OvR!yqwZG)vyn`Zu!trubU3UL}lwQsvdGR73b9Cz$fmVm)lHOv*n|4)1Dd_bx5vEQ5g&A$6#5c86OafhFyDTZvD}_4SHTDD*Fo*gI5IPo^>Gl}dH%(I=&ZLNT z>v7rSo>-9BH*qdxp*?pK9#LjFbJ@&&YTKe+l40(}lI7bFtf-0F&^)sR04H(ThN* zv=}6^?V_}8$Xu1wUb&yOyiik(-Xh`WGs_|c3VZHluXr`+x6k3Uxtj7W%p|F=cBlZJ z{y;3C_id+$qhHy{@Cm%s@J8Am(8#py3~<+4DGyq>QU6&m!@Auw@?+S4eWC7l&W)u`rXE4#e!^_8jl4Jj~j*0&_S~m4-q` zch1C6L%}t7lM?E_my(BL6N|95iZ!>yjmU+k*<6={q7W}##(v_p!b>>q-}Xd&rsmVV zVO#&pK?3m-LkA(dY@uxK;&)8U1o}8+E}!rClCTL7Yy|Hlejparf4&^-eYlcceP=xt zGkR^j4qn(!J_G(jC-9M=IT+x6T_a8?JW#!xtW~XC;#@Rf)S-k;%B^WxYo?6L%uwt) zoFg7wPw3EJEz=|<`~?yDag|Hi`+Hj+CN)wRy$!OENGIN}@WTwHN(Qd~0rsQ@ebLSpn)k5g41 z0$j!CBYqIh*UG#8y@kjvkG;v?L~bjB*4rN4W^DB8^oe2?nUp=i-;Wc{oU&18j=3m2 zwX0Npe-4M>qo$yPd|0D_wh!65``EE()uC#i81>TECSCmrcCM;8i6?qa4EcX3$^Q?I zZ^AlWtSL@#{|i}dKT|?zrk^mlHM$cU?FTTFli(V7rqV%3m%u{G4FYNe1Jj?jUeVvC zFLga?6mHyDJL-Yhi>Dz=MP1T*f#TXX#0aK1jUQiYhkf#6Z!woiE#g@A@cH*eoVz5d zsHbYX`<|4(7;sfuf6V9s$x2P0)vYtR=*5;!q#!R1pfEQ%^$_fBztsdH$>9ep9?HCt z?Pt1v_d5O;%AU95;x{+`gXSB%7)h%(d0H7ipZ%CDo_f1>1#hLwRGp23=7y0oqUXf) zTk6xScoR$KfGB`@9+#%qF4>Eo3%oCuj@| z3Pqh0ovcb%8}n}?1#Hx2Gw$x5=#wW-4Hv1Uh)0l<#*bYYxP=A1pE#NCJkwfstIc(v z8xvV{?!vn!_P#rtK0v(JJS_V1pCYdVDw7bcdOtgSdn0@-z~ASJ`H_!H`Ydx#D8a|# zb7qa4MCpV?Zq9BnMqaz@BI8?`0SQr}w1^T;_d2NHkGnbBsKZ-57ubOL!S#lpV%@=4 ztWyJP>ovp;k{4+%OrFc}u?XRq<}Jp~VK;2+9zGDk@96Djj%oxole-}FP(-S1(Y1A+ z*L}_XR$h5lPCM`dbOWS?G0J2bOt=e3IY(EK+etk+`p^^|3F37BlNV;S^=BX4xSKYi zqh_DZd!X!;!9IHlG_4FUr@O1AOJmRZQQ?faInfJFWx)yBvSN)fP*_H;YnTLB9U&$! zcl{%YG#%@`Pr6J(&kHnF1(Ir6)Z5qtOhMa;LcVS> ze%JVX!373CZD@SU$6lE^7dby*!$B}T^Vlrk90xGTlADn6^2mjg(Xhew-q=8}45ovM z%-l`*!kFZ3UbIL5`e4Wg_$B*bS3n(efCJpRpV1tL++hpSE-M^AG;Ge5Va zb0$2I8lWfx(SI%@Xd)eY;>C1lyr^DqO4Y$n6ThWd_lD_6y;2}(4*tPu8^bYXGj8UD zK)gFX;DP|P`kX!v9Ojk3=jI(m%H8E}YL%P%KA4GhqN~GKbL*a0hxqA}aT=@3iqLXH zzY{qOJm^WVNMl*C!}nEzYibAM8*6=Iz4CK($In*B=i-+vdm2}B4@*n8=_2QNP=grc z#2HW5Dr8`6uQX8ie4ci^Q=hbqnkFCszoWU`z#bY9z<{xD+#i(@eokgw&<`tQVQYlKcY6RQ-;B_A0=H`FZ5ej-JIS$S>516=Ldbec2y9u0(WU==qUv$3GSM zGPJc|4&~~g>HWD9wexBxyX}Ip|KzeQN_>OhWG1wwZU^Q5ZHA5oLfkd>5>H+*2m4}h zloJ2l($^8Bcxihz-K9~zr9N=wW};y90#$)g1^F$+>eQsK$U9kCoUo(2;$PU~<1>Fr zNqAMW*Ikf<-d)XuwaM3=og=sf&NS`V7~(H8b_J*mym%HlFIN2q!bx{~w|kV~*w#`^K(VOVxX+wPo2D;Ys`j=hxNl$* zyP?IR%h{_rYm6SZ$n>}K)P3?#lOX{E_B5I{W&d!#Z!MG^ceqC zt~BlpwC7smq%@bffXiS=s>UBH*%i1d26EU16Ou?TSasXz(TEj5d;<5TlFGd zb-Lm6WEf83>*KG}s~apqYj?J2gY&YX2S1)Rxvw5xvR^xYFlSRHvc7J2UjQFS(mz)s z{0AJuG^Yz$kGtB&eMl{4^nXduaZ?)m> zT?l~8{$gRxDR1ENY0XK|+uFHd3WRSDE(ZrMMn**n7N;6Dxj;RwcM5z>dpBbNdHYi2 zL%Hgt{|5NxM`+mtSGm5gAk4UND^Jh!_P4*^6`SYnkAu6+sqd~A1EXhkW;QRAc_%oS z#yyta2@~0fefb6tWSDl45G`lTJ4?fv=G1~7Jbn$n?@RijPUA5Q5lVC6n>0V-rqt=j zx0lL5*zUfgp2&R2CEIk5gvYxEnK3aqSU$z1JH2!xMcO*5n#m|Ee)G#;_gua1fLbUg z>3usozidsAD7*-o*vAk(1$eZQof%ZL5W8gnstw6McZ4Tha}1a0WjiSa7d|&%!XT`A zHv6}7p^40EOLXrLE(H`zCsjOVscdh4aj_yYv*Xd8)tIRLlBx?N z)N8agF3VMcM?Vk}(?!;+v?z=|`5}?rC3jqiK`)o(btn9#saX$5pM)FHP~X&mf1OHu zvVI83^+7YJ|1j`5Pj1xGDn@AgQ3V~QOCBJNx;5F82OLfG6dzD6qX?xTPrqVIw_}+6 zy8aEZ`V^&<&?D-pWVWGmb|i~Jom?(>@82r{#m}+)PliOI-tA*}mJI0?>{W0jl1CS) zq!R;&HEa~kCfJTTSoxFRHFyI-93)oHGw`;ybJp@x>J^auhMv(;i7B!WUDBbf19^<} z^3Oe=|9F+}Z|tc$Q#^osD4dKj3-MU2nnSGM0gc`AQLp7NZt^8QfJv}0Nc2+6C6(#*3Hs9~7ZasmMv zcz?^)t@x;k466+)Gg2!IDwTW*7x5854i{JKH$}XQdFEpi(Y}|0sNcdr3M!i-D|?vU z$MCZY`uI`%`)BUQyV|j6rl~{=I`f}s>{Qnq`K@sGYX!SFm*P@!(oHcbCF@oBuu&L^MlG5LbNwz9X*J{$hGWsRdiR%&wM4TpwaV5EPI; z=^RtUq|^X9tWAuZNSkp_p)_&3g2$_mzGSgY8d)u~(=VdNIAGx{3|<(SIJ}bwry~eK z7XXwn_b;{!zI(^9^Owhwqsr+ass3yKo^_T`xNwq9>(&} zDT+f;F!gZB#!rnLQp>%G2Q!6KxIB6t*8}0{X9q_PSarH|f#>GUydwwUYX?r`i31$K zbVObWTyQW>d-$cL4oE&{5AWT{$@Z5$+KX-Pd-71$UJ+i$5Zy>HGbZtBm#FscOrxQk?E=XG~U&?Wo80YhC$UCR|SVCl@Q$ix3u zfq5xj2E86TCI3+#eb#|;wra9oQRX1Wm>DOVc4F-Tnnd)NA7LX@Uyk3ZIM8e{poKWEpvo_HngPH>I@we16kgh( z|2YHo@4ib%bqFW>7YaNq41H>AGwzu8YwpQZKVPSnc`vJoS!_Z02nwBB~mb3Y0MZxxzklv z1RQ^!nY_KFlg?w2&SO*Quo3(#aO_n~L%i|?ca^p-?Eq6Ab|8$>CGxh0#W+J|NSg%j=@;|$``@Y@oZ`&_P^xcc0D2sLfk6*1(K zNrjAoh2Aea7RtDdfJJVBFH03f(kOn z>NX}!YQ19vknoVZEbt0;*Y?p(;#vobwySB;KhK-5-Hwi`cKK@gt6Jn{I)syqyo?ryFJ$tSFv@mEU|6oQpFIs_^|C)We zviJmbO&7ntDspVFfxG7*R3Oz(5)YF7r7f+)X_cW7`zWxjm3ITdF|1`}g^7&ASyp<( z6}Wp|mFRNufnrMP1NuvW>XqtOAM@wSFUGW3g@2U8s^<1MqD0u6US|QHTJK6I6+F?x zX^Mcj#mH-u$DC(5!K;}OQe8IWp9SBF#xZOc^XScmqC)7+e)Buzg`fLh5Ihv2&h5*m zj%Hana#0yZef{?7V_=&beZWRsd%@eAu{AE20B|DWMOoGAm~|k1fF3cFw;KNFI>K7a zyQh(5;3d6-)zg`?L2`!JR6TBdt>^|2H?>j=4<|c`-9^@~-?isN1~b$?#sJv9`4b)0 zG{O~(YU7l`wSUfzselx}sU*8OS!LqX=NG5UoTZnr8*1M1CKV6(-Rph1e(ksuuo5-PP0rSTcb+*47x4AEyR+h-$P zs+$7U4*5}a4~IyhG_O-rp)~)gN}&XW9A#U&-^^2n485w zzCw%M{D6y&kV5J{4D0j^l&!2?=e*6ErVdU{OH+e3PDehw?jHp~@Gy<|-s$RJZ>syD zvA24t^VR!mp!hJ4Nu;^yRv83&NQMm>R^m)oo{d2;BRLOFo5JrsPYEMjn|D0NPA#0} zQONg_snsveT4<|per==~Cn1LyK1JL+Hy?zv$i%%h`P-2q6Pav6Ss}}Hj7M{6FX@Az zamFPtKX%jnWLM*ow~DD@u?6E-;IM`CZ-6L?XUh7$ieuQ0zN5<(ZcnY+7l-gg;LGfFJLXI^1u zK4Vz1RxKMpiq8LGxI17D8#zi%RKH6chZ&Zk)M#uieqQ>~WeoNE_&`r0)hXT4i=RjA z5hZ?F;Nk_jxu5c)N+ECE_{|x5`a=Z^FI|^NQLXOUnT8ZuJCtRk?pYf2m}%Am-6G~4 z?xgD=3gr!y)}P?q`%hLz^m=hQZ+i+&5;Iob57%Q|kPJ^4R$8BtMk|BJep1j*g_1A% zx^0;0u%(p0FdO?sMLu2O<=Y@;6ypaiL$*ZeClBSpGtOMou(^zwGrBH5k8TD|(edtc z#}O)qTtiNUiv&RXfn7>C+%h8kl#oXnN#>>XQD_m?Gk91oErwPmkFO1pzD3ln&_9K@ z7szyvAA~xU=z*dw<;NmVZXWYVRWv~iMe5#A3}if7If`Ie;!on)*H-KEeb3+Xr}3Co zal2#OB##WC@mE1g)JGiY(b_1_ltvp?!%dw`1YCWDjPM$kpURRKX?pMb_{2ud-4u!q zBy(h*r1-cl!T4-L&r zphqu{Da-l|x>1QTcr$X^ShLgxhIzHd6%*xKDoj1H#R5iP=Q zL()=HOablxR4LV&{#ZID=hj@}Vhp@?wVLDxr}n`~-DE4_6fCcM^l=h3olK120)5}G z&H1^e&zPs~y^!mNhewSI*^$Q6{VijYHW$=F!VXAW#r`{thPRHjA<(JSF33|d))DYV zUZQJCq?`6*GkuMTLR&xxg3L<)(no%Ur`5E~<_9M`sK6uTYaGQca;1}=C%FGDCB9$~J=^ec&~@fQulgMp=FN>*U9mftZ-w=~>uymGs-pijonN9l>}$DD zz&VW9+o@%n2rw*s^BCZC-%%>$cX9JaNo?^B?+EBJTD^1&ce4cbUcJczf3HHH6^k)o zeokk%C_9K=4c^v7+QEdA41jWp<1pRZ}zxAo$qXHlMBvU)L=W5mSy%f@l8T-AQz56() z8?-CFK9u9jWa?(jn9P4F^Zydw<`=ep>1Cugzu4!tU?6=KoG0{svbazpuqA(INdmdF zxo7Y&FVg5&xrlQ!TgNx0!55%P<*4F95q&e+EJ&8BN`8FxRB9!ZMgs?4s<W>RrLAkDpX}c!EW4T_DwodR*lwB z0uoFa@&xn<(Uv9e?Xu~gDKzuQ0^cLMbJC zuVn0gx-GJrBhk<;EsEak#Q zBp_Sy$*^(5v0qE7@P`Pd6z*Z@L`QoGF!f8gsegQuU{isxSv3osShUO!hs#y3>7mP9 zu*p?$YJO?rr*rPE7<%1{;ptjXwjqG#r#bIaf6a1&yLeZTh=8})gR!xaKtcP@V6XeWYf3iP=Q z0qF=DRKG)B^@o|NGZLO;t4+TQ*nww<$0z4wn?5zFxLsQZygH@hJ zV8}5|pdK8pQc?=PLgNkqi*^fixA4oPmMb)Ph(>G>OC3fV`;A!7MX$f!mES;&v&`uiG`%Vldy1Z|5HsyQja2|E%z=QSy^pR;Ki%&95d z^Ffp?1=Nm=RVbZn>F*oc4Y$vB=M;Q(9Z*8^A=7M3L)%LpA2$>bAJ(<8D!_WrWGd*e zG^dEG*{3PX@(=Qedi4j;KwJz#4 z8+-$E6_Mz3;TW!1yOmGj@hSirjj7eRk@Yc;pd6}Q;l^2Cf`9x}{^Ohk_j3>nQYjyY? zo|%DF$jD5N7TH${GBQYAZ&MV>LzuNarrw9uLw6Pw!E*z_J%X3*{i5899fsU12d_%g zg{|MOG^eJX8W#MSh^fIe#=1-6hi(7*xbz*IOZ0U1{~a`X1?_(o9xy2`zzid}y-au* zGPkr?uJJU8qZc|`FkeS|J(>Oq6NBOo%s?NjlPZNWxQlt|u7@LM(t zsW1#GBF8MNSFa#KIUJhw8?%^Wtro(zDv&8U2AK|Rr4_L};86c;s%KJxX8g2c_p_DqIGX?+SZrj9Qb$+^0QV~j`nE` z4S;h8VUuA)PHA1#zGDK%J?oe%6%Rp4nUT#ikOhAwb|JO!DBVzXD7!cj#hCvCcvYT zLahg57mBYd>Pf;8+qFJ75J3EN=_qj`ZYSqT;Yc@IwuY+&6pRwlw#zeFI>tRzEt9nCC_kvkY70z zSp^-#`O;Z|v52O}aEbxu$H^0;*OkP-;=(b5N zuNgKc=R?k-wK2%w&O%jZ*9V4jkP-t7i)sD4ho8oc=RP_O*#oBQIVi}A2JG^EGs0Z- zns&_MNd|9wuVpKZzD1s&iLzpn+uZrBozL7@diNRp8uoYR<@iO1tOD&{4t47X*3PLO ziD>pL0+9~MENfAsD`Q6+?%`$M%648KyQ!==i}f=4bpUpxZC8cKv&6_aREeN<2IY!i z?l2Gqb;jMLci(WJA$>NyRm$Lkcp(cvP@_yfUH<{qDEqx}>*mSeU20Ou=Hr zL6udA8d88}xiwf1-21t~zocX3038miP}wUC+zP!sPuTRL6a$nCCBt7ME!}HzH|(zr z#%vYp{jNoe73K!FaxVN_$%$V#n~8GWtGs9F*0r>iTH1aCNnH7>Q-}MXl^$v{505hf z@fhS++v5ZgH~zwxvW)h4ocs`rATCxQmw?#3LY(XzuN}{HZ8t=+-Q>_8f)3*X5t1V` z5;oBXp8Y%+?dKP5;f4LmhTW?JQ#Dm6)Njzma(gur*@L+ChjI`d3EN*jD^-{ep4GIU z8R;Xg%rFHV5;`^a%|lYEL7$y9#-~V z&+8?5xuQYa1n?KB6bj)G{cuHh%g5)qd!b1Qd8XeDaGRD7IjpMBOH3Vif>nL^%8=%4 zbq9fl`5`xf_VigF#;W-C9ID_5(qxc4Tj~2?!DD=K?zF(68?cO^BBQAgoT(Gz2-5TZ zE~oF4^&Wz>mqonpqxiI7pW8USYDGDyXP$+7n$*1SE*+78i}2rH1ork&b_c4w-DujY zofIlFF7Jm&g1C7y5{kOXE0QVf3GE?f8ta1$>o?mhHS+oTl@^4Ql1ps-uNZP_*Dz-N z;qb%#Z&B&w%%o*;R`cd|nk4PqXmA8fc7;+u``~;;Wo$97gS^MNxCC$9?G?#)otC)* zz@*BU%6lo!oqBP4C|Otb#64?{zc}kY16x0#OTqqho+;3nv$Ya)G8ffNSgIN;S8mh& zOT9kMJN_-&e>TMh-;MY$MY0@U&JXhYa>CTPN15V=@IQHL{HSoYT>7@L+j;le^ue>< z>}!Dy)k{>8=};+>323qITg)YD?TB^lUEYtHVxwvcW?0NW$1>n&mI?>V2b8au2q+TDRVDt1Nwg`BJxI^a-g3dQ38+*1XZ+g zz?q^Y(TTGcbsa+C>8x1?K9AY*jQ8I)9ks}Q_2x%I>F4i+$!=Z;V;vqm+NFsL3)m_d z19J`R>Z)a};UIp&0DZ7j;T|L?=~$d!@xR9J=M-+mBKt} zVhfyZJM5OWS-m$km|;*VEX*^Aa1KX+Pv(q^{aS#6qbbPqDVR!9KYw!$ z-=Qd!Hm&BWByKXUX&R1gNZb1!h`(4*B5j4NgyV{p+V9y|Um_cf^q?U~M<*+sG8V1o zY^G{a9#nIbkTCLc{z`xl?Sb1OEWHUG23>S-16R}uf89{8JYxxs@WYe zr&SW?`?3}x6KSJtLPOZL;^}SWl}GYY?*ODyd!&WGO9D_+TOu`&%nWXc=9`2HHSVff zsu!aC##)0%n%~QA3gCFzG~t%zd@FUdzp}UuAX%>=A z#8nAqGGDC{CK*P^_O=9}5|;NTsdvTo_EZH#`VwgwZxtYMsk~U7J^BKLBz;T zzCm9i}I{92#9ok-A%g8MW11MZ)ZQ;MW$G>CMXPq0C2>;0h9j(`B# z1#4O2+V}V0D70H}^tOWF26Jll87q}j%(2>>L4_4ta` zS3YyFbQJ$2e04tS@Ni5g#KJKFnBIIPkDfUH2WQmoi-@^jeB{4As}UkSMYx^D>%TP+071l+kq3 z!b>Xr<7!=Cj{^gHf_2)R{_N(62si3JI*8~1_#Bt-WL#3{=u>~`&!J0L@qnYfQcBjF z+&{Ibee3PQ9BK9V(NJAV;wJvwy=wk-5x9#}!y6_Pd+m;%%k`Mr$FJvCMn9}s)0Q}G zrDbeITr6&c_E?n4sST#`vhLEjUN-grmNP_zb)2<`OdV&62RkFfiLKxW&zw8Qw*SM{ zdxo?9zj5DfDWzuZ5woRMMC@2?6}2g)h)wJ*_9%+hh^m#Sy|*fA?-45Y-Xk?*RMlR$ z>%sNl`u*>Rd7RJpIL`AuUMJQWaNz%k(s0FqrUX3oD+?@*oKy+lN#Qrhk;^Qx8RBQo z9HRR8uZ6i-I6)mPp#O26LRHYN=6oOD7stheW7lP(IXIK7uO zyk55-lw1+_tD;!;lQGKt-~)j>c0~ig8nCYiSav-*gk*SknnPIpyP*IZ?|A>2KWu~l z-uyX;>7pIIAg-x32xB;1JIxzqFDE7n`!&p^RlIpwkD}2S6Pd< zYMr9y-s}~98YlocL;i?5pM7wr<}UROU+1FyQC0uS`w9bMpkqOfo4c7PP>i$lSSjY! z{TLMrEiS<~JPE8h=`iQoE;#AdISdHiFK`EIx^FZ-*u4lR@vv`L{IfkdF``jwHSJ$j z%ZC*P?=p%Vdf4JPe$F=lrXkLU5|kI=4!mPW&aSf^cW(IF{&qA}&M1@R}kzQqO|oEQxjm^{)WXezFl6bFL`XpD$%R^qjdlwIAyyaf)Xw!|MQ)7S zPW0*5jm;D8%<;ors^o2-4ud-h$rEVj)`({xOwk@V=y%|=z-zgo^rWhZX%TI|0>oe~ z<7C84iSR%CCuf_2LMX}?@~3u*rblhR-gw2H5YJY<&0e_U?NPw|tz$8_Dfe%PG@0|l z6|hD6SyP;qmG14PSWLG0%L3W(;HH6n3-+EOMGtqWrq9{4vfv-Vmq?uJj+aWJ;ym#( z_VL?Yt{G!e2IuOTyoJJt0nQA<+%%~PX%UIrs+<{@v7e~np(KISSt9=SLJJqAY$DLTats40AHn z=eAba9Lks6e!Qt2@v|@z8jg6c^0oF!hJXG?m8FeC&LbS6Qa7OsB;`b(;x?RQI^c$h zu1!ClcQ|_Sg8_I=u>sS(A4`i|rY9j7rY;iQx;F29s(76<>HXx6H8P&}P+8hA)4U)Q zy`K)(%|ZMAGRs5R?Xl(^SU4evj>dXpAwk!@tUL9NEOw?qX@m$TUHU7MUIV_*wtoV> z3O{=Fte?;^ph;r1sDe%3MZQgC>H%jlvil;?-^7JyA_GvfMnhFxdY_i%huhm=Rr9nkH z92$zKSz@l~%d~Bc_f6Uu3BLLd_^v`s&Tk2L%kVGj;+~20PoF-2Ml;D%ZT(SHNOP`k zZs0p_W}ImpvUa`_>F)AQws5(ke@ipXTvp3fJ>0XEb))`AwyH_baxq z{;pGJIOohXsY%bwJmFTOh#J=0sM*@@!Mr38itIXN=WE=V#c(XM!pwG$p$(}Fs39^7 zGh{ppPd_jG@$rO5t^GRjU4-WAMOWuTg$US*<6O`XzlB-Xz0LKbVh-ViHALzr8g7ko zNTr!`89{uyEBMqbjz@*vM91SkBT>IA^N-1OstY67nHyA;E;a@SvqW96@jd;{{O1zY|N6)8b3Z8!x0 ztDjdjLcayER61blUxtWoT75tqHGY45XDzUt^ob>o*WQMTu{Zn668dh2aN8_S`Mj$B zYHDZ1XM9yh3TB>m5GI8rCn(8w1)LRH?ouV_=y+yuPwV(!TowZ{7o?sU zW>BoJJmZ1p$2ib}rwm4uo>lP@M9TL3FkO8Gz9f{LFKDPNbE^X9Xngy1nx;}GT(u!v z!jZdH<5tHQ>FH-y=yJQcq2p9t` zvWRF7v}i{9)~!+x4DS92eU+xAIAoo|8Yg^u1^Hg87w`L~9Ku!X`+Zk0T#ajPP-$I_ zfB0}o@&&4gR8Tt~$1Oy7Q-yv$ekOt}6%f=R@T6wwrIvSYQQX^Jg&FHunii~D+JFb+v-S|#RuSmwQW(d7yjbniaRv${uV6fo= zwcWLzqVF=9BEsAN&7`_GnN)Cpsov;;hOGnA{ICoWk3139dG&@WEDFqR zKhj54u#5%ist4y>GY4_JLwwyb6Z-S- zBSX0t3~gNCgd~OUqe>B)?72f8tqmOh{T3x-93AF6{WX#BFy?P>a<2n38@}Xhb(?dc zbNnKdK1ptEW#OFGd|gjry%Fb4Jd*0bm0%1@ z!oRcpq2Ep{x6_6D_pz&#dlbo+(VFiYT@%4oB6 z-8mtD`_>^9P>pN1?YHhmYkzeyeMmnEmQ$*!67wquF;~{D=KQy#d;JkO17~-$EJ-Y; z!Z8#@M22^Dh5h)`Yv|c zo|2BarAo`Limsi;;*6gaMZeoAIP@|K>&<35;F_+8%$Ui-N}?(6yDdI5GuzO<{E9r$ zM4{5<52m~10#(qYf|Pi>d3mD6q&ogs3V4f(N0E$AoCVbMJv)rcE>ws&vYxE*%cypa zXUWLlypf52tC`4o@zFD+1yrNVt=skt$&NOJ^(}T&#zwdQ&+AcB;-1~e`;}NQ#a<1b zFLPQ^i%R+=8qYu{Y%MDQgZj#2r#d~>XJdK7h69NARKo&h&_Ab{AVac1gT01u2oPnS zI z1l?I_bKymGCGmqR?2}=kL=e7&DYA-uz}w^|>afLX#$(8k(l!5YKk!Uzh~#=1L$RmU zh6goJ2e<!BvkfRzp<_(F|!G=ej?uZTlhcUj(lqv|p3Nj0>*_nVP=*|r_r#>?QS3`@Nj2j=G6cR>OsLhf6} zKh@5@h9N;1{tGHWB^b&$>EdEr)_GY&ZOTKiIS(7>+@ga$kI#M z6s{fYyCFGNvk-T>gg5@gMj@8jVHfF3-tG!I(ia#%B=qYClszbDeEY1|n;Mt~Y*l4n zN*Voxj85bRegvF7Za8y7`=7RCel2je{W9m)Gs}(h*)?}PD1F=HO)?g;?|b#oUXyg% zl#3ug#;tm4CF*!$AAgV0vgqGKF{Z1Q!jR9kFJl>nW-%g{){R5>Bx_&|3AHYjOWvIiefDlQB@?*O2cl?1sTt@ z!pgPqKsfrBPu<(39?9Rm`50Zcg4#0aKk-69>j`v5+d0*DPVGxEoz8Guki(4C7XvCY zXwCQQr?>BhqdxB}R{mSknE%QQ?d_@eT=lMfjjBS{J|>2HOJL(-JTQ!;L%IdKEQ&(y z6c!@S^conK86ww~TzU2s; zjGz+4KnftFw62ENEJCGX-EUJfKn@k(&(&}cin>1~A)4hxBy{5@!!35*xSh+={}u$4Df0LoifTQ3wG+q9s&svnd=OxS7BDK#xuV#~@eB#E%OO+!I_fjN zcwdnU&yEz=z+%K1)?45of{^q3NSVfQtv0_VG(XgSKgV+c`J}yRq{hNaH@A zfO}m|JD`wrxK9Cr@ajkz56oQ%@mz_#S#at6x%xvb`}8Nx_UyS;{};i?_J5d<>l80{ z-d2q3evG&zv~h0uUFX1E6W?JT0b}klORm0t>jn($Ol62(H7{4YCspA(gYCb*Om_R+ z`GBUI!8s#3BVTXb!MV~+z8Ya8BG5xq{A1&Wsel;eSwJD7gQGUiP83bK$?AY*kl>+d zvg7T#ce>qug}z2kxF7uBDG>nz#ZUC~{PfjfJCg$`{mbxROF0Ncb(<3q)*w|%DFj@ zS%+u6nsa`3i+-!^XU{gx=Qpp`t1F*z{%m$8^QhCJg$Wj5XqYkqk#$(Jm4hY5C=wj_ zQ*%#kS9c!95=07qU}*Ui5#|>LZn3sihJx&g4IA#;KDdZ@BmA8KGYjy(RYUhg_sMKG zR}YUKu0;z@9G+qO@*VZK0pg(3+!+%XJwut3`Cyz3p(#js^;I;ba5cloQL}^SaqeVY z!cPJ7awwHB@yNmXp?8j~iY|A=YHeXg7B*7$4-lX!>z9wH47;38uUo9Zk_Z2z0uU

        =A3?O;<0a9+VH-CNMmL-s>$UF-&*4-L-=(Gg_GK(9_qEuLhnf<6-?L zZsH-a3GeE!9!j{RPKYLXOw!QZ7Pq$QXp9N2q_kdMFHg)THJ@%&B`c=7GnSC zJ%3A%p+?5Ij*675SA?s15@&kDpfd_li}GiWp1mWUyt!8)HxN~PIWdtN!WGI_XjEZe z@HOC@n*Eem_8{>6Zl|87{+i@3BHrQBr*8?V4C0GG%>*{IGG%|_4Qyb%qSs*u-;!|O zFBB~3x%ZP5==dvy*WO!j%*!}3k9U^4MpgJO446PQQD+BB0nv!%Hq=H*TfG;a6JbOj z-)NdA>`^n=j;sEw-^ZILM#nm5$3pwBglt|ng!i02e|ftJd6PDxDTG@3r@6atxDVk$ zN@p?%Ih*F{%`8nAo5y~(Yzog0M}ooW;L~x*3fd$ZRdR2v=|8uWeo+1*{a{lswd;0PFjxt#8NAN~$vA4PhBxoeiEsO? z_f(EnRlg!Uk(qL(IiM2;AsGJX9@af{WBSHmrcRq@SmOPG9#I*Pelalct$66}?+qsx z?;&CB#GfN24}Z_=a~r%GcrbBTrV}?U1mNPr=1hO(TPpGGj)D3xD~q&Vl^<-M<#LOS zo!oC=X++*%&BFSV1&T3=+Sc%v#lBojH1L3z<#)e##&Huga2Fi2^DZg@g~Z?iktzT) zw!r3TmKIIvjKNa9nxfsSaq{W#QVr=t;=onQgCnIQpPpmZb3>Mc;FIm!bo9{I;D@68 zW8#kZsh#fJc0-Cgu9n@GyR+B?)Yb<#yn(m?X*qI_qm(gW5yk0aw&XT(v<~a&B9hg4JM((&g}19c*p$pWQfX6*H*7} z+#6q?2$Gq~L8B$YyD&Enq88*A9%)mAm)|Z#(-;IBpVo4z9|g)=ZS;eHgww|S zuL{zI2lcLfb_x_ww~Qw<;}5ho&av^gyA-!Mc9=%rI0sQDPbQ#<-p<9q&1^?h$S@`HgR!LqxI zuTn8kg*c+K<7`WQVCs{y<$73rJFY?la`7G@D0>O_go1Ja)}ZK?)aP2WBZh#u>}lxr zUn$^}+oZCT=hbSU?(EGuX-%MTm%kJAdL$^oh2v_x99F~jPbw{t-k7ikj)&LX{*j%Y zRxN;@CA;z6q=qg2;f=o3z=cBNN?LVm2AWD!n)2i>=(O{FG5Pjzu<0O(BaZd9E%@(G z>0Ztym#wXbN;^jr1pgk>__$VKqJ*WOl|_qTk|pP-^8MUKJr(xnw79EKeWCw-ciq*V z1RUX+ZzEz#`W>sIDVQdi-rZw&aO1ep%rJ7OVY+AY;?+r&ronh8>YY{Ztkq+NOlqF0 z2&!G~Sk-r?c05H}TRlil42_?>)d$~-fNlnslX$^Kgq!npNR!@ROY!blHD-8 z4dP{!4_nCrDzv;rZIy-X_!d3M2+Jom+YPScs8?}A_Z4OOOxX!fJ+DCx3}d3U0cG)3 zJwPYkRpiH63H8TN_#Nr&nwc^C@_J$J7!tI}HTHes3OfloA^Y+(TH1dmYkucasOy~h0B8z0}?=$LQ>2PQT zEszanebf2SR`8e`%hBC^KLu^hF%o2wF!{_rC9{S_$KHvx+Vk<|`e-iesXtod*Gz>` zod$Z-G%x0FZ_0DaX1G+tPp5gss=Bz1k<-pSf#=yK51;y}$7p7#P9OYGB-jHv!+Zo2 ziuykK?JjN5iW*QNhe9a*G~3Q)cEsxzyy_68h&%|BOVh?6#Kiaf83c$_8XmVz01XM@ zQCSA8N?v4(Hs>o)DUQpfbFi0jS+bzJV2+FWXQJ0%3<1N7*6L(ZnHdJc_s{&3=!w(i zM<++&QD|#|w98S%ea6hTYXGC>#f4T~|6Qcl9oe7tf6V=89GTmBCT{sk53so+g^LNz z`sBs&Wk7#sAqwYCrHJeOCFrqMOVFD;1$3O?`}; zF(aKJ@@w2W=fBqQ=OdlV-{@0SVP;TJTF`@(wvbVyqqEZB^G)%)2ygK5?F8TIoX7BD zMB9!34Vqi_T=_b5@vMb4=xH2I+__0Mu4}M2N4g+tE+uCP`be?VpzxA4@$B+Ncva5m z=={;yW$;PUZ5q06@zCiG>ir)`IcmE|9{WIBbzqQ?f#1^Kc^bXaL*+o%+oAErrpHzU z+#6o(1FekTW$n!$9pR~{lJm6Z4KvcE13Rc&A)CcW+9fu+O3taxNxH$_u-C9l+ymKj+rFQO`zK?wqo1vN`;h}_T21C6$(zr`>6vxaJF(Aj? zobV0Ta2Ql6MvY5OA9fEmn1k8m+5DonCXI2DV@di!H^|9ltw(O>;0Gy|fubPcin&l; zvX->?ILjf5rttL=+s-M!Z}V>odIew{rN|<&;qh8z+6SV}ET1LB6QNI$f_XlF-Bdjt zUvF;HXJ_C$*j!wGMlsOmk(>%UOl_aFhv{l=-drl@*1-K;vezm1!x~s&Ksh8>WZ}rS zS^hTU>Y|d{$V7gBBflS~vLT;v!F<3^k?K@Er$Punk0Aw1v|0|0xb03h%{r z_e=^>947$I3J5-0GTYZh@*#{|H?L^95sj*B~7+*H|Ud^yx^`{)wJL87rhOigq zU4B`%-K6TD#o6b09*Tg(mHH6nh1CJ3EXyZ99d7kmDg&|4nErpISETAQH#Arave|`t z)7AW*;g?KA(xE5}h$uJzPEWeK?YDii?LcRor_+>lJX}72-5N+-RawtLjxF;`^{96KUkz5tMT5m~}`cwr|E;Hm?TNt3;fb25#Jb_|V6!l7uileeS; z;n3N;Ur0{U-tNsrcZoww1XaDP8v$b~{*Y&DO*(J(?H1V>O8~A(ZsIURsn4lUmt*ja zQzDC+QZ3V7Hp#{o$ofoGLe9av`3o2YHRTe5t46`K*FIU;grAuH_ykTZ)#D#`JCDkT zWIT?ro^>zL{QmDxmz!MFG>&c{xCny$M6$=!{kP^lK_5s}c$g7}fpAU-dAiWVsfCqgSmvlT7abDTT}qmw~$w+om@xo;n3y zn}YTUT=Vlcsrd%l-+EJNy_(cOORj+#Qv0p?Xn_%nhwt2zus36$=^8`aI;=P7Q&R>6 zo3+qMd_@Qq!%}R3>o$&)K&V7pj;9*OMla{pruxKUOEv0Z_=jZPppi%<{X$ox9kXGh ztyt}42pSHZzx;~0Caup57hzF6Tgo%LvNwBVnN~S>Uy%q7djLIHRVACo+sBz)&NWTQ zwnx$MAw#e1ZqVXEuA9S~hx6jsFQ)w);K#_4K7Vb&Hi?EW`RH0GX|aLjq5e~)>&J8?>Uy~` z3^xC+$$k}y)<2NiP%F)tm00K)qnqsv#(v0g%-u=?;MGmBgrv6#|x&f|^ z*Y=<7iN@tI2mV%uwBB@jzytPBg*!fHIS*$Lh~dxh!q|K$^^vuWe$s zwd>{1Vle?NpHB%4zrmnoU0+Kq?gPBg)#k!k&Tlbl)lB-I8fh@^s}!TviSU>U-xeH$ z@W6)jT@x#T=F|C8haKOuQIYInn8O%h&C$d35zz5*0^is$i_aVMQvN`i>z z)iMtXVsYD`+*E_>v;z(L(ED&nY-~{YX$^5*{@{EuV$h~F>+#1@sr`C+w5iWD9Afeb z0^&>7x;2YUEI#;6jq9kVYV#r>YoawAAaA~05h1(~bXZGs!^kaEkBmM5ty~4koFoGA zE1g@<#Q>_Vc#iHZoS^SPs0*TLIo{k{)~4MzfZ<>Pp$N*Q@sXbBW{*;`-0M8I;?x6B z3wk%F5IT|2arxxWxe!RVoto7fUuaMXBl!}olS0+y!3{+_o65(mcu3hw!vic3J`1sD zXU`xe0C)(0ra_vPurV(Y-yuaoq%M zJ20rsPP5b-r#vE~9hx49G|7={r->9s-?8S0d_4ertOjfO=xgT{) zShW;`5^)L$MBrKe0c9=fc z`ED_|qtDm$c@hGL7v;v?2543O4T_|dJKPq*+{6r74#%OjpFts?~HLo zgKETG8|-u1NW{19!3$Wv5Nnj5J{OAXC=rQ;aBoP~m_r@QndBnXvcVEN>v_;+B9wKC z@kBeRWE4)6JuLPp(Jibb%L-Y{gFV;%#liu|P@iC92X_&Y6U%03lHY-|oPY7N*8T$n zDjQ>X7hIMV=Rz)7?`W2+S7%-TR^K!vG6)1J08%W?(=+BK3jZ;)Mfze%j#pO9%q5rG zL~1YKD96z%6rfd*$uxJ zTj*Md5S2M$uUoyh@g=O}wA!6$(%6loXfnX>(BV1{)xXpID6;JH>st@#1ZOAQH)`=< z#PnP=;%6`Vf?^+T9K9W$I`7L-+mx_yEw*q1O3y?)q!=HZ$$X%FyjBB#K0a$~+~|st zTDqik!k*E!9cjbaT-QGPZy0h>{Qh6l-E9#LNqQ2r#*m()tYlk(lQ>Oknfyu5R3(PC z!x|=KPq^*EE^8`dt=Y7n=bsAr7BSbZY5tWcOaY%Vd5ZNdqirFhr0!Idih@2dm1Hx{bxISAVZR8_Hc9f~CgJoLy5pJ!f@mfphe>dB0lx^?4xGtXr_h`;e&N=kZ# z(85@duA)zXAPXmG4`$!ioGK@c5t(|!)uu_hOE@hlT}ezl0}>AVD`try?ct?Ik$KHq za1g6$ejvc?z{O32V3+F$wWez_Ulzs0=4QE{2~#W(hA205i2{t6QlRtb2-bD zvoC4!f0nYz$mN#5vi=K@_iUa&;OyP(ArBrxU{IC!;jv4Yd_n^zD#PMb%NBEjXg|2E@3%VRHFPgFUa&yOcrj>-{GO*tx-@spOZp`O-bU8I zUxyGAx5IGHfaYQIhu7BJf!;ahJA@`G!!lt6UuwO`{uXiISrfDUbg+wj3Ln&wgn__U%E#xreDGmWB6dImD)Jy z1#_%*C(jfq-oq5WjDglS;_~qHHy&RmSEHYEB&0ybIrZDiZDjt`!b zQ+ZB@qZxN3x0qj(`Yp<69fX_#I!X0zmW+D9RaU=NT7eDy_NmCD+%MZ;mgsP7i2YZd z*q35}(}*vVbR+<1+p0 zCa^@OBz?Hg!`{VgHW;t;rF42MlXI`*TP4R}e{P&yIkv9tH1O^{?P&lAwIcfz6pa-; z7wGBe{V*>^J?#E^Sc`+xmdUdOW;94v+Jbf-Lu603s31WrGA`qXIn(J8IAjdgNr9mcx&#iJ`k6 z!!nI3QR=qEAA#mmR2x62>&TBxhyXjhnh$LhxHg&^JAvO(rM?UOd*SwD-hwn~M<#CZ zG>Wl^8hhViCe;iYG3ruUUDQ^&tUO>K+?SGM)*QoJPrl{_*W31MNkn*He&xagE=Bbn zi0!R_8Wn(Eu^?I)_H&+1&p zvmW$x!hsR|9s~BvD}m>%*{0X?(gnPeYoG8@))qOeEN8|Li4C(n5sm1KT1{=9mS>QSi&P^d~ke&Pa$DW-lOJ~-tI z6W%ON3WW;@C5~&%=hW{L8Y|&l4-k52DLuGEBjs-zhJy{zgseeoXndM<&U%aUqHo%0 z#O@qzdjxNI6V3EE5nIrow;&rImJ}1uR>VO7TFO)UNOz3-or-IMu;H`NIP4)#TZy@2 z-T8j?kB9rZQte+z+yQJL9(CZ%ovhv{8%Nby&w4di)yw|kwo3hGM!ioUbr!XpCV55!cq8=ONEJ#baDmmYU&Y9 zb(!Evrn)gNn#?ukdP#v)&0{f@ddfF!-^l6fN}HmSp`O6Wb;-S_V_X6M=;X4nbZxIH z-pV!ac|i_N0Jh?L;>7AC%gYqUB8;xVma!_F7F?fyI=-O%lRJMf_J7348%$G0lOg)F z^~kRg;ajwckAysRLPZq6OAMa;P-`)@r!taRpQ*IPjWgjO9TTWqs<6~zFL0#b5EcBO zY7)LQK+Oo`>W!1zd2`oc$b{~hB^Rn(^^$&#p0O27FT^L1xQAUk3K%$^~nU8Z|1zS__p3`!GXHe#Ki^+6?d-e14Yw5<;N>p+puIh~D zUHu1z-?AdNYth@Ms=AS@`IkW|Xk5OU0UBie-o|4ULHVmj7#sTWg5L7QAnObNh>m*C zvZv~Ut2Wxk6t#{-3brPUyNVIl%zR;iSsmmZx_XHEuK`uEkHiJ5ctfh0k{@`0qSQ_W zyikkCm9bhMv4*(oUxdq* z*l&V`nANL>?vFJ)5?a5zJVrm5iv&{-__M=&i&I2I<|B%XMWHsKI5n9@vXsU4dJ$;{ z_YrbqF2aJ|>Fe@lgDz~o<^!Kl@im0Fvv z`hfd(ztcYQiD}1N^p*2}+HTT5@nyb;M@@IBxnU_8oSB^-wIXY?fKQn!${+dKvz;^I z7Qx*=={%8t_&t71g64ZN>47}>^|U_mwt|5~3VjIFj^}r$wVamcF}$z(k`Y$iJw$?MvouOd*x~BPT5#mZkWX_BHxvR9rwCiQ3rnBg zqge1Tpq+pk%X{>_R z`@>(%uZ8|)?2r)gmX&EM1-5+p83uc1weR(*MthWP(&@0HUV_EMGXvEg!`PeDms<4& z9M&z&;VQ!^pA~x8%EdDHy#9LC#xr2U`oct%dI$P&WGHU}!F7^3E>EJ)uosM;ub4dS zqZ!!p^I2$rO#%xt9xm7NACsFv$J*E7j)TsDHNh8OeM05`ryxQ`X~m%agms_><|H=K z;a1i^T!L(1B2=yZ+MxFfSf#0hxmVziT6HM-vw3$4XGp=*tfmj*(&sGK_W=>Ay@F|t zR!a|cNSf17QzMO$_xSMhpp*IZN0+ljO#^n+P4SDb{yVjbgKSJ1u|&_nDW%8gVRS8k zP*CSXBOi|qKI*{-zV`{W!1N}^bO*!d?uxgwbp1UW%d+Ro5ch({h}U^x7*-nz;rdSs zTja9)FYb&3CRUn#@=S%fdvpu~;~M!83D$t&CQs>Yq@`!t;>-D@_f4T_%G}H8h4C8oILMVg&Af3I~wdYslCsblA4RgJ{n&rNgA+EZbsw{Oap z8ARlTmT<)2-|~H~(-+0dCofBX;!!g@m~VLM+~SCx?4vu!^78_Hr={NbyHCXPd0vf{ z*KOBd4Ee*Mb@3N1p;J5`_%b37pPAb|0Pp0w=2}LW*?znjPd~jev-Rtd`YPRaZ#yMySt$!<+bv~|ziCr*W9ea<;s-SA!^eya&RP8vdY?Z!* z@Ulmwb(VRtJ&|AeUP=pISI3Bop=7Nv(l9-V9^!&m+0G=Ij2i9Dt_m9;_*_`6f?1F1 zzZ^!tFaX^#rjz3#;7>FAQp=awh|J3;4NqmRcOOH@|f)bwj6AWAKL~_XqH&1=rr4j<%Mp$JK*jHEb^lrXJ6bs?eAr zHPE~(7E_v4L6N>KI=DJsW^rq$*WbD%oO%hT-KDA@&Hr@%SQgR`V#%8dDj7WR>eA}o z_bhsxxYjxax^iO4Idz+-uao8GJ1RMoDmzw%0x)P*UzV<@mN7n)o1lVTkAnr7Is2`M0pCWguBk)X%JM#_P zhIa6v9X@svAmun+-hU=xW07OW*bXz{+Na=g@WVJ45q`Yvhr{cE<9EsON^FWtmY)oK z!rQI=i%@ktJPFDy7joi!$gx8|ZF)@$=pw;NEs(tnt9hpWuaX3={c6ELpJrL`#`(LH zWps#5os7L^R1o##=g%9b*3`GJ{cTB6{&$Wc+~SG17$WkN@wgA9Rzi&2u6eoF`oJ)~ zi*8g6&&$};mDQkn({N57hUnd|zG3mtzGR(fRa?%gI&jatL(%@vNli6MhibJ#NBemu zrLCDyo^~5BW``z*<-w`nRpUpsd+4f2?`^g2_lj#D5~VeC6^rTfTz!8vA6_t|@H&Ml zqv)!$Q#rnbx)=V-{LRla_Uywq)CHbBLjKrr1X#HuR_WfvM!fP3im@hlTi>WjdlIqn z>Sa?q(6OwePkO4rZ0LJ2HDaJW%~pp4z;LOj!YDUtl8Fm0>fFI2!-9KIDy^Ajq4gBf zN`h7e>t2A{^@Pk(w*fu((a(qXknzP~cB_6=gD*Xm^8Pf&-**&y9@cLiI0X63n-=^# z>|pBfYC5CDGPGgoYNlSc>p2)XA7R(?lM-^^Wy?&Uxb1DR+fc;nI-3Np;qz$vOqnXx zM75WDylD2m@w>Rq@9WM{!{Mqh{TF{ln8#_Q6x;Dv>iPqYu7|l`@9Afs;*7pWrhMl6 zK5tm<7WQ@B-r9TO@Z8nPVqD)@lMgQzQ=K1=9jJ-3{QGAC7$g_ZtKkEbTXNyA`V)7ODO+T@ z4631Y?GnbQq=OHid9Hww+4vQq^ZwfA0Pd?ZR&7*_H&m%Yv+ZP*oO-UKi;P^n+)u0I zgB~E$vGbVln_HFWdoeIh5c|wDS?povH1)OFvF85hVHJ0_)BOZ#Vns|x{kY>3h52y< zPj%^_No`1mdl`@kMsL1u2HnnY6xaqqpLgV)?b0IOSGX)JO;7`Kj)@%1pDWsGdL&*X z#Cf^UXYU>O1e7Dfgh;gv9%4+W;Fj;@i3Z7+Gig-&6^_0>9vZL0|0NNoC;VvC#i?LY z`qP>Z*ehdt`=n$G&##*Q(gs?Y521NlG9>aD7S(o!PYFmWew z=KT%6q@k5=Jn`;uPT}8r%f(L`gECbDm-Z~0&=p7ROG;pj?U7GS*QJYE_h#OG3==ic&2_X|v))+(9V$`#L6M*^F9 zp0;fr5yF>#7sB*F#It))ssr$U$33um(*O_xHxM(tqse{HtkV(ryzxhU@<;Y>YSiB| zDXU8n#g#f`A5GAE4On1__+h0h`TY0KyeS^piLmZDRzpmTE)ioE+wWgk&$hKs;3$vH zyPT^-MI#h#8gP0H0UF(%_jw{sNDh3#`CODWskr6abM1055(q&h5*XmtXe&MFPC06lMM?YEjEc`G z66Kk(f!)^J^=&-feIGIe@mI{BwS-tp_oRMokGa)FptW%MQp4e;M{bjzpac1U%LTVm0MkP$@)A9LX z$ATE6=WwALn6d)Y9K^K46OMr--_rD z*c0BrviI>sf)k}9FSp(ecwTKOJ+};8n!Q^$UB#?vm0a5bJrnR-td(Bx1vm>>GuKUQ z4Uw{UEm`$asSPq){kF*k9BK3TuX8l+vv8%(O|Y6zg9sUvHEE1vm=~0W&Gk7#w+n@o zKpwruaiU}ek<>#{>(kZhP29`zsF=KZ_|I?0B4rSc&wF2cW3crkcSxYPBM&a-4s#ey zyr_P1a;~-#jD9$h0VE4)dhmnkD;A6myZIa>{ixT|Qm|n$mSp@Swqb(RMt?Mpw+Cn3 zkhar$)vF|1g#C=xN{3tSQu0O>OvD4xiJiM{J4OZD&YXkDt1Mp==V5#+fm zm0Gr2>4)q$T7AF2Mgu1f$BqQE_RjsoPV1`@=r?`v=bnQ45k?bVs{RRyuJ`imt3b(x z8{zdR1tK{?`_rlW_S1Ws&SP$>uXN4E4|=`+0shMDpcx#D{&4V1hSE2wcCaPAw+uhd z5OqDo;Dx)T%cUTWeZ{-ta+5bkkFS?=k7t{TjLEJ54@0jB|0}N3?hLM;Zn{Yf-5ofx zd-0H`^NID^OyEbHvWOb&fya!Hcrd?cw$7_NMRnq@mhSY;<}kU)Qn*e_)(JaQ&C6OK zqDj^MBU9e(Z^_N#d}ARJ(#?-i$7~qiGur^>-A$_=YJ}wm^>{3UC6tSQ77(jA_tS=- z{a>BL?bWL$T{lECy7jtDvYi<=Jcghb=NyXpc48*w)z%4J0b4{|2((h-tpsrh(^WtE zSUGJ;O5(uqJWQ{1z0o||z^RxPdy#L#fK8-yiqn_=Dx=^_4_60c9^Rg61{$ITgVv28 zVirRq*%~i;F&v_ai|9@j2Hdt!SeWi|7Spj7P%;jTatW52RH$DG6|Rz*8;&Do(7HPZ z=u3EQEzfHAiQr2|1-s>bh!F0z9Eoeoz{V4gpAR19vrB4MyJ1xV+Ui+e!yHSuF21L3 zW>nLL;6_1sU)Z`nFJ*oCt}m6NoCr5bE7+^i z%Z7WYP2|ndHD1x1qbKY1jEV}EvHNUJsz{1#iaAVvgREbM!7nV4NO&2Ka=kN&kX$Sz z) zbH9|qWrmjd5=wPTyu2%zE+bVrD}qG-r25Z2f-$61x`}P^hNKs z1G&?PYB$zAxG%ahUiLmSDP1(2D^Z(N z>oB(`?P+))ku~cnS~;3T8|Ey$&z*X}Yozlb2JGUp@zn)tx z`oiwt0tG5aafcQwQrv?TFRm@cA-GF$306EnDeeV|Lkh)$JHg#b@D$gS;sh?gJNLeK z=KJ3L7o3?h=j^@LTF?3*DhEDNeK24OT`M`pG-YDlcIyN}<-!PrAS>Rl`C6;`Mz_NA`1`_+OEO%=w3}s#(Jow2ul@IO=YaEkc%#cC|99nno93?m=xC)3l z3(}V7o^0LYsLPTdO-O(h-(|5)7_B-S%Lr!|)zG&!^!|AxJLJ-tZ}tOnyoUJz_v1f< z_24>Nb%0fHVwxbeh`i0`EU)3RbY4gw)$*@l&%9@7360&r2XyMmKJ4mQg}~o=&he?* z(ew!cjI4k6FqV#qz}$MNnh|^Jeu`o*M9Hp>NFJ!BkvqY*RgZk83@PQw%VKWNc_sE2 zmcH2`|M_8gU<@FI>H*MMmVS=nlvVJbU!QaDBJN}RDTeZ;(+A$2^5&I)F+JSf!Uy1( zZ&pxMU+OrB2v}tzDX5RBl;28)u%DA0Lu1@a`#jPGIkWk=gU?L&MZD4n+C{CKc<4p7 z2uBJIK;7%Kez1E;g<0SN!V|B#120%<3d+_Xs5S4C-ViyEIs;Q$dH}!H9$)l0!dbEt zbm@JQ_Yt!j{J&au*PF-W09&6llP%9EWpcWxRFe4|k{3nd#NGh;cMrK`2hPe#a$?k_ z%OC&XTYIybY2>zJ*a-OVOA=eykKdkqsSK}=GN5} zqU`<^l^8VqJ-~#mIbO|%)*^vVP=jlm8Bt7D|Ap7xAp6rw*5-T(fdt?)n+L{8FO*u&R~Z{&nXSXmrp;helJfo zTnTMcgRfm}Jt~^f*n0UaA(iSYEl{xUWYvl+JizbO(yROt=BewbgTb5<(w%UWfmk+w zs*>jn`VeTtxz+N*b0^RTNTlsBwxaPlE<`+`t<3&%JGZX^PuQ*#1D1o&q?=_mD;;Re z;~2VFY+F$RhB)OIt#!;XTebeqYlnA?r5-^8(j51PPGJLHA9vp_Y{hg9vd;!>+#j*| z6K?CUyJ)3dH(z;YB1Eg?33qbE-#wJ_|)9#`yL! zv663LUb*>v*(+L_R+>N>t+g7!bHo3M4?JNoUyg;jkktoD&`<2KZr{bHoBTkAxlp@e zV!t4Rs21hdE1*6|C-h!?C2f}a42)-L6i)7pGoI>rG)UBim|!uIDB|3ca&^S6KU4I% z#67*`GGP~`$Yj1&={`P1{!gSkXWF#)sIkEVfg9qkx9gR!b4Mw1wGOgITfCwtIdT11 zYa*@kdQtPgiWuf>kzOg=Azq%fY(39?X_Lwku2s%oWF&CBKDX9u^xQx!$nh^sdGJTt ze1BaAriL*iiPbhU(_BuAXGragPORfjW8C@0TwdbzM%#;q(u^VHI^gz1W}nc|VSf9s z%5Snb8mVkE`dM;R)uvHF_j@qO5WaZ2DmgA zJJ)8C-8SKmzqe6zl<&l{;w}2Z$v49}Zq3|rvy$z37ZuFZlXw7>Uwqx26Kvx_YZZoj zfc~rj&m=6d{Df=rfLQg9PmsPOFiBA2GMzMmCCKy<)g!I>8FUf;%9Yb_vM~cJi}O0- za5M5;mW2Q0dj^zJ|jus-N*U)3uj> z0#y58)8gsByHEuZG?s0X1Wlha{ad=g55IO^|+ z*xti~!8C)-H#!hc<8_A!zI#g-uqMZv>gtDOy<~v+xcAzp3Z{H3&NZF}t;0VT`F&X} z#GzS@rCE|m?Dw zF1-sVF@~OLhpduMZybQY`SFnet`M<3ropPT#2-gSGY{1J#--FD;9Ar^sUk(S$giFeu&#W$f%}fh@)3Qp_sk)RFN;GTR?Q5DiDFy5GGau)N`G0g<9_gwd z1;*>dvzZez%}tU68)+X=%Dg|nu_m05AB2fTQgO714WxbY^dxl^oO`#VmUn_XO^+mVu3q3kDN3#Mo;P9T@6)@BDzgecHf%fj=()HWf!#68u~Qw--g&lJ}zO z+m@6;e`%=psRUy}KLhglvrmFrS;uE@e+E@1kU^La4I_Iigue3&6B2=DM4rVz+h-Dc z%q5qaM~lksda%1Ke=Y0w^4*8w)3rif_;lPfRjO!)KSR_g9vkMMyr?olWp-zOBAPJMQ|mGUN0wWW4B-1?tYqb`LC zP@&oS+#AgsFxy-;Zl|3bMQRG{NMZRP2B9Y^z8RDmuZxM8w(l`w!-XOuwS|t8(kgIw ztSJT+!v~x@)h1k@9j8hArBI^O(QY)Hma>=~OzbxpMNi|AIWGIIC%!au&K5^Z!&hb0 zC8+d}#(V&4h_0XNSMOQDt-94G^$?9Ain(jA64eGy)maE?EtHwZJS& zve4iw9iY|2qqhWKg|LP6P-hl8W{V}(xe81nSBBlBY(Cg%4{%GQahOd=LyV1QdG)B& zn%{+ue5SDHOA)$Ugbo9T*G|#=sj1D=`~*K)6*-Fxtbn336mKj?3@M=ROk{(S)0=c{ zE?%15MJPi`YrIqOVA2F3TRJsg~EH!hhwjyO7h+U z5?VM2)e?8Vt1i2(Avu4|Xh#`Fyq%`6)r5NzkW2zKmdQdmO1@9$ROtne2?oTDM%Wo$ z;2+)&E-~UFX$fEE?YS6B#|Q=VhkjeL^|bt`sQj1GCML)W$jlIwkg=3{W_SIonJ&UR zC1^M#__SUAeSk0F{k7SLGacNSO<#Ze*; z>D9(9SgwR_3uvF^D<(rB7NhrC^7ym2b|pD?l+JCTzf&)whH^ z_u(N=LnsB3_be>57JuefQ$9jJgQ|c=>f%bON;5xxRSltUri0mS`d^;o%dfT1`g&mg z+`6M$iwGL_=q2e>i?dYffry=D^30@poW)wUT3)=c(;G0Oow+2Kr98>cSjj25zt z$^#j-F0U87`mo%zej9WC@zL@iCjQNfw`D%l^4M0mWToMLarRglkyJ*UP_;xF@&dYo z^Wfm|QPv#Zx?@mWO*Tv?u3ThF@kRH!bD*6V<8tZK%z=B1mJ_oF@;S%r)v=~2FWDKL z=j=s0-E%f<G{peT~Vn8uJ6cS-hWtN9+Gu2+p&b* z@;^gI*;?6vGWU2sNqd8kaGjd#zO zEiT75P8b*VNB>ET?LoM?)&Ah_-<-gdIo@OQq-y((OSqMy`@>a3Z)Bc;q=$m;+}AO^ z>Nx!52it0TFtRqGz0|GU!@yFz3ei1l|CFL8lI7-Lm$CX2&wj9=(hyxm9jH8k1;Uj3 zy|0zCFD39aXkkxOPzC+>EdOm}J)xJxFx|fnf*$90@B2NOa^-^aB3iiCZswajbMS4h zM1s%Jv-D0U8-7_gItkT7zFYV9j+O)VW>rV-Xt zW#1l-%BHeh?4lZ@%5e5x18hB=t~d6-Zw7c{A7UyZW$V)GLyFq}-L>Q@ZoGi$1Rb8j z-k$;w#O<1$izhP#l^honm)h$T5o@=HtaJq;g^kd|w{^+V$L$zgit+c16H z|JqSc5|r4@CScey;$1cZ$yQmcSOPqm2S@3%)@fS%qgH*3>XEt~F4|1y!lO%CvWMfA z3K6mG1Pj=1v5=SgkW0yNHFscy5U;t-V+8MG%9{SU;ZkVgI8-+Wb?M8^i&${m^0WG- z<1N#BZyHA<%QnunJxYGb0LpZ!rDL746W|)YkB68IbIX}?yRC`M1mBum?)vtMbXFrZ zcnSEp7qPMR94G(2f{H)arKMW#4+I#N2<Aje@%DunQmds0tKj&A27u5m z$n5G@!g442N$OHHMB0&xY4I9$A^j*g&X4?T(}9yDFvhRK7=gd7nn!{v#p=6{&b6rW zOc;J2IY09krpxwq30yOQ;6|dpAPNbORIra@cRG&o=xn`+k~bjV95aTao9Xrt z6_(E-*;o`mpP{>ZL7>Sb3E1#;`CQT!80A9%wXRaGu=dR1ax=IavYeRq+8h#%c6onP zB@{#Sf_GK?>itBvf(vk`^P&OZEsKZ_#-X%9@Gdy4^=MzHJs+W~KM%6iIa|4AXfQmQ zx#BXU=%)Yg{Mbw0w4q6M0`VD}O{rmtcsg#qTa5DTT~ZB)7gSw5`8)r_6&QjuzQ$XF zlWIkts!iqRs&|jlnyRS_MT932@v|R%Ie=>wvh2z#N(1%DMz$VtsXW|G4GOvnt!myQ z{c!?m#zUEf6VC;7pD@3pO)NSf%_O&E4Br}9!CA00m|Iw9wEbFw;K^6E=AIQbpgaXW1qYo)2T`8lFPi_I_Qu5(uE zS+XGZSyd*#=?Qux?Hh=Z3FqKi@q9}*>iMe-J!vk*fqWs=stAYoDI2#bL=5i-?rkTu za??o2lP|1(_xy!M=_6-im{H z=UG(Z{UHw<_|C^m!i&ZJD)4aO4}i7mO>dAnEAtZ);_&8w?;@AyHyiTkUG;zHG`GsT z72tj6avHdjT5pGjS_B=k1DQKeM<>%@Upyh+j*oVT#h`eTj+`$`!SjyM>>Y>S;>v

        dj9-%QPBkrq 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 WHNOA8eTMMg5>1UC8&w!QiT)2B(-gG; literal 0 HcmV?d00001 diff --git a/packages/frontend/public/vite.svg b/packages/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/packages/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From eaac39f0c6cc4a9c13623fedad24c359f92254b4 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 20:51:22 +0900 Subject: [PATCH 050/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20yarn=20?= =?UTF-8?q?=EB=AA=85=EB=A0=B9=EC=96=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index e794138c..2fe8a201 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -34,7 +34,7 @@ jobs: ${{ runner.os }}-node- - name: Install dependencies - run: yarn ci + run: yarn install if: steps.cache.outputs.cache-hit != 'true' - name: Set PUBLIC_URL From 1301ded5f74db318f96e897861d96dadcb1835f1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 20:57:23 +0900 Subject: [PATCH 051/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20build=20?= =?UTF-8?q?=EB=AA=85=EB=A0=B9=EC=96=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 2fe8a201..80167f3b 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -44,13 +44,14 @@ jobs: - name: Build app run: | - yarn run build - cp ./build/index.html ./build/404.html + yarn client build + cp ./packages/frontend/build/index.html ./packages/frontend/build/404.html - name: Build storybook run: | - yarn run build-storybook - mv ./storybook-static ./build/storybook + yarn client build-storybook + mv ./packages/frontend/storybook-static ./packages/frontend/build/storybook + - name: Deploy to gh-pages branch uses: peaceiris/actions-gh-pages@v3 with: From 1c4854d298c727a966cb3994280f8933b841629c Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 21:58:25 +0900 Subject: [PATCH 052/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20tailwind=20config?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=EC=9D=84=20=EB=B6=88=EB=9F=AC=EC=98=A4?= =?UTF-8?q?=EC=A7=80=20=EB=AA=BB=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/styles/theme/darkTheme.ts | 12 ++++++------ packages/frontend/src/styles/theme/lightTheme.ts | 10 +++++----- packages/frontend/src/utils/getHistogramColorData.ts | 2 +- .../{tailwind.config.js => tailwind.config.ts} | 9 ++++++--- packages/frontend/tsconfig.app.json | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) rename packages/frontend/{tailwind.config.js => tailwind.config.ts} (81%) diff --git a/packages/frontend/src/styles/theme/darkTheme.ts b/packages/frontend/src/styles/theme/darkTheme.ts index 2ea53c4e..e6e492cf 100644 --- a/packages/frontend/src/styles/theme/darkTheme.ts +++ b/packages/frontend/src/styles/theme/darkTheme.ts @@ -1,19 +1,19 @@ import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; -import tailwindConfig from '@/../tailwind.config.js'; +import tailwindConfig from '@/../tailwind.config'; const colorConfig = resolveConfig(tailwindConfig).theme.colors; - +console.log(colorConfig.red); export const darkTheme: ChartTheme = { background: '#1a1a1a', textColor: '#ffffffe6', gridLines: '#334158', borderColor: '#485c7b', candlestick: { - upColor: colorConfig.red, - downColor: colorConfig.blue, - borderUpColor: colorConfig.red, - borderDownColor: colorConfig.blue, + upColor: colorConfig.red.toString(), + downColor: colorConfig.blue.toString(), + borderUpColor: colorConfig.red.toString(), + borderDownColor: colorConfig.blue.toString(), wickUpColor: '#838ca1', wickDownColor: '#838ca1', }, diff --git a/packages/frontend/src/styles/theme/lightTheme.ts b/packages/frontend/src/styles/theme/lightTheme.ts index 94b9e2c1..c1f2698d 100644 --- a/packages/frontend/src/styles/theme/lightTheme.ts +++ b/packages/frontend/src/styles/theme/lightTheme.ts @@ -1,6 +1,6 @@ import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; -import tailwindConfig from '@/../tailwind.config.js'; +import tailwindConfig from '@/../tailwind.config'; const colorConfig = resolveConfig(tailwindConfig).theme.colors; @@ -10,10 +10,10 @@ export const lightTheme: ChartTheme = { gridLines: '#e0e3eb', borderColor: '#d6dcde', candlestick: { - upColor: colorConfig.red, - downColor: colorConfig.blue, - borderUpColor: colorConfig.red, - borderDownColor: colorConfig.blue, + upColor: colorConfig.red.toString(), + downColor: colorConfig.blue.toString(), + borderUpColor: colorConfig.red.toString(), + borderDownColor: colorConfig.blue.toString(), wickUpColor: '#737375', wickDownColor: '#737375', }, diff --git a/packages/frontend/src/utils/getHistogramColorData.ts b/packages/frontend/src/utils/getHistogramColorData.ts index 0a347645..86524a45 100644 --- a/packages/frontend/src/utils/getHistogramColorData.ts +++ b/packages/frontend/src/utils/getHistogramColorData.ts @@ -1,5 +1,5 @@ import resolveConfig from 'tailwindcss/resolveConfig'; -import tailwindConfig from '@/../tailwind.config.js'; +import tailwindConfig from '@/../tailwind.config'; // TODO: api 나오면 객체/위치 수정 interface VolumeData { diff --git a/packages/frontend/tailwind.config.js b/packages/frontend/tailwind.config.ts similarity index 81% rename from packages/frontend/tailwind.config.js rename to packages/frontend/tailwind.config.ts index 69c2addd..10590b9f 100644 --- a/packages/frontend/tailwind.config.js +++ b/packages/frontend/tailwind.config.ts @@ -1,5 +1,6 @@ -/** @type {import('tailwindcss').Config} */ -export default { +import type { Config } from 'tailwindcss' + +const config: Config = { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: {}, @@ -18,4 +19,6 @@ export default { }, }, plugins: [], -}; +} + +export default config \ No newline at end of file diff --git a/packages/frontend/tsconfig.app.json b/packages/frontend/tsconfig.app.json index 374f7514..24c6800d 100644 --- a/packages/frontend/tsconfig.app.json +++ b/packages/frontend/tsconfig.app.json @@ -25,5 +25,5 @@ "composite": true }, - "include": ["src", "src/**/*.json"] + "include": ["src", "src/**/*.json", "tailwind.config.ts"] } From 577a8b2bb1f9b5ccb9d9465e37d329b2fca89f7d Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 21:58:47 +0900 Subject: [PATCH 053/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20css=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/layouts/Layout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/components/layouts/Layout.tsx b/packages/frontend/src/components/layouts/Layout.tsx index e37b3f2a..ad7fb7e8 100644 --- a/packages/frontend/src/components/layouts/Layout.tsx +++ b/packages/frontend/src/components/layouts/Layout.tsx @@ -3,9 +3,9 @@ import { Sidebar } from './Sidebar'; export const Layout = () => { return ( -

        +
        -
        +
        From 9bbec3306f822df6cb00913b3861643432f5a1e7 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 21:59:06 +0900 Subject: [PATCH 054/209] =?UTF-8?q?=E2=9C=A8=20feat:=20trading=20chart=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=ED=85=8C=EB=A7=88=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/TradingChart.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/TradingChart.tsx b/packages/frontend/src/pages/stock-detail/TradingChart.tsx index fd3053b2..198dedb0 100644 --- a/packages/frontend/src/pages/stock-detail/TradingChart.tsx +++ b/packages/frontend/src/pages/stock-detail/TradingChart.tsx @@ -1,13 +1,13 @@ import { useRef } from 'react'; import { useChart } from './hooks/useChart'; import { useChartResize } from './hooks/useChartResize'; -import { ChartTheme, darkTheme } from '@/styles/theme'; +import { ChartTheme, lightTheme } from '@/styles/theme'; interface TradingChartProps { theme?: ChartTheme; } -export const TradingChart = ({ theme = darkTheme }: TradingChartProps) => { +export const TradingChart = ({ theme = lightTheme }: TradingChartProps) => { const containerRef = useRef(null); const chart = useChart({ containerRef, theme }); From 9495552c213a3d67a12444ff31877e41aa84395d Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 21:59:35 +0900 Subject: [PATCH 055/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20build=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9C=84=ED=95=B4=20pr=20?= =?UTF-8?q?=EC=8B=9C=20=EB=8F=8C=EC=95=84=EA=B0=80=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 80167f3b..4a8d8098 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -3,6 +3,8 @@ name: storybook deploy on: push: branches: ['dev-fe'] + pull_request: + branches: ['dev-fe'] workflow_dispatch: From a5a0430d5ebda8efd06e544fb1bfd5fa44e7855f Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 22:03:19 +0900 Subject: [PATCH 056/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20build=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=AA=85=20=EC=88=98=EC=A0=95=20-\>=20dist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 4a8d8098..5397e084 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -47,12 +47,12 @@ jobs: - name: Build app run: | yarn client build - cp ./packages/frontend/build/index.html ./packages/frontend/build/404.html + cp ./packages/frontend/dist/index.html ./packages/frontend/dist/404.html - name: Build storybook run: | yarn client build-storybook - mv ./packages/frontend/storybook-static ./packages/frontend/build/storybook + mv ./packages/frontend/storybook-static ./packages/frontend/dist/storybook - name: Deploy to gh-pages branch uses: peaceiris/actions-gh-pages@v3 From 43f1461b506791aa963508c806c9b1dc8976c8f1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 22:09:15 +0900 Subject: [PATCH 057/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20frontend?= =?UTF-8?q?=20deploy=20workflow=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-frontend.yml | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/deploy-frontend.yml diff --git a/.github/workflows/deploy-frontend.yml b/.github/workflows/deploy-frontend.yml new file mode 100644 index 00000000..79cd98e2 --- /dev/null +++ b/.github/workflows/deploy-frontend.yml @@ -0,0 +1,65 @@ +name: Deploy Frontend in Monorepo + +on: + push: + branches: + - dev-fe + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + services: + docker: + image: docker:20.10.7 + options: --privileged + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Cache Yarn dependencies + uses: actions/cache@v3 + with: + path: | + **/node_modules + ~/.yarn-cache + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build frontend + run: | + yarn workspace frontend build + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push backend Docker image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + + - name: Deploy to server + uses: appleboy/ssh-action@v1.1.0 + with: + host: ${{ secrets.SERVER_HOST }} + username: ${{ secrets.SERVER_USER }} + key: ${{ secrets.SERVER_SSH_KEY}} + port: ${{ secrets.SERVER_PORT }} + script: | + docker pull ${{ secrets.DOCKER_USERNAME }}/frontend:latest + docker-compose down + docker-compose up -d From 83634145ff3f511589133ea971e285edf68bc6c2 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 22:15:35 +0900 Subject: [PATCH 058/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20workflow?= =?UTF-8?q?=EC=9D=98=20build=20dir=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 5397e084..e43536d0 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -58,4 +58,4 @@ jobs: uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build + publish_dir: ./packages/frontend/dist From c24982cc43a2a97b5c40de6636fe4ed8d3cdc490 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 22:44:58 +0900 Subject: [PATCH 059/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20github=20?= =?UTF-8?q?pages=20=EB=A9=94=EC=9D=B8=EC=97=90=20storybook=EC=9D=84=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index e43536d0..081dcd53 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -44,18 +44,12 @@ jobs: PUBLIC_URL=$(echo $GITHUB_REPOSITORY | sed -r 's/^.+\/(.+)$/\/\1\//') echo PUBLIC_URL=$PUBLIC_URL > .env - - name: Build app - run: | - yarn client build - cp ./packages/frontend/dist/index.html ./packages/frontend/dist/404.html - - name: Build storybook run: | yarn client build-storybook - mv ./packages/frontend/storybook-static ./packages/frontend/dist/storybook - name: Deploy to gh-pages branch uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./packages/frontend/dist + publish_dir: ./packages/frontend/storybook-static From 2b98d57d241aed18007c04f22ddff1141285d781 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 22:54:33 +0900 Subject: [PATCH 060/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20pr=20?= =?UTF-8?q?=EB=82=A0=EB=A6=B4=20=EB=95=8C=20workflow=20=EB=8F=8C=EC=95=84?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storybook.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index 081dcd53..9df02eff 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -3,8 +3,6 @@ name: storybook deploy on: push: branches: ['dev-fe'] - pull_request: - branches: ['dev-fe'] workflow_dispatch: From 2339e5f819a43531e695380e380de4ba264f32e0 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 23:11:51 +0900 Subject: [PATCH 061/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20dockerfil?= =?UTF-8?q?e=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/Dockerfile | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 packages/frontend/Dockerfile diff --git a/packages/frontend/Dockerfile b/packages/frontend/Dockerfile new file mode 100644 index 00000000..0f9d14d7 --- /dev/null +++ b/packages/frontend/Dockerfile @@ -0,0 +1,11 @@ +FROM node:20-alpine AS builder +WORKDIR /packages +COPY . . +RUN yarn install --frozen-lockfile +RUN yarn workspace frontend build + +# Nginx 서버로 빌드된 파일 서빙 +FROM nginx:alpine +COPY --from=builder /packages/packages/frontend/dist /usr/share/nginx/html +EXPOSE 8080 +CMD ["nginx", "-g", "daemon off;"] From b3ff70dd263b4a20f82b37afb08aaf4df773f4a2 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Thu, 14 Nov 2024 23:14:00 +0900 Subject: [PATCH 062/209] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20ci:=20docker=20?= =?UTF-8?q?image=20=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy-frontend.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-frontend.yml b/.github/workflows/deploy-frontend.yml index 79cd98e2..72623155 100644 --- a/.github/workflows/deploy-frontend.yml +++ b/.github/workflows/deploy-frontend.yml @@ -47,10 +47,10 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push backend Docker image + - name: Build and push frontend Docker image run: | - docker build -t ${{ secrets.DOCKER_USERNAME }}/backend:latest -f packages/backend/Dockerfile . - docker push ${{ secrets.DOCKER_USERNAME }}/backend:latest + docker build -t ${{ secrets.DOCKER_USERNAME }}/frontend:latest -f packages/frontend/Dockerfile . + docker push ${{ secrets.DOCKER_USERNAME }}/frontend:latest - name: Deploy to server uses: appleboy/ssh-action@v1.1.0 From 6584e35f7825aafa59fd8403e914ca505ef2e0a9 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:45:18 +0900 Subject: [PATCH 063/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=A7=80=EC=88=98=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=82=98?= =?UTF-8?q?=ED=83=80=EB=82=B4=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stocks/components/StockIndexCard.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 packages/frontend/src/pages/stocks/components/StockIndexCard.tsx diff --git a/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx b/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx new file mode 100644 index 00000000..66ff74c7 --- /dev/null +++ b/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx @@ -0,0 +1,32 @@ +import { ReactNode } from 'react'; +import { cn } from '@/utils/cn'; + +interface StockIndexCardProps { + children: ReactNode; + price: number; + change: number; + changePercent: number; +} + +export const StockIndexCard = ({ + children, + price, + change, + changePercent, +}: StockIndexCardProps) => { + return ( +
        +

        {children}

        +

        {price}

        +

        = 0 ? 'text-red' : 'text-blue', + )} + > + {changePercent >= 0 ? '▲' : '▼'} + {change}({changePercent}) +

        +
        + ); +}; From 4fc0a89a973956b1ba5d030e6f5d64ece139c5f3 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:45:51 +0900 Subject: [PATCH 064/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=82=98=ED=83=80=EB=82=B4?= =?UTF-8?q?=EB=8A=94=20=EC=B9=B4=EB=93=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/stocks/components/StockInfoCard.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/frontend/src/pages/stocks/components/StockInfoCard.tsx diff --git a/packages/frontend/src/pages/stocks/components/StockInfoCard.tsx b/packages/frontend/src/pages/stocks/components/StockInfoCard.tsx new file mode 100644 index 00000000..db2d3412 --- /dev/null +++ b/packages/frontend/src/pages/stocks/components/StockInfoCard.tsx @@ -0,0 +1,47 @@ +import { cn } from '@/utils/cn'; + +interface StockInfoCardProps { + name: string; + currentPrice: number; + changeRate: number; + changeRatePercent: number; + index: number; +} + +export const StockInfoCard = ({ + name, + currentPrice, + changeRate, + changeRatePercent, + index, +}: StockInfoCardProps) => { + return ( +
        +

        {name}

        +
        + 등락률 + = 0 ? 'text-red' : 'text-blue', + )} + > + {changeRate >= 0 && '+'} + {changeRate.toLocaleString()}원 ({changeRatePercent} + %) + +
        +
        + 현재가 + + {currentPrice.toLocaleString()} + +
        +
        + ); +}; From 523f72547fdcdac2be9f32a8ed939e581e21aac2 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:46:16 +0900 Subject: [PATCH 065/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=88=9C=EC=9C=84=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EA=B8=B0=20=EC=9C=84=ED=95=9C=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stocks/StockRankingTable.tsx | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 packages/frontend/src/pages/stocks/StockRankingTable.tsx diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx new file mode 100644 index 00000000..483870b9 --- /dev/null +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -0,0 +1,65 @@ +import { Link } from 'react-router-dom'; +import DownArrow from '@/assets/down-arrow.svg?react'; +import stockData from '@/mocks/stock.json'; +import { cn } from '@/utils/cn'; + +export const StockRankingTable = () => { + return ( +
        + + + + + + + + + + + + + + + + + + + {stockData.data.map((stock, index) => { + return ( + + + + + + + + ); + })} + +
        종목현재가 +

        등락률

        + +
        거래대금거래량
        + {index + 1} + + {stock.name} + + {stock.currentPrice.toLocaleString()}원= 0 ? 'text-red' : 'text-blue', + )} + > + {stock.changeRate >= 0 && '+'} + {stock.changeRate.toLocaleString()}원 ( + {stock.changeRatePercent} + %) + {stock.tradingVolume.toLocaleString()}원{stock.tradingValue.toLocaleString()}주
        +
        + ); +}; From ccd6e2ba2359f8247dc6d1c1dd235a5ef361966d Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:47:02 +0900 Subject: [PATCH 066/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EB=A9=94=EC=9D=B8=ED=8E=98=EC=9D=B4=EC=A7=80=20UI=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/down-arrow.svg | 3 + packages/frontend/src/mocks/market.json | 25 +++ packages/frontend/src/mocks/stock.json | 184 ++++++++++++++++++ packages/frontend/src/pages/stocks/Stocks.tsx | 72 +++++++ packages/frontend/src/pages/stocks/index.ts | 1 + 5 files changed, 285 insertions(+) create mode 100644 packages/frontend/src/assets/down-arrow.svg create mode 100644 packages/frontend/src/mocks/market.json create mode 100644 packages/frontend/src/mocks/stock.json create mode 100644 packages/frontend/src/pages/stocks/Stocks.tsx create mode 100644 packages/frontend/src/pages/stocks/index.ts diff --git a/packages/frontend/src/assets/down-arrow.svg b/packages/frontend/src/assets/down-arrow.svg new file mode 100644 index 00000000..a60f760d --- /dev/null +++ b/packages/frontend/src/assets/down-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/mocks/market.json b/packages/frontend/src/mocks/market.json new file mode 100644 index 00000000..4943c51f --- /dev/null +++ b/packages/frontend/src/mocks/market.json @@ -0,0 +1,25 @@ +{ + "data": [ + { + "name": "코스피", + "price": 2591.03, + "change": -26.77, + "changePercent": -1.0, + "trend": "down" + }, + { + "name": "코스닥", + "price": 738.49, + "change": 9.4, + "changePercent": 0.1, + "trend": "up" + }, + { + "name": "달러환율", + "price": 1382.2, + "change": -26.77, + "changePercent": -1.0, + "trend": "down" + } + ] +} diff --git a/packages/frontend/src/mocks/stock.json b/packages/frontend/src/mocks/stock.json new file mode 100644 index 00000000..9d2b7fc5 --- /dev/null +++ b/packages/frontend/src/mocks/stock.json @@ -0,0 +1,184 @@ +{ + "data": [ + { + "id": 1, + "name": "삼성전자", + "currentPrice": 82600, + "changeRate": 3200, + "changeRatePercent": 5.9, + "tradingVolume": 12850000, + "tradingValue": 1061410000000 + }, + { + "id": 2, + "name": "Alphabet Inc.", + "currentPrice": 2750.5, + "changeRate": -6500, + "changeRatePercent": 3.6, + "tradingVolume": 500000, + "tradingValue": 1377500000 + }, + { + "id": 3, + "name": "Amazon.com Inc.", + "currentPrice": 3400.1, + "changeRate": -1000, + "changeRatePercent": 2.5, + "tradingVolume": 300000, + "tradingValue": 1020300000 + }, + { + "id": 4, + "name": "애플", + "currentPrice": 145.3, + "changeRate": 2.5, + "changeRatePercent": 1.8, + "tradingVolume": 10000000, + "tradingValue": 1453000000 + }, + { + "id": 5, + "name": "테슬라", + "currentPrice": 680.4, + "changeRate": 15.2, + "changeRatePercent": 2.3, + "tradingVolume": 1200000, + "tradingValue": 816480000 + }, + { + "id": 6, + "name": "마이크로소프트", + "currentPrice": 300.1, + "changeRate": 4.0, + "changeRatePercent": 1.3, + "tradingVolume": 8000000, + "tradingValue": 2400800000 + }, + { + "id": 7, + "name": "페이스북", + "currentPrice": 345.8, + "changeRate": -10.5, + "changeRatePercent": -3.0, + "tradingVolume": 600000, + "tradingValue": 207480000 + }, + { + "id": 8, + "name": "넷플릭스", + "currentPrice": 525.4, + "changeRate": 20.6, + "changeRatePercent": 4.0, + "tradingVolume": 900000, + "tradingValue": 473860000 + }, + { + "id": 9, + "name": "IBM", + "currentPrice": 135.7, + "changeRate": -5.2, + "changeRatePercent": -3.7, + "tradingVolume": 200000, + "tradingValue": 27140000 + }, + { + "id": 10, + "name": "인텔", + "currentPrice": 55.5, + "changeRate": 1.0, + "changeRatePercent": 1.8, + "tradingVolume": 4000000, + "tradingValue": 222000000 + }, + { + "id": 11, + "name": "스타벅스", + "currentPrice": 95.0, + "changeRate": 1.5, + "changeRatePercent": 1.6, + "tradingVolume": 1500000, + "tradingValue": 142500000 + }, + { + "id": 12, + "name": "코카콜라", + "currentPrice": 60.2, + "changeRate": -0.3, + "changeRatePercent": -0.5, + "tradingVolume": 3000000, + "tradingValue": 180600000 + }, + { + "id": 13, + "name": "존슨앤드존슨", + "currentPrice": 165.0, + "changeRate": 3.0, + "changeRatePercent": 1.8, + "tradingVolume": 800000, + "tradingValue": 132000000 + }, + { + "id": 14, + "name": "월마트", + "currentPrice": 140.5, + "changeRate": 0.5, + "changeRatePercent": 0.4, + "tradingVolume": 2000000, + "tradingValue": 281000000 + }, + { + "id": 15, + "name": "디즈니", + "currentPrice": 175.0, + "changeRate": -2.0, + "changeRatePercent": -1.1, + "tradingVolume": 400000, + "tradingValue": 70000000 + }, + { + "id": 16, + "name": "NVIDIA", + "currentPrice": 220.3, + "changeRate": 6.0, + "changeRatePercent": 2.8, + "tradingVolume": 1500000, + "tradingValue": 330450000 + }, + { + "id": 17, + "name": "Qualcomm", + "currentPrice": 130.8, + "changeRate": 1.8, + "changeRatePercent": 1.4, + "tradingVolume": 900000, + "tradingValue": 117720000 + }, + { + "id": 18, + "name": "Adobe", + "currentPrice": 540.2, + "changeRate": 10.5, + "changeRatePercent": 2.0, + "tradingVolume": 300000, + "tradingValue": 162060000 + }, + { + "id": 19, + "name": "Salesforce", + "currentPrice": 270.0, + "changeRate": -3.0, + "changeRatePercent": -1.1, + "tradingVolume": 200000, + "tradingValue": 54000000 + }, + { + "id": 20, + "name": "PayPal", + "currentPrice": 90.5, + "changeRate": 2.0, + "changeRatePercent": 2.3, + "tradingVolume": 1000000, + "tradingValue": 90500000 + } + ] +} diff --git a/packages/frontend/src/pages/stocks/Stocks.tsx b/packages/frontend/src/pages/stocks/Stocks.tsx new file mode 100644 index 00000000..c3d98820 --- /dev/null +++ b/packages/frontend/src/pages/stocks/Stocks.tsx @@ -0,0 +1,72 @@ +import { StockIndexCard } from './components/StockIndexCard'; +import { StockInfoCard } from './components/StockInfoCard'; +import { StockRankingTable } from './StockRankingTable'; +import marketData from '@/mocks/market.json'; +import stockData from '@/mocks/stock.json'; + +const TOP_VIEW = 5; + +export const Stocks = () => { + const kospi = marketData.data.filter((value) => value.name === '코스피')[0]; + const kosdaq = marketData.data.filter((value) => value.name === '코스닥')[0]; + const rateOfExchange = marketData.data.filter( + (value) => value.name === '달러환율', + )[0]; + + return ( +
        +

        오늘의 투자

        +
        +

        + 지금 시장, 이렇게 움직이고 있어요. +

        +
        + + 코스피 + + + 코스닥 + + + 달러환율 + +
        +
        +
        +

        + 이 종목은 어떠신가요? +

        +
        + {stockData.data.slice(0, TOP_VIEW).map((stock, index) => ( + + ))} +
        +
        +
        +

        + 지금 가장 활발한 종목이에요. +

        + +
        +
        + ); +}; diff --git a/packages/frontend/src/pages/stocks/index.ts b/packages/frontend/src/pages/stocks/index.ts new file mode 100644 index 00000000..46525b4e --- /dev/null +++ b/packages/frontend/src/pages/stocks/index.ts @@ -0,0 +1 @@ +export * from './Stocks'; From ae164124002296001028bfbc539fd7824093be28 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:47:26 +0900 Subject: [PATCH 067/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20layout=20padding?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/layouts/Layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/layouts/Layout.tsx b/packages/frontend/src/components/layouts/Layout.tsx index ad7fb7e8..2d679229 100644 --- a/packages/frontend/src/components/layouts/Layout.tsx +++ b/packages/frontend/src/components/layouts/Layout.tsx @@ -5,7 +5,7 @@ export const Layout = () => { return (
        -
        +
        From 4f60f9b79c30d19b865d13d21ebbc3f0220646c1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:47:44 +0900 Subject: [PATCH 068/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EB=A9=94=EC=9D=B8=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/routes/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/routes/index.tsx b/packages/frontend/src/routes/index.tsx index 2a08323b..e49f80a4 100644 --- a/packages/frontend/src/routes/index.tsx +++ b/packages/frontend/src/routes/index.tsx @@ -3,6 +3,7 @@ import { Layout } from '@/components/layouts'; import { Home } from '@/pages/home'; import { MyPage } from '@/pages/my-page'; import { StockDetail } from '@/pages/stock-detail'; +import { Stocks } from '@/pages/stocks'; export const router = createBrowserRouter([ { @@ -13,8 +14,11 @@ export const router = createBrowserRouter([ element: , }, { - // TODO: 주식 메인페이지 만들어지면 path 바꿀것 path: '/stocks', + element: , + }, + { + path: 'stocks/:id', element: , }, { From ea31cb82b9f934440b291c5d7be046cef4797c5e Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 18 Nov 2024 20:54:47 +0900 Subject: [PATCH 069/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20return=20?= =?UTF-8?q?=ED=82=A4=EC=9B=8C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stocks/StockRankingTable.tsx | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx index 483870b9..73856127 100644 --- a/packages/frontend/src/pages/stocks/StockRankingTable.tsx +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -27,37 +27,32 @@ export const StockRankingTable = () => { - {stockData.data.map((stock, index) => { - return ( - - - {index + 1} - - {stock.name} - - - {stock.currentPrice.toLocaleString()}원 - = 0 ? 'text-red' : 'text-blue', - )} + {stockData.data.map((stock, index) => ( + + + {index + 1} + - {stock.changeRate >= 0 && '+'} - {stock.changeRate.toLocaleString()}원 ( - {stock.changeRatePercent} - %) - - {stock.tradingVolume.toLocaleString()}원 - {stock.tradingValue.toLocaleString()}주 - - ); - })} + {stock.name} + + + {stock.currentPrice.toLocaleString()}원 + = 0 ? 'text-red' : 'text-blue')} + > + {stock.changeRate >= 0 && '+'} + {stock.changeRate.toLocaleString()}원 ({stock.changeRatePercent} + %) + + {stock.tradingVolume.toLocaleString()}원 + {stock.tradingValue.toLocaleString()}주 + + ))}
        From 4446e25b7464fe3a80af2e4f10f25a5b4451d019 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 14:28:53 +0900 Subject: [PATCH 070/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20button=20type=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20hover=20=EC=8B=9C=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/ui/button/Button.tsx | 12 +++++++----- .../frontend/src/pages/stock-detail/StockDetail.tsx | 5 +---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/frontend/src/components/ui/button/Button.tsx b/packages/frontend/src/components/ui/button/Button.tsx index 7000fb44..04915e29 100644 --- a/packages/frontend/src/components/ui/button/Button.tsx +++ b/packages/frontend/src/components/ui/button/Button.tsx @@ -3,17 +3,17 @@ import { cva, VariantProps } from 'class-variance-authority'; import { cn } from '@/utils/cn'; export const ButtonVariants = cva( - `display-bold12 border rounded shadow-black`, + `display-bold12 border rounded shadow-black py-1`, { variants: { backgroundColor: { - default: 'bg-white', + default: 'bg-white hover:bg-orange', gray: 'bg-gray', - orange: 'bg-orange', + orange: 'bg-orange hover:bg-white', }, textColor: { - default: 'text-orange', - white: 'text-white', + default: 'text-orange hover:text-white', + white: 'text-white hover:text-orange', }, size: { default: 'w-24', @@ -35,6 +35,7 @@ export interface ButtonProps } export const Button = ({ + type = 'button', backgroundColor, textColor, size, @@ -44,6 +45,7 @@ export const Button = ({ }: ButtonProps) => { return ( From df3e85135995f4574ba08e88f59f9b3b3759d3c9 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 14:29:14 +0900 Subject: [PATCH 071/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20type=20import=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/stocks/components/StockIndexCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx b/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx index 66ff74c7..f9ae9e55 100644 --- a/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx +++ b/packages/frontend/src/pages/stocks/components/StockIndexCard.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { cn } from '@/utils/cn'; interface StockIndexCardProps { From 5fbf6ed2f70b0fb50b67914f1880dd86fcbcd471 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 14:29:48 +0900 Subject: [PATCH 072/209] =?UTF-8?q?=E2=9C=A8=20feat:=20input=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/ui/input/Input.tsx | 19 +++++++++++++++++++ .../frontend/src/components/ui/input/index.ts | 1 + 2 files changed, 20 insertions(+) create mode 100644 packages/frontend/src/components/ui/input/Input.tsx create mode 100644 packages/frontend/src/components/ui/input/index.ts diff --git a/packages/frontend/src/components/ui/input/Input.tsx b/packages/frontend/src/components/ui/input/Input.tsx new file mode 100644 index 00000000..dea815e4 --- /dev/null +++ b/packages/frontend/src/components/ui/input/Input.tsx @@ -0,0 +1,19 @@ +import { type InputHTMLAttributes } from 'react'; +import { cn } from '@/utils/cn'; + +interface InputProps extends InputHTMLAttributes { + className?: string; +} + +export const Input = ({ placeholder, className, ...props }: InputProps) => { + return ( + + ); +}; diff --git a/packages/frontend/src/components/ui/input/index.ts b/packages/frontend/src/components/ui/input/index.ts new file mode 100644 index 00000000..ba9fe7eb --- /dev/null +++ b/packages/frontend/src/components/ui/input/index.ts @@ -0,0 +1 @@ +export * from './Input'; From ef363c774ff7c946d63f8baca5e2b0a16a8b0ea6 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 14:31:37 +0900 Subject: [PATCH 073/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=EB=93=9C=EB=B0=94=20MenuList=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/layouts/MenuList.tsx | 38 +++++++++++-------- .../src/components/layouts/Sidebar.tsx | 24 +++++++++--- packages/frontend/src/constants/menuItems.tsx | 27 +++++-------- packages/frontend/src/types/menu.ts | 8 ++++ 4 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 packages/frontend/src/types/menu.ts diff --git a/packages/frontend/src/components/layouts/MenuList.tsx b/packages/frontend/src/components/layouts/MenuList.tsx index dc1940c2..7afebc1a 100644 --- a/packages/frontend/src/components/layouts/MenuList.tsx +++ b/packages/frontend/src/components/layouts/MenuList.tsx @@ -1,11 +1,12 @@ import { type ReactNode } from 'react'; import { useNavigate } from 'react-router-dom'; -import { type MenuItemData } from '@/constants/menuItems'; +import { type MenuSection } from '@/types/menu'; import { cn } from '@/utils/cn'; interface MenuListProps { - items: MenuItemData[]; + items: MenuSection[]; isHovered: boolean; + onItemClick?: (item: MenuSection) => void; } interface MenuItemProps { @@ -15,28 +16,33 @@ interface MenuItemProps { onClick?: () => void; } -export const MenuList = ({ items, isHovered }: MenuListProps) => { +export const MenuList = ({ items, isHovered, onItemClick }: MenuListProps) => { const navigate = useNavigate(); + const handleClick = (item: MenuSection) => { + if (item.path) { + navigate(item.path); + } + + onItemClick?.(item); + }; + return (
          - {items.map((menu) => { - const { id, icon, text, url } = menu; - return ( - url && navigate(url)} - /> - ); - })} + {items.map((item) => ( + handleClick(item)} + /> + ))}
        ); }; -const MenuItem = ({ icon, text, onClick, isHovered }: MenuItemProps) => { +const MenuItem = ({ icon, text, isHovered, onClick }: MenuItemProps) => { return (
      • ); }; diff --git a/packages/frontend/src/components/layouts/search/Search.tsx b/packages/frontend/src/components/layouts/search/Search.tsx new file mode 100644 index 00000000..33771b09 --- /dev/null +++ b/packages/frontend/src/components/layouts/search/Search.tsx @@ -0,0 +1,28 @@ +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { cn } from '@/utils/cn'; + +interface SearchProps { + className?: string; +} + +export const Search = ({ className }: SearchProps) => { + const searchResult = ['']; + + return ( +
        +

        검색

        +

        + 주식을 검색하세요. +

        +
        + + +
        + {searchResult.map((word) => ( + // TODO: 추후 Link로 수정 +

        {word}

        + ))} +
        + ); +}; diff --git a/packages/frontend/src/components/layouts/search/index.ts b/packages/frontend/src/components/layouts/search/index.ts new file mode 100644 index 00000000..addd5330 --- /dev/null +++ b/packages/frontend/src/components/layouts/search/index.ts @@ -0,0 +1 @@ +export * from './Search'; From 9c22b07366f032883422fb78044683f15db9fc32 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 14:33:29 +0900 Subject: [PATCH 075/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B0=94=EA=B9=A5=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=ED=96=88=EC=9D=84=20=EB=95=8C=20callback=20=EC=8B=A4=ED=96=89?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=BB=A4=EC=8A=A4=ED=85=80=ED=9B=85=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/layouts/Sidebar.tsx | 55 +++++++++++-------- .../frontend/src/hooks/useOutsideClick.ts | 23 ++++++++ 2 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 packages/frontend/src/hooks/useOutsideClick.ts diff --git a/packages/frontend/src/components/layouts/Sidebar.tsx b/packages/frontend/src/components/layouts/Sidebar.tsx index f57af1e6..bf4a5682 100644 --- a/packages/frontend/src/components/layouts/Sidebar.tsx +++ b/packages/frontend/src/components/layouts/Sidebar.tsx @@ -4,6 +4,7 @@ import logoTitle from '/logoTitle.png'; import { MenuList } from './MenuList'; import { Search } from './search'; import { BOTTOM_MENU_ITEMS, TOP_MENU_ITEMS } from '@/constants/menuItems'; +import { useOutsideClick } from '@/hooks/useOutsideClick'; import { type MenuSection } from '@/types/menu'; import { cn } from '@/utils/cn'; @@ -11,6 +12,12 @@ export const Sidebar = () => { const [isHovered, setIsHovered] = useState(false); const [showSearch, setShowSearch] = useState(false); + const ref = useOutsideClick(() => { + if (showSearch) { + setShowSearch(false); + } + }); + const handleMenuItemClick = (item: MenuSection) => { if (item.text === '검색') { setShowSearch((prev) => !prev); @@ -19,26 +26,26 @@ export const Sidebar = () => { return (
        - +
        + +
        { > {showSearch && }
        -
        +
        ); }; diff --git a/packages/frontend/src/hooks/useOutsideClick.ts b/packages/frontend/src/hooks/useOutsideClick.ts new file mode 100644 index 00000000..bd99fdcd --- /dev/null +++ b/packages/frontend/src/hooks/useOutsideClick.ts @@ -0,0 +1,23 @@ +import { useEffect, useRef } from 'react'; + +export const useOutsideClick = (callback: () => void) => { + const ref = useRef(null); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent | TouchEvent) => { + if (!ref.current?.contains(event.target as Node)) { + callback(); + } + }; + + document.addEventListener('mouseup', handleClickOutside); + document.addEventListener('touchend', handleClickOutside); + + return () => { + document.removeEventListener('mouseup', handleClickOutside); + document.removeEventListener('touchend', handleClickOutside); + }; + }, [callback]); + + return ref; +}; From de414aec4cccc1a0c6526bc335cf20f7af94fe38 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 20:35:52 +0900 Subject: [PATCH 076/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/google.png | Bin 0 -> 2846 bytes packages/frontend/src/assets/kakao.png | Bin 0 -> 3382 bytes packages/frontend/src/assets/naver.png | Bin 0 -> 2444 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/frontend/src/assets/google.png create mode 100644 packages/frontend/src/assets/kakao.png create mode 100644 packages/frontend/src/assets/naver.png diff --git a/packages/frontend/src/assets/google.png b/packages/frontend/src/assets/google.png new file mode 100644 index 0000000000000000000000000000000000000000..33d8f0ee562d61d00b288c969555f6d1bc96f36b GIT binary patch literal 2846 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 literal 0 HcmV?d00001 diff --git a/packages/frontend/src/assets/naver.png b/packages/frontend/src/assets/naver.png new file mode 100644 index 0000000000000000000000000000000000000000..e3da3450e951e3c5dcc47710e1ba871ca4dafdb8 GIT binary patch literal 2444 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 a-vTjtL{oo(sk3T%0=zv>dN5JpIsXP^q^ev1 literal 0 HcmV?d00001 From 8ce72664009580469486e3b6e6f3e70f0a97fbec Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 20:40:14 +0900 Subject: [PATCH 077/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/login/Login.tsx | 33 +++++++++++++++++++++ packages/frontend/src/pages/login/index.ts | 1 + 2 files changed, 34 insertions(+) create mode 100644 packages/frontend/src/pages/login/Login.tsx create mode 100644 packages/frontend/src/pages/login/index.ts diff --git a/packages/frontend/src/pages/login/Login.tsx b/packages/frontend/src/pages/login/Login.tsx new file mode 100644 index 00000000..f1df9679 --- /dev/null +++ b/packages/frontend/src/pages/login/Login.tsx @@ -0,0 +1,33 @@ +import { Link } from 'react-router-dom'; +import google from '@/assets/google.png'; +import kakao from '@/assets/kakao.png'; +import naver from '@/assets/naver.png'; + +interface LoginButtonProps { + to: string; + src: string; + alt: string; +} + +export const Login = () => { + return ( +
        +

        + 스마트한 투자의 첫걸음,
        주춤주춤과 함께해요! +

        +
        + + + +
        +
        + ); +}; + +export const LoginButton = ({ to, src, alt }: LoginButtonProps) => { + return ( + + {alt} + + ); +}; diff --git a/packages/frontend/src/pages/login/index.ts b/packages/frontend/src/pages/login/index.ts new file mode 100644 index 00000000..a10c3a83 --- /dev/null +++ b/packages/frontend/src/pages/login/index.ts @@ -0,0 +1 @@ +export * from './Login'; From 841a28106c37d365e2c2593bcaccc3f096cc928a Mon Sep 17 00:00:00 2001 From: baegyeong Date: Wed, 13 Nov 2024 20:40:48 +0900 Subject: [PATCH 078/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/routes/index.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/frontend/src/routes/index.tsx b/packages/frontend/src/routes/index.tsx index e49f80a4..0ee8d743 100644 --- a/packages/frontend/src/routes/index.tsx +++ b/packages/frontend/src/routes/index.tsx @@ -1,6 +1,7 @@ import { createBrowserRouter } from 'react-router-dom'; import { Layout } from '@/components/layouts'; import { Home } from '@/pages/home'; +import { Login } from '@/pages/login'; import { MyPage } from '@/pages/my-page'; import { StockDetail } from '@/pages/stock-detail'; import { Stocks } from '@/pages/stocks'; @@ -25,6 +26,10 @@ export const router = createBrowserRouter([ path: '/my-page', element: , }, + { + path: '/login', + element: , + }, ], }, ]); From df29ebec66f5c2477e06362b87d295131645c46a Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 15:34:52 +0900 Subject: [PATCH 079/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=B2=84=ED=8A=BC=EC=97=90=20shadow=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/login/Login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/login/Login.tsx b/packages/frontend/src/pages/login/Login.tsx index f1df9679..280d9fa0 100644 --- a/packages/frontend/src/pages/login/Login.tsx +++ b/packages/frontend/src/pages/login/Login.tsx @@ -26,7 +26,7 @@ export const Login = () => { export const LoginButton = ({ to, src, alt }: LoginButtonProps) => { return ( - + {alt} ); From 37f3eb574347fc1e04e9c5e75a22a116d55d2e5f Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 16:14:29 +0900 Subject: [PATCH 080/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20axios=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 1 + yarn.lock | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 067b43c4..d0ce21e7 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@tanstack/react-query": "^5.59.19", + "axios": "^1.7.7", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lightweight-charts": "^4.2.1", diff --git a/yarn.lock b/yarn.lock index 7612ff5b..909d52d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2752,6 +2752,15 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -4456,6 +4465,11 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -6711,6 +6725,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" From 6737e6b660eb8eccd0eafac7c96075b08db773f1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 16:15:14 +0900 Subject: [PATCH 081/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20login=20=EC=A0=84?= =?UTF-8?q?=EC=B2=B4=20=EB=84=A4=EB=AA=A8=EB=B0=95=EC=8A=A4=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/login/Login.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/frontend/src/pages/login/Login.tsx b/packages/frontend/src/pages/login/Login.tsx index 280d9fa0..5ad490d6 100644 --- a/packages/frontend/src/pages/login/Login.tsx +++ b/packages/frontend/src/pages/login/Login.tsx @@ -12,21 +12,23 @@ interface LoginButtonProps { export const Login = () => { return (
        -

        - 스마트한 투자의 첫걸음,
        주춤주춤과 함께해요! -

        -
        - - - -
        +
        +

        + 스마트한 투자의 첫걸음,
        주춤주춤과 함께해요! +

        +
        + + + +
        +
        ); }; export const LoginButton = ({ to, src, alt }: LoginButtonProps) => { return ( - + {alt} ); From 906423e066d3089fd2da2fe9affc4dadf543b8b5 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 16:15:31 +0900 Subject: [PATCH 082/209] =?UTF-8?q?=E2=9C=A8=20feat:=20api=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/apis/index.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/frontend/src/apis/index.ts diff --git a/packages/frontend/src/apis/index.ts b/packages/frontend/src/apis/index.ts new file mode 100644 index 00000000..3d6b587e --- /dev/null +++ b/packages/frontend/src/apis/index.ts @@ -0,0 +1,6 @@ +import axios from 'axios'; + +export const instance = axios.create({ + baseURL: import.meta.env.VITE_BASE_URL, + timeout: 1000, +}); From eb87babdf1595ca06ac1d93009bd2c219549dbc2 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 17:24:44 +0900 Subject: [PATCH 083/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/like.svg | 3 +++ .../stock-detail/components/ChatMessage.tsx | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/frontend/src/assets/like.svg create mode 100644 packages/frontend/src/pages/stock-detail/components/ChatMessage.tsx diff --git a/packages/frontend/src/assets/like.svg b/packages/frontend/src/assets/like.svg new file mode 100644 index 00000000..df23f220 --- /dev/null +++ b/packages/frontend/src/assets/like.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/pages/stock-detail/components/ChatMessage.tsx b/packages/frontend/src/pages/stock-detail/components/ChatMessage.tsx new file mode 100644 index 00000000..da696f9d --- /dev/null +++ b/packages/frontend/src/pages/stock-detail/components/ChatMessage.tsx @@ -0,0 +1,24 @@ +import Like from '@/assets/like.svg?react'; + +interface ChatMessageProps { + name: string; + contents: string; + like: number; +} + +export const ChatMessage = ({ name, contents, like }: ChatMessageProps) => { + return ( +
        +

        + {name} +

        +
        +

        {contents}

        +
        + + {like} +
        +
        +
        + ); +}; From 8c4930dfc20f062cbdc0a6172da35beea28f9f29 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Tue, 19 Nov 2024 17:25:42 +0900 Subject: [PATCH 084/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20chatPanel=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B0=80=EC=9A=B4?= =?UTF-8?q?=EB=8D=B0=20=EC=A0=95=EB=A0=AC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/ChatPanel.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx index b4d808df..9c568ceb 100644 --- a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -2,10 +2,13 @@ import { TextArea } from './components'; export const ChatPanel = () => { return ( -
        +

        채팅

        + onChange={(e) => setChatText(e.target.value)} + /> -
    + ); }; From 7cba32ad0d07067471575b7ab11131d904865c36 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 00:53:50 +0900 Subject: [PATCH 105/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20ws=20-\>=20wss?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/sockets/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/sockets/config.ts b/packages/frontend/src/sockets/config.ts index 30f7b471..67cdd3be 100644 --- a/packages/frontend/src/sockets/config.ts +++ b/packages/frontend/src/sockets/config.ts @@ -1,6 +1,6 @@ import { io } from 'socket.io-client'; -const URL = 'ws://juchum.info'; +const URL = 'wss://juchum.info'; export interface SocketChatType { stockId: string; From bd69976d36c23a36b727b15307d915ad744f332f Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 00:57:04 +0900 Subject: [PATCH 106/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20layout=20padding?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/components/layouts/Layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/components/layouts/Layout.tsx b/packages/frontend/src/components/layouts/Layout.tsx index 2d679229..ad7fb7e8 100644 --- a/packages/frontend/src/components/layouts/Layout.tsx +++ b/packages/frontend/src/components/layouts/Layout.tsx @@ -5,7 +5,7 @@ export const Layout = () => { return (
    -
    +
    From 920c83dce03eee01476cda0f2a9069c97c51aafb Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 01:19:21 +0900 Subject: [PATCH 107/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=9B=B9?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EC=BF=BC=EB=A6=AC=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=A7=81=EC=9C=BC=EB=A1=9C=20=EB=93=A4=EC=96=B4=EA=B0=80?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/sockets/config.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/sockets/config.ts b/packages/frontend/src/sockets/config.ts index 67cdd3be..3f6b29e5 100644 --- a/packages/frontend/src/sockets/config.ts +++ b/packages/frontend/src/sockets/config.ts @@ -8,14 +8,13 @@ export interface SocketChatType { } export const socketChat = ({ stockId, pageSize = 20 }: SocketChatType) => { - return io(`${URL}/api/chat/realtime`, { - transports: ['websocket'], - reconnectionDelayMax: 10000, - query: { - stockId, - pageSize, + return io( + `${URL}/api/chat/realtime?stockId=${stockId}&pageSize=${pageSize}`, + { + transports: ['websocket'], + reconnectionDelayMax: 10000, }, - }); + ); }; export const socketStock = io(`${URL}/api/stock/realtime`, { From 9d292df1c6f5aab731cee63b1bfb8c4cb603b527 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 01:19:49 +0900 Subject: [PATCH 108/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20useEffect=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=B0=B0=EC=97=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stock-detail/ChatPanel.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx index 9b91ebe3..fd48594f 100644 --- a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -24,9 +24,7 @@ export const ChatPanel = () => { useEffect(() => { const handleChat = (message: ChatDataResponse) => { - console.log('Received message:', message); if (message?.chats) { - console.log('Chats:', message.chats); setChatData(message.chats); } }; @@ -38,7 +36,7 @@ export const ChatPanel = () => { socketChat.off('chat', handleChat); }; } - }, [socketChat, isConnected]); + }, []); return (
    From 0d2f0cb633a1ef2edd89ffab78e766adc692a559 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 03:11:04 +0900 Subject: [PATCH 109/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=ED=8A=B8=20url=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/login/Login.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/frontend/src/pages/login/Login.tsx b/packages/frontend/src/pages/login/Login.tsx index 67b13ef3..df3b47a1 100644 --- a/packages/frontend/src/pages/login/Login.tsx +++ b/packages/frontend/src/pages/login/Login.tsx @@ -19,11 +19,7 @@ export const Login = () => {

    주춤주춤과 함께해요!

    - +
    From 377cedd229c744ee6d32b1d214d7990c0d10d859 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 03:17:01 +0900 Subject: [PATCH 110/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20url=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=EA=B3=A0=EC=B9=A8=20=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/login/Login.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend/src/pages/login/Login.tsx b/packages/frontend/src/pages/login/Login.tsx index df3b47a1..2b6c4ff7 100644 --- a/packages/frontend/src/pages/login/Login.tsx +++ b/packages/frontend/src/pages/login/Login.tsx @@ -28,7 +28,7 @@ export const Login = () => { export const LoginButton = ({ to, src, alt }: LoginButtonProps) => { return ( - + {alt} ); From 12661aba3ac6437d2b3bb68d042e1a733e928f04 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 03:52:53 +0900 Subject: [PATCH 111/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=9B=B9?= =?UTF-8?q?=EC=86=8C=EC=BC=93=20=EC=BB=A4=EC=8A=A4=ED=85=80=ED=9B=85=20?= =?UTF-8?q?=EC=B6=94=EC=83=81=ED=99=94=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/ChatPanel.tsx | 23 +++++++++------- packages/frontend/src/sockets/useWebsocket.ts | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 packages/frontend/src/sockets/useWebsocket.ts diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx index fd48594f..5a2d5765 100644 --- a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -1,21 +1,24 @@ import type { ChatDataType, ChatDataResponse } from '@/sockets/types'; -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { TextArea } from './components'; import { ChatMessage } from './components/ChatMessage'; import DownArrow from '@/assets/down-arrow.svg?react'; -import { useSocketChat } from '@/sockets/chat'; +import { socketChat } from '@/sockets/config'; +import { useWebsocket } from '@/sockets/useWebsocket'; export const ChatPanel = () => { const STOCK_ID = '005930'; - const [chatData, setChatData] = useState(); - const { socket: socketChat, isConnected } = useSocketChat({ - stockId: STOCK_ID, - }); + + const socket = useMemo(() => { + return socketChat({ stockId: STOCK_ID }); + }, [STOCK_ID]); + + const { isConnected } = useWebsocket(socket); const handleSendMessage = (message: string) => { if (isConnected) { - socketChat.emit('chat', { + socket.emit('chat', { room: STOCK_ID, content: message, }); @@ -30,13 +33,13 @@ export const ChatPanel = () => { }; if (isConnected) { - socketChat.on('chat', handleChat); + socket.on('chat', handleChat); return () => { - socketChat.off('chat', handleChat); + socket.off('chat', handleChat); }; } - }, []); + }, [isConnected, socket]); return (
    diff --git a/packages/frontend/src/sockets/useWebsocket.ts b/packages/frontend/src/sockets/useWebsocket.ts new file mode 100644 index 00000000..9a280d69 --- /dev/null +++ b/packages/frontend/src/sockets/useWebsocket.ts @@ -0,0 +1,26 @@ +import { useEffect, useState } from 'react'; +import { Socket } from 'socket.io-client'; + +export const useWebsocket = (socket: Socket) => { + const [isConnected, setIsConnected] = useState(socket.connected); + + useEffect(() => { + const onConnect = () => { + setIsConnected(true); + }; + + const onDisconnect = () => { + setIsConnected(false); + }; + + socket.on('connect', onConnect); + socket.on('disconnect', onDisconnect); + + return () => { + socket.off('connect', onConnect); + socket.off('disconnect', onDisconnect); + }; + }, [socket]); + + return { isConnected }; +}; From f782fe27acdd9d8a6dc834bd182daa6974de0ee9 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 10:25:04 +0900 Subject: [PATCH 112/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=20=EC=9D=B4=EC=8A=88=EB=A1=9C=20=EB=AA=A9=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EB=A1=9C=20=EC=9E=A0=EC=8B=9C=20=EB=8C=80?= =?UTF-8?q?=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/mocks/stock.json | 80 +++++++++---------- .../src/pages/stock-detail/StockDetail.tsx | 8 +- .../src/pages/stocks/StockRankingTable.tsx | 5 +- packages/frontend/src/pages/stocks/Stocks.tsx | 21 ++--- packages/frontend/src/routes/index.tsx | 2 +- packages/frontend/src/sockets/chat.ts | 30 ------- 6 files changed, 63 insertions(+), 83 deletions(-) delete mode 100644 packages/frontend/src/sockets/chat.ts diff --git a/packages/frontend/src/mocks/stock.json b/packages/frontend/src/mocks/stock.json index 9d2b7fc5..824a52ac 100644 --- a/packages/frontend/src/mocks/stock.json +++ b/packages/frontend/src/mocks/stock.json @@ -6,8 +6,8 @@ "currentPrice": 82600, "changeRate": 3200, "changeRatePercent": 5.9, - "tradingVolume": 12850000, - "tradingValue": 1061410000000 + "volume": 12850000, + "marketCap": 1061410000000 }, { "id": 2, @@ -15,8 +15,8 @@ "currentPrice": 2750.5, "changeRate": -6500, "changeRatePercent": 3.6, - "tradingVolume": 500000, - "tradingValue": 1377500000 + "volume": 500000, + "marketCap": 1377500000 }, { "id": 3, @@ -24,8 +24,8 @@ "currentPrice": 3400.1, "changeRate": -1000, "changeRatePercent": 2.5, - "tradingVolume": 300000, - "tradingValue": 1020300000 + "volume": 300000, + "marketCap": 1020300000 }, { "id": 4, @@ -33,8 +33,8 @@ "currentPrice": 145.3, "changeRate": 2.5, "changeRatePercent": 1.8, - "tradingVolume": 10000000, - "tradingValue": 1453000000 + "volume": 10000000, + "marketCap": 1453000000 }, { "id": 5, @@ -42,8 +42,8 @@ "currentPrice": 680.4, "changeRate": 15.2, "changeRatePercent": 2.3, - "tradingVolume": 1200000, - "tradingValue": 816480000 + "volume": 1200000, + "marketCap": 816480000 }, { "id": 6, @@ -51,8 +51,8 @@ "currentPrice": 300.1, "changeRate": 4.0, "changeRatePercent": 1.3, - "tradingVolume": 8000000, - "tradingValue": 2400800000 + "volume": 8000000, + "marketCap": 2400800000 }, { "id": 7, @@ -60,8 +60,8 @@ "currentPrice": 345.8, "changeRate": -10.5, "changeRatePercent": -3.0, - "tradingVolume": 600000, - "tradingValue": 207480000 + "volume": 600000, + "marketCap": 207480000 }, { "id": 8, @@ -69,8 +69,8 @@ "currentPrice": 525.4, "changeRate": 20.6, "changeRatePercent": 4.0, - "tradingVolume": 900000, - "tradingValue": 473860000 + "volume": 900000, + "marketCap": 473860000 }, { "id": 9, @@ -78,8 +78,8 @@ "currentPrice": 135.7, "changeRate": -5.2, "changeRatePercent": -3.7, - "tradingVolume": 200000, - "tradingValue": 27140000 + "volume": 200000, + "marketCap": 27140000 }, { "id": 10, @@ -87,8 +87,8 @@ "currentPrice": 55.5, "changeRate": 1.0, "changeRatePercent": 1.8, - "tradingVolume": 4000000, - "tradingValue": 222000000 + "volume": 4000000, + "marketCap": 222000000 }, { "id": 11, @@ -96,8 +96,8 @@ "currentPrice": 95.0, "changeRate": 1.5, "changeRatePercent": 1.6, - "tradingVolume": 1500000, - "tradingValue": 142500000 + "volume": 1500000, + "marketCap": 142500000 }, { "id": 12, @@ -105,8 +105,8 @@ "currentPrice": 60.2, "changeRate": -0.3, "changeRatePercent": -0.5, - "tradingVolume": 3000000, - "tradingValue": 180600000 + "volume": 3000000, + "marketCap": 180600000 }, { "id": 13, @@ -114,8 +114,8 @@ "currentPrice": 165.0, "changeRate": 3.0, "changeRatePercent": 1.8, - "tradingVolume": 800000, - "tradingValue": 132000000 + "volume": 800000, + "marketCap": 132000000 }, { "id": 14, @@ -123,8 +123,8 @@ "currentPrice": 140.5, "changeRate": 0.5, "changeRatePercent": 0.4, - "tradingVolume": 2000000, - "tradingValue": 281000000 + "volume": 2000000, + "marketCap": 281000000 }, { "id": 15, @@ -132,8 +132,8 @@ "currentPrice": 175.0, "changeRate": -2.0, "changeRatePercent": -1.1, - "tradingVolume": 400000, - "tradingValue": 70000000 + "volume": 400000, + "marketCap": 70000000 }, { "id": 16, @@ -141,8 +141,8 @@ "currentPrice": 220.3, "changeRate": 6.0, "changeRatePercent": 2.8, - "tradingVolume": 1500000, - "tradingValue": 330450000 + "volume": 1500000, + "marketCap": 330450000 }, { "id": 17, @@ -150,8 +150,8 @@ "currentPrice": 130.8, "changeRate": 1.8, "changeRatePercent": 1.4, - "tradingVolume": 900000, - "tradingValue": 117720000 + "volume": 900000, + "marketCap": 117720000 }, { "id": 18, @@ -159,8 +159,8 @@ "currentPrice": 540.2, "changeRate": 10.5, "changeRatePercent": 2.0, - "tradingVolume": 300000, - "tradingValue": 162060000 + "volume": 300000, + "marketCap": 162060000 }, { "id": 19, @@ -168,8 +168,8 @@ "currentPrice": 270.0, "changeRate": -3.0, "changeRatePercent": -1.1, - "tradingVolume": 200000, - "tradingValue": 54000000 + "volume": 200000, + "marketCap": 54000000 }, { "id": 20, @@ -177,8 +177,8 @@ "currentPrice": 90.5, "changeRate": 2.0, "changeRatePercent": 2.3, - "tradingVolume": 1000000, - "tradingValue": 90500000 + "volume": 1000000, + "marketCap": 90500000 } ] } diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index 3dc56c84..1f74e492 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -1,3 +1,4 @@ +import { useParams } from 'react-router-dom'; import { TradingChart } from './TradingChart'; import { AddAlarmForm, @@ -7,12 +8,17 @@ import { } from '.'; import Plus from '@/assets/plus.svg?react'; import { Button } from '@/components/ui/button'; +import stockData from '@/mocks/stock.json'; export const StockDetail = () => { + const { stockId = '' } = useParams(); + + const detailData = stockData.data.find((data) => data.id === +stockId); + return (
    -

    삼성전자

    +

    {detailData?.name}

    diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx index 46a78cc2..117ea95c 100644 --- a/packages/frontend/src/pages/stocks/StockRankingTable.tsx +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -3,6 +3,7 @@ import { Link } from 'react-router-dom'; import { usePostStockView } from '@/apis/queries/stock-detail'; import { useGetStocksByPrice } from '@/apis/queries/stocks'; import DownArrow from '@/assets/down-arrow.svg?react'; +import stockData from '@/mocks/stock.json'; import { cn } from '@/utils/cn'; const LIMIT = 20; @@ -42,7 +43,7 @@ export const StockRankingTable = () => { - {data?.map((stock, index) => ( + {stockData.data?.map((stock, index) => ( { {index + 1} mutate(stock.id)} + onClick={() => mutate(stock.id.toString())} className="display-bold14 hover:text-orange cursor-pointer text-ellipsis hover:underline" aria-label={stock.name} > diff --git a/packages/frontend/src/pages/stocks/Stocks.tsx b/packages/frontend/src/pages/stocks/Stocks.tsx index d5fda3ca..b4d6dd9a 100644 --- a/packages/frontend/src/pages/stocks/Stocks.tsx +++ b/packages/frontend/src/pages/stocks/Stocks.tsx @@ -3,6 +3,7 @@ import { StockInfoCard } from './components/StockInfoCard'; import { StockRankingTable } from './StockRankingTable'; import { useGetTopViews } from '@/apis/queries/stocks'; import marketData from '@/mocks/market.json'; +import stock from '@/mocks/stock.json'; const LIMIT = 5; @@ -51,15 +52,17 @@ export const Stocks = () => { 이 종목은 어떠신가요?
    - {topViews?.map((stock, index) => ( - - ))} + {stock.data + .slice(0, 5) + ?.map((stock, index) => ( + + ))}
    diff --git a/packages/frontend/src/routes/index.tsx b/packages/frontend/src/routes/index.tsx index 0ee8d743..1249146d 100644 --- a/packages/frontend/src/routes/index.tsx +++ b/packages/frontend/src/routes/index.tsx @@ -19,7 +19,7 @@ export const router = createBrowserRouter([ element: , }, { - path: 'stocks/:id', + path: 'stocks/:stockId', element: , }, { diff --git a/packages/frontend/src/sockets/chat.ts b/packages/frontend/src/sockets/chat.ts deleted file mode 100644 index cc6ff161..00000000 --- a/packages/frontend/src/sockets/chat.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useEffect, useMemo, useState } from 'react'; -import { socketChat, type SocketChatType } from './config'; - -export const useSocketChat = ({ stockId, pageSize }: SocketChatType) => { - const socket = useMemo(() => { - return socketChat({ stockId, pageSize }); - }, [pageSize, stockId]); - - const [isConnected, setIsConnected] = useState(socket.connected); - - useEffect(() => { - const onConnect = () => { - setIsConnected(true); - }; - - const onDisconnect = () => { - setIsConnected(false); - }; - - socket.on('connect', onConnect); - socket.on('disconnect', onDisconnect); - - return () => { - socket.off('connect', onConnect); - socket.off('disconnect', onDisconnect); - }; - }, [socket]); - - return { socket, isConnected }; -}; From 7c40223d7e506bf88be76eafd2bdb41e8354dcc8 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Fri, 22 Nov 2024 10:41:41 +0900 Subject: [PATCH 113/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/pages/stocks/StockRankingTable.tsx | 6 +++--- packages/frontend/src/pages/stocks/Stocks.tsx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx index 117ea95c..b8464a70 100644 --- a/packages/frontend/src/pages/stocks/StockRankingTable.tsx +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -1,17 +1,17 @@ import { useState } from 'react'; import { Link } from 'react-router-dom'; import { usePostStockView } from '@/apis/queries/stock-detail'; -import { useGetStocksByPrice } from '@/apis/queries/stocks'; +// import { useGetStocksByPrice } from '@/apis/queries/stocks'; import DownArrow from '@/assets/down-arrow.svg?react'; import stockData from '@/mocks/stock.json'; import { cn } from '@/utils/cn'; -const LIMIT = 20; +// const LIMIT = 20; export const StockRankingTable = () => { const [isGaining, setIsGaining] = useState(true); - const { data } = useGetStocksByPrice({ limit: LIMIT, isGaining }); + // const { data } = useGetStocksByPrice({ limit: LIMIT, isGaining }); const { mutate } = usePostStockView(); return ( diff --git a/packages/frontend/src/pages/stocks/Stocks.tsx b/packages/frontend/src/pages/stocks/Stocks.tsx index b4d6dd9a..8bdcc01c 100644 --- a/packages/frontend/src/pages/stocks/Stocks.tsx +++ b/packages/frontend/src/pages/stocks/Stocks.tsx @@ -1,11 +1,11 @@ import { StockIndexCard } from './components/StockIndexCard'; import { StockInfoCard } from './components/StockInfoCard'; import { StockRankingTable } from './StockRankingTable'; -import { useGetTopViews } from '@/apis/queries/stocks'; +// import { useGetTopViews } from '@/apis/queries/stocks'; import marketData from '@/mocks/market.json'; import stock from '@/mocks/stock.json'; -const LIMIT = 5; +// const LIMIT = 5; export const Stocks = () => { const kospi = marketData.data.filter((value) => value.name === '코스피')[0]; @@ -14,7 +14,7 @@ export const Stocks = () => { (value) => value.name === '달러환율', )[0]; - const { data: topViews } = useGetTopViews({ limit: LIMIT }); + // const { data: topViews } = useGetTopViews({ limit: LIMIT }); return (
    From dca2079da0086baf836507c7f47f12e6d30ad4d5 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:31:53 +0900 Subject: [PATCH 114/209] =?UTF-8?q?=F0=9F=9A=9A=20chore:=20zod=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/package.json | 3 ++- yarn.lock | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 6120a69c..3f991a75 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -21,7 +21,8 @@ "react-dom": "^18.3.1", "react-router-dom": "^6.28.0", "socket.io-client": "^4.8.1", - "tailwind-merge": "^2.5.4" + "tailwind-merge": "^2.5.4", + "zod": "^3.23.8" }, "devDependencies": { "@chromatic-com/storybook": "3.2.2", diff --git a/yarn.lock b/yarn.lock index f3d6ca8c..621f108a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8318,3 +8318,8 @@ yocto-queue@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== + +zod@^3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From ecc018e8b693425d8c82ba30bb3e6abec7d6c9ba Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:34:12 +0900 Subject: [PATCH 115/209] =?UTF-8?q?=E2=9C=A8=20feat:=20get,=20post=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(zod=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EC=B6=94=EA=B0=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/apis/utils/formatZodError.ts | 7 ++++ packages/frontend/src/apis/utils/get.ts | 26 +++++++++++++++ packages/frontend/src/apis/utils/post.ts | 32 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 packages/frontend/src/apis/utils/formatZodError.ts create mode 100644 packages/frontend/src/apis/utils/get.ts create mode 100644 packages/frontend/src/apis/utils/post.ts diff --git a/packages/frontend/src/apis/utils/formatZodError.ts b/packages/frontend/src/apis/utils/formatZodError.ts new file mode 100644 index 00000000..616b951d --- /dev/null +++ b/packages/frontend/src/apis/utils/formatZodError.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const formatZodError = (error: z.ZodError): string => { + return error.errors + .map((err) => `${err.path.join('.')}: ${err.message}`) + .join(', '); +}; diff --git a/packages/frontend/src/apis/utils/get.ts b/packages/frontend/src/apis/utils/get.ts new file mode 100644 index 00000000..7a270452 --- /dev/null +++ b/packages/frontend/src/apis/utils/get.ts @@ -0,0 +1,26 @@ +import { z } from 'zod'; +import { instance } from '../config'; +import { formatZodError } from './formatZodError'; + +interface GetParams { + schema: z.ZodType; + url: string; +} + +export const get = async ({ schema, url }: GetParams): Promise => { + try { + const { data } = await instance.get(url); + const result = schema.parse(data); + + if (!result.success) { + throw new Error(formatZodError(result.error)); + } + + return result; + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('API error:', error); + } + return null; + } +}; diff --git a/packages/frontend/src/apis/utils/post.ts b/packages/frontend/src/apis/utils/post.ts new file mode 100644 index 00000000..ade33e62 --- /dev/null +++ b/packages/frontend/src/apis/utils/post.ts @@ -0,0 +1,32 @@ +import { AxiosRequestConfig } from 'axios'; +import { z } from 'zod'; +import { instance } from '../config'; +import { formatZodError } from './formatZodError'; + +interface PostParams { + params: AxiosRequestConfig['params']; + schema: z.ZodType; + url: string; +} + +export const post = async ({ + params, + schema, + url, +}: PostParams): Promise => { + try { + const { data } = await instance.post(url, { params }); + const result = schema.parse(data); + + if (!result.success) { + throw new Error(formatZodError(result.error)); + } + + return result; + } catch (error) { + if (process.env.NODE_ENV === 'development') { + console.error('API error:', error); + } + return null; + } +}; From 0fbec7cdf3345adf509df8f1c4e0ea9a032728b0 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:38:48 +0900 Subject: [PATCH 116/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88=20=EC=A0=95=EC=9D=98=20=EB=B0=8F=20api=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/apis/queries/stock-detail/index.ts | 1 + .../src/apis/queries/stock-detail/schema.ts | 19 +++++++++++++++++ .../src/apis/queries/stock-detail/types.ts | 9 -------- .../queries/stock-detail/useGetStockDetail.ts | 21 +++++++++++++++++++ .../src/pages/stock-detail/StockDetail.tsx | 7 ++++--- 5 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 packages/frontend/src/apis/queries/stock-detail/schema.ts delete mode 100644 packages/frontend/src/apis/queries/stock-detail/types.ts create mode 100644 packages/frontend/src/apis/queries/stock-detail/useGetStockDetail.ts diff --git a/packages/frontend/src/apis/queries/stock-detail/index.ts b/packages/frontend/src/apis/queries/stock-detail/index.ts index 1ec21def..031ffa0d 100644 --- a/packages/frontend/src/apis/queries/stock-detail/index.ts +++ b/packages/frontend/src/apis/queries/stock-detail/index.ts @@ -1 +1,2 @@ +export * from './useGetStockDetail'; export * from './usePostStockView'; diff --git a/packages/frontend/src/apis/queries/stock-detail/schema.ts b/packages/frontend/src/apis/queries/stock-detail/schema.ts new file mode 100644 index 00000000..c592a604 --- /dev/null +++ b/packages/frontend/src/apis/queries/stock-detail/schema.ts @@ -0,0 +1,19 @@ +import { z } from 'zod'; + +export const GetStockRequestSchema = z.object({ + stockId: z.string(), +}); + +export type GetStockRequest = z.infer; + +export const GetStockResponseSchema = z.object({ + marketCap: z.number(), + name: z.string(), + eps: z.number(), + per: z.number(), + high52w: z.number(), + low52w: z.number(), +}); + +export type GetStockResponse = z.infer; + diff --git a/packages/frontend/src/apis/queries/stock-detail/types.ts b/packages/frontend/src/apis/queries/stock-detail/types.ts deleted file mode 100644 index 1a5eb831..00000000 --- a/packages/frontend/src/apis/queries/stock-detail/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface PostStockViewRequest { - stockId: string; -} - -export interface PostStockViewResponse { - id: string; - message: string; - date: Date; -} diff --git a/packages/frontend/src/apis/queries/stock-detail/useGetStockDetail.ts b/packages/frontend/src/apis/queries/stock-detail/useGetStockDetail.ts new file mode 100644 index 00000000..3704dfe0 --- /dev/null +++ b/packages/frontend/src/apis/queries/stock-detail/useGetStockDetail.ts @@ -0,0 +1,21 @@ +import { useQuery } from '@tanstack/react-query'; +import { + GetStockResponseSchema, + type GetStockRequest, + type GetStockResponse, +} from './schema'; +import { get } from '@/apis/utils/get'; + +const getStockDetail = ({ stockId }: GetStockRequest) => + get({ + schema: GetStockResponseSchema, + url: `/api/stock/${stockId}/detail`, + }); + +export const useGetStockDetail = ({ stockId }: GetStockRequest) => { + return useQuery({ + queryKey: ['stockDetail'], + queryFn: () => getStockDetail({ stockId }), + enabled: !!stockId, + }); +}; diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index 1f74e492..ba67e5f7 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -6,19 +6,20 @@ import { NotificationPanel, StockMetricsPanel, } from '.'; +import { useGetStockDetail } from '@/apis/queries/stock-detail'; import Plus from '@/assets/plus.svg?react'; import { Button } from '@/components/ui/button'; import stockData from '@/mocks/stock.json'; export const StockDetail = () => { - const { stockId = '' } = useParams(); + const { stockId } = useParams(); + const { data } = useGetStockDetail({ stockId: stockId ?? '' }); - const detailData = stockData.data.find((data) => data.id === +stockId); return (
    -

    {detailData?.name}

    +

    {data?.name}

    From 8c2ffaf7c620d8daa7621f36cffbae1fdeedb74b Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:40:35 +0900 Subject: [PATCH 117/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=EC=88=98=20=EC=A6=9D=EA=B0=80=20=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EB=A7=88=20=EC=A0=95=EC=9D=98=20=EB=B0=8F=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/apis/queries/stock-detail/schema.ts | 13 +++++++ .../queries/stock-detail/usePostStockView.ts | 34 ++++++++++--------- .../src/pages/stocks/StockRankingTable.tsx | 2 +- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/frontend/src/apis/queries/stock-detail/schema.ts b/packages/frontend/src/apis/queries/stock-detail/schema.ts index c592a604..7bc7e881 100644 --- a/packages/frontend/src/apis/queries/stock-detail/schema.ts +++ b/packages/frontend/src/apis/queries/stock-detail/schema.ts @@ -17,3 +17,16 @@ export const GetStockResponseSchema = z.object({ export type GetStockResponse = z.infer; +export const PostStockViewRequestSchema = z.object({ + stockId: z.string(), +}); + +export type PostStockViewRequest = z.infer; + +export const PostViewResponseSchema = z.object({ + id: z.string(), + message: z.string(), + date: z.date(), +}); + +export type PostViewResponse = z.infer; diff --git a/packages/frontend/src/apis/queries/stock-detail/usePostStockView.ts b/packages/frontend/src/apis/queries/stock-detail/usePostStockView.ts index 0c63cfff..6c6e8ede 100644 --- a/packages/frontend/src/apis/queries/stock-detail/usePostStockView.ts +++ b/packages/frontend/src/apis/queries/stock-detail/usePostStockView.ts @@ -1,20 +1,22 @@ -import type { PostStockViewRequest, PostStockViewResponse } from './types'; -import { useMutation, type UseMutationOptions } from '@tanstack/react-query'; -import { instance } from '@/apis/config'; +import { useMutation } from '@tanstack/react-query'; +import { + PostViewResponseSchema, + type PostStockViewRequest, + type PostViewResponse, +} from './schema'; +import { post } from '@/apis/utils/post'; -const postStockView = async ({ - stockId, -}: PostStockViewRequest): Promise => { - const { data } = await instance.post('/api/stock/view', { stockId }); - return data; -}; +const postStockView = async ({ stockId }: PostStockViewRequest) => + post({ + params: stockId, + schema: PostViewResponseSchema, + url: 'api/stock/view', + }); -export const usePostStockView = ( - options?: UseMutationOptions, -) => { - return useMutation({ - mutationKey: ['stock_view'], - mutationFn: (stockId) => postStockView({ stockId }), - ...options, +export const usePostStockView = () => { + return useMutation({ + mutationKey: ['stockView'], + mutationFn: ({ stockId }: PostStockViewRequest) => + postStockView({ stockId }), }); }; diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx index b8464a70..ab180f5b 100644 --- a/packages/frontend/src/pages/stocks/StockRankingTable.tsx +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -52,7 +52,7 @@ export const StockRankingTable = () => { {index + 1} mutate(stock.id.toString())} + onClick={() => mutate({ stockId: stock.id.toString() })} className="display-bold14 hover:text-orange cursor-pointer text-ellipsis hover:underline" aria-label={stock.name} > From 49157cbafd148ba8c45b8805436d638446d25c7a Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:42:27 +0900 Subject: [PATCH 118/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=EC=88=98=EC=88=9C=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=8A=A4=ED=82=A4=EB=A7=88=20=EC=A0=95=EC=9D=98=20=EB=B0=8F=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/apis/queries/stocks/index.ts | 2 +- .../src/apis/queries/stocks/schema.ts | 19 +++++++++++++ .../frontend/src/apis/queries/stocks/types.ts | 12 --------- .../src/apis/queries/stocks/useGetTopViews.ts | 23 +++++++++------- packages/frontend/src/pages/stocks/Stocks.tsx | 27 +++++++++---------- 5 files changed, 45 insertions(+), 38 deletions(-) create mode 100644 packages/frontend/src/apis/queries/stocks/schema.ts delete mode 100644 packages/frontend/src/apis/queries/stocks/types.ts diff --git a/packages/frontend/src/apis/queries/stocks/index.ts b/packages/frontend/src/apis/queries/stocks/index.ts index 645eecca..9337de4e 100644 --- a/packages/frontend/src/apis/queries/stocks/index.ts +++ b/packages/frontend/src/apis/queries/stocks/index.ts @@ -1,3 +1,3 @@ -export * from './types'; +export * from './schema'; export * from './useGetTopViews'; export * from './useGetStocksByPrice'; diff --git a/packages/frontend/src/apis/queries/stocks/schema.ts b/packages/frontend/src/apis/queries/stocks/schema.ts new file mode 100644 index 00000000..a857bd08 --- /dev/null +++ b/packages/frontend/src/apis/queries/stocks/schema.ts @@ -0,0 +1,19 @@ +import { z } from 'zod'; + +export const GetStockListRequestSchema = z.object({ + limit: z.number(), + sortType: z.enum(['increase', 'decrease']), +}); + +export type GetStockListRequest = z.infer; + +export const GetStockListResponseSchema = z.object({ + id: z.string(), + name: z.string(), + currentPrice: z.number(), + changeRate: z.number(), + volume: z.number(), + marketCap: z.string(), +}); + +export type GetStockListResponse = z.infer; diff --git a/packages/frontend/src/apis/queries/stocks/types.ts b/packages/frontend/src/apis/queries/stocks/types.ts deleted file mode 100644 index 528603db..00000000 --- a/packages/frontend/src/apis/queries/stocks/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface GetStockListRequest { - limit: number; -} - -export interface GetStockListResponse { - id: string; - name: string; - currentPrice: number; - changeRate: number; - volume: number; - marketCap: string; -} diff --git a/packages/frontend/src/apis/queries/stocks/useGetTopViews.ts b/packages/frontend/src/apis/queries/stocks/useGetTopViews.ts index 64b48a65..9ba48219 100644 --- a/packages/frontend/src/apis/queries/stocks/useGetTopViews.ts +++ b/packages/frontend/src/apis/queries/stocks/useGetTopViews.ts @@ -1,16 +1,19 @@ -import type { GetStockListRequest, GetStockListResponse } from './types'; import { useQuery } from '@tanstack/react-query'; -import { instance } from '@/apis/config'; +import { + GetStockListResponseSchema, + type GetStockListRequest, + type GetStockListResponse, +} from './schema'; +import { get } from '@/apis/utils/get'; -const getTopViews = async ({ - limit, -}: GetStockListRequest): Promise => { - const { data } = await instance.get(`/api/stock/topViews?limit=${limit}`); - return data; -}; +const getTopViews = ({ limit }: Partial) => + get({ + schema: GetStockListResponseSchema, + url: `/api/stock/topViews?limit=${limit}`, + }); -export const useGetTopViews = ({ limit }: GetStockListRequest) => { - return useQuery({ +export const useGetTopViews = ({ limit }: Partial) => { + return useQuery({ queryKey: ['stocks', 'topViews'], queryFn: () => getTopViews({ limit }), }); diff --git a/packages/frontend/src/pages/stocks/Stocks.tsx b/packages/frontend/src/pages/stocks/Stocks.tsx index 8bdcc01c..d5fda3ca 100644 --- a/packages/frontend/src/pages/stocks/Stocks.tsx +++ b/packages/frontend/src/pages/stocks/Stocks.tsx @@ -1,11 +1,10 @@ import { StockIndexCard } from './components/StockIndexCard'; import { StockInfoCard } from './components/StockInfoCard'; import { StockRankingTable } from './StockRankingTable'; -// import { useGetTopViews } from '@/apis/queries/stocks'; +import { useGetTopViews } from '@/apis/queries/stocks'; import marketData from '@/mocks/market.json'; -import stock from '@/mocks/stock.json'; -// const LIMIT = 5; +const LIMIT = 5; export const Stocks = () => { const kospi = marketData.data.filter((value) => value.name === '코스피')[0]; @@ -14,7 +13,7 @@ export const Stocks = () => { (value) => value.name === '달러환율', )[0]; - // const { data: topViews } = useGetTopViews({ limit: LIMIT }); + const { data: topViews } = useGetTopViews({ limit: LIMIT }); return (
    @@ -52,17 +51,15 @@ export const Stocks = () => { 이 종목은 어떠신가요?
    - {stock.data - .slice(0, 5) - ?.map((stock, index) => ( - - ))} + {topViews?.map((stock, index) => ( + + ))}
    From d591c44694abaf9958592288b6a8cdabedaab9ea Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 03:43:31 +0900 Subject: [PATCH 119/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=A3=BC=EC=8B=9D?= =?UTF-8?q?=20=EA=B0=80=EA=B2=A9=EC=88=9C=20=ED=83=80=EC=9E=85=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../queries/stocks/useGetStocksByPrice.ts | 45 ++++++++++--------- .../src/pages/stocks/StockRankingTable.tsx | 26 +++++++---- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/packages/frontend/src/apis/queries/stocks/useGetStocksByPrice.ts b/packages/frontend/src/apis/queries/stocks/useGetStocksByPrice.ts index 7d6fa284..a14f0269 100644 --- a/packages/frontend/src/apis/queries/stocks/useGetStocksByPrice.ts +++ b/packages/frontend/src/apis/queries/stocks/useGetStocksByPrice.ts @@ -1,29 +1,32 @@ -import type { GetStockListRequest, GetStockListResponse } from './types'; import { useQuery } from '@tanstack/react-query'; -import { instance } from '@/apis/config'; +import { + GetStockListResponseSchema, + type GetStockListRequest, + type GetStockListResponse, +} from './schema'; +import { get } from '@/apis/utils/get'; -const getTopGainers = async ({ - limit, -}: GetStockListRequest): Promise => { - const { data } = await instance.get(`/api/stock/topGainers?limit=${limit}`); - return data; -}; +const getTopGainers = ({ limit }: Partial) => + get({ + schema: GetStockListResponseSchema, + url: `/api/stock/topGainers?limit=${limit}`, + }); -const getTopLosers = async ({ - limit, -}: GetStockListRequest): Promise => { - const { data } = await instance.get(`/api/stock/topLosers?limit=${limit}`); - return data; -}; +const getTopLosers = ({ limit }: Partial) => + get({ + schema: GetStockListResponseSchema, + url: `/api/stock/topLosers?limit=${limit}`, + }); export const useGetStocksByPrice = ({ limit, - isGaining, -}: GetStockListRequest & { isGaining: boolean }) => { - return useQuery({ - queryKey: ['stocks', isGaining], - queryFn: isGaining - ? () => getTopGainers({ limit }) - : () => getTopLosers({ limit }), + sortType, +}: GetStockListRequest) => { + return useQuery({ + queryKey: ['stocks', sortType], + queryFn: + sortType === 'increase' + ? () => getTopGainers({ limit }) + : () => getTopLosers({ limit }), }); }; diff --git a/packages/frontend/src/pages/stocks/StockRankingTable.tsx b/packages/frontend/src/pages/stocks/StockRankingTable.tsx index ab180f5b..42ea0715 100644 --- a/packages/frontend/src/pages/stocks/StockRankingTable.tsx +++ b/packages/frontend/src/pages/stocks/StockRankingTable.tsx @@ -1,17 +1,20 @@ import { useState } from 'react'; import { Link } from 'react-router-dom'; import { usePostStockView } from '@/apis/queries/stock-detail'; -// import { useGetStocksByPrice } from '@/apis/queries/stocks'; +import { + type GetStockListRequest, + useGetStocksByPrice, +} from '@/apis/queries/stocks'; import DownArrow from '@/assets/down-arrow.svg?react'; -import stockData from '@/mocks/stock.json'; import { cn } from '@/utils/cn'; -// const LIMIT = 20; +const LIMIT = 20; export const StockRankingTable = () => { - const [isGaining, setIsGaining] = useState(true); + const [sortType, setSortType] = + useState('increase'); - // const { data } = useGetStocksByPrice({ limit: LIMIT, isGaining }); + const { data } = useGetStocksByPrice({ limit: LIMIT, sortType }); const { mutate } = usePostStockView(); return ( @@ -29,13 +32,18 @@ export const StockRankingTable = () => { 종목 현재가 -

    등락률({isGaining ? '상승순' : '하락순'})

    +

    등락률({sortType === 'increase' ? '상승순' : '하락순'})

    setIsGaining((prev) => !prev)} + onClick={() => + setSortType((prev) => { + if (prev === 'increase') return 'decrease'; + return 'increase'; + }) + } /> 거래대금 @@ -43,7 +51,7 @@ export const StockRankingTable = () => { - {stockData.data?.map((stock, index) => ( + {data?.map((stock, index) => ( Date: Mon, 25 Nov 2024 03:44:13 +0900 Subject: [PATCH 120/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=83=81=ED=83=9C=20=EC=A1=B0=ED=9A=8C=20=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EB=A7=88=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/apis/queries/auth/schema.ts | 7 +++++++ .../frontend/src/apis/queries/auth/types.ts | 3 --- .../src/apis/queries/auth/useGetLoginStatus.ts | 17 +++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 packages/frontend/src/apis/queries/auth/schema.ts delete mode 100644 packages/frontend/src/apis/queries/auth/types.ts diff --git a/packages/frontend/src/apis/queries/auth/schema.ts b/packages/frontend/src/apis/queries/auth/schema.ts new file mode 100644 index 00000000..eb1f186a --- /dev/null +++ b/packages/frontend/src/apis/queries/auth/schema.ts @@ -0,0 +1,7 @@ +import { z } from 'zod'; + +export const GetLoginStatusSchema = z.object({ + message: z.enum(['Authenticated', 'Not Authenticated']), +}); + +export type GetLoginStatus = z.infer; diff --git a/packages/frontend/src/apis/queries/auth/types.ts b/packages/frontend/src/apis/queries/auth/types.ts deleted file mode 100644 index 2ec8c5a4..00000000 --- a/packages/frontend/src/apis/queries/auth/types.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetLoginStatusResponse { - message: 'Authenticated' | 'Not Authenticated'; -} diff --git a/packages/frontend/src/apis/queries/auth/useGetLoginStatus.ts b/packages/frontend/src/apis/queries/auth/useGetLoginStatus.ts index 4d68f335..2e9c5966 100644 --- a/packages/frontend/src/apis/queries/auth/useGetLoginStatus.ts +++ b/packages/frontend/src/apis/queries/auth/useGetLoginStatus.ts @@ -1,15 +1,16 @@ import { useQuery } from '@tanstack/react-query'; -import { GetLoginStatusResponse } from './types'; -import { instance } from '@/apis/config'; +import { GetLoginStatusSchema, type GetLoginStatus } from './schema'; +import { get } from '@/apis/utils/get'; -const getLoginStatus = async (): Promise => { - const { data } = await instance.get('/api/auth/google/status'); - return data; -}; +const getLoginStatus = () => + get({ + schema: GetLoginStatusSchema, + url: '/api/auth/google/status', + }); export const useGetLoginStatus = () => { - return useQuery({ - queryKey: ['login_status'], + return useQuery({ + queryKey: ['loginStatus'], queryFn: getLoginStatus, }); }; From ded8dd05fa79c8b52e33ea9fedf4be7d257b98c4 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 04:03:53 +0900 Subject: [PATCH 121/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=20response=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/ChatPanel.tsx | 12 ++++++++--- packages/frontend/src/sockets/schema.ts | 20 +++++++++++++++++++ packages/frontend/src/sockets/types.ts | 14 ------------- 3 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 packages/frontend/src/sockets/schema.ts delete mode 100644 packages/frontend/src/sockets/types.ts diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx index 5a2d5765..6404c9bc 100644 --- a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -1,14 +1,18 @@ -import type { ChatDataType, ChatDataResponse } from '@/sockets/types'; import { useEffect, useMemo, useState } from 'react'; import { TextArea } from './components'; import { ChatMessage } from './components/ChatMessage'; import DownArrow from '@/assets/down-arrow.svg?react'; import { socketChat } from '@/sockets/config'; +import { + ChatDataSchema, + type ChatData, + type ChatDataResponse, +} from '@/sockets/schema'; import { useWebsocket } from '@/sockets/useWebsocket'; export const ChatPanel = () => { const STOCK_ID = '005930'; - const [chatData, setChatData] = useState(); + const [chatData, setChatData] = useState(); const socket = useMemo(() => { return socketChat({ stockId: STOCK_ID }); @@ -27,7 +31,9 @@ export const ChatPanel = () => { useEffect(() => { const handleChat = (message: ChatDataResponse) => { - if (message?.chats) { + const validatedChatData = ChatDataSchema.safeParse(message?.chats); + + if (validatedChatData.success && message?.chats) { setChatData(message.chats); } }; diff --git a/packages/frontend/src/sockets/schema.ts b/packages/frontend/src/sockets/schema.ts new file mode 100644 index 00000000..7495d1ed --- /dev/null +++ b/packages/frontend/src/sockets/schema.ts @@ -0,0 +1,20 @@ +import { z } from 'zod'; + +export const ChatDataSchema = z.object({ + id: z.number(), + likeCount: z.number(), + message: z.string(), + type: z.string(), + createdAt: z.date(), + liked: z.boolean(), + nickname: z.string(), +}); + +export type ChatData = z.infer; + +export const ChatDataResponseSchema = z.object({ + chats: z.array(ChatDataSchema), + hasMore: z.boolean(), +}); + +export type ChatDataResponse = z.infer; diff --git a/packages/frontend/src/sockets/types.ts b/packages/frontend/src/sockets/types.ts deleted file mode 100644 index 323f0b4a..00000000 --- a/packages/frontend/src/sockets/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface ChatDataType { - id: number; - likeCount: number; - message: string; - type: string; - createdAt: Date; - liked: boolean; - nickname: string; -} - -export interface ChatDataResponse { - chats?: ChatDataType[]; - hasMore: boolean; -} From f97cf06042386585f11b461c475495a4ce325d4e Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 04:04:23 +0900 Subject: [PATCH 122/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20get,=20post=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=8B=9C=20parse=20=EB=8C=80=EC=8B=A0=20s?= =?UTF-8?q?afeParse=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/apis/utils/get.ts | 4 ++-- packages/frontend/src/apis/utils/post.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/apis/utils/get.ts b/packages/frontend/src/apis/utils/get.ts index 7a270452..6f894f59 100644 --- a/packages/frontend/src/apis/utils/get.ts +++ b/packages/frontend/src/apis/utils/get.ts @@ -10,13 +10,13 @@ interface GetParams { export const get = async ({ schema, url }: GetParams): Promise => { try { const { data } = await instance.get(url); - const result = schema.parse(data); + const result = schema.safeParse(data); if (!result.success) { throw new Error(formatZodError(result.error)); } - return result; + return data; } catch (error) { if (process.env.NODE_ENV === 'development') { console.error('API error:', error); diff --git a/packages/frontend/src/apis/utils/post.ts b/packages/frontend/src/apis/utils/post.ts index ade33e62..9f7c71c2 100644 --- a/packages/frontend/src/apis/utils/post.ts +++ b/packages/frontend/src/apis/utils/post.ts @@ -16,13 +16,13 @@ export const post = async ({ }: PostParams): Promise => { try { const { data } = await instance.post(url, { params }); - const result = schema.parse(data); + const result = schema.safeParse(data); if (!result.success) { throw new Error(formatZodError(result.error)); } - return result; + return data; } catch (error) { if (process.env.NODE_ENV === 'development') { console.error('API error:', error); From bbc116743917d19d9f10ec41911755e970c805ad Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:02:01 +0900 Subject: [PATCH 123/209] =?UTF-8?q?=F0=9F=90=9B=20fix:=20=EA=B1=B0?= =?UTF-8?q?=EB=9E=98=EB=9F=89=20=EC=A7=80=ED=91=9C=EA=B0=80=20=EB=91=90?= =?UTF-8?q?=EB=B2=88=20=EB=B0=98=EB=B3=B5=EB=90=98=EB=AF=80=EB=A1=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/constants/METRIC_DETAILS.ts | 4 ---- .../src/pages/stock-detail/StockMetricsPanel.tsx | 12 +----------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/frontend/src/constants/METRIC_DETAILS.ts b/packages/frontend/src/constants/METRIC_DETAILS.ts index 2f5150e8..401ce2fc 100644 --- a/packages/frontend/src/constants/METRIC_DETAILS.ts +++ b/packages/frontend/src/constants/METRIC_DETAILS.ts @@ -1,8 +1,4 @@ export const METRIC_DETAILS = { - tradingVolume: { - name: '거래량', - message: '특정 기간 동안 거래된 주식의 수량이에요.', - }, price: { currentPrice: { name: '현재가', diff --git a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx index 3cba9f83..c9542c3e 100644 --- a/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/StockMetricsPanel.tsx @@ -1,19 +1,9 @@ -import { MetricSection, Title } from './components'; -import { Tooltip } from '@/components/ui/tooltip'; +import { MetricSection } from './components'; import { METRIC_DETAILS } from '@/constants/METRIC_DETAILS'; export const StockMetricsPanel = () => { return (
    -
    -
    - - {METRIC_DETAILS.tradingVolume.message} - - {METRIC_DETAILS.tradingVolume.name} -
    - 00.000 -
    Date: Mon, 25 Nov 2024 22:03:30 +0900 Subject: [PATCH 124/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A1=A4=EB=B0=94=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=A7=80?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/index.css | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/frontend/src/index.css b/packages/frontend/src/index.css index 7b68d633..cd69632b 100644 --- a/packages/frontend/src/index.css +++ b/packages/frontend/src/index.css @@ -54,3 +54,22 @@ @apply text-xs; } } + +::-webkit-scrollbar { + width: 5px; + height: 5px; +} + +::-webkit-scrollbar-track { + background: #dadada; + border-radius: 5px; +} + +::-webkit-scrollbar-thumb { + background: #aeaeae; + border-radius: 5px; +} + +::-webkit-scrollbar-thumb:hover { + background: #555; +} From beb8181fd52368145346b78dd1406442ea9587b1 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:04:34 +0900 Subject: [PATCH 125/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=95=8C=EB=9E=8C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/constants/alarmOptions.tsx | 5 ++ .../src/pages/stock-detail/AddAlarmForm.tsx | 66 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 packages/frontend/src/constants/alarmOptions.tsx diff --git a/packages/frontend/src/constants/alarmOptions.tsx b/packages/frontend/src/constants/alarmOptions.tsx new file mode 100644 index 00000000..3a46ffd1 --- /dev/null +++ b/packages/frontend/src/constants/alarmOptions.tsx @@ -0,0 +1,5 @@ +export const ALARM_OPTIONS = [ + { id: 1, label: '목표가' }, + { id: 2, label: '등락률' }, + { id: 3, label: '거래가' }, +]; diff --git a/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx index 95715984..3bffa75a 100644 --- a/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx +++ b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx @@ -1,7 +1,67 @@ -export const AddAlarmForm = () => { +import { Button } from '@/components/ui/button'; +import { ALARM_OPTIONS } from '@/constants/alarmOptions'; +import { cn } from '@/utils/cn'; + +interface AddAlarmFormProps { + className?: string; +} + +export const AddAlarmForm = ({ className }: AddAlarmFormProps) => { + const handleSubmit = () => {}; + return ( -
    -

    알림 추가

    +
    +

    알림 추가

    +
    +
    +
    +

    언제 알림을 보낼까요?

    +
    + + +
    +
    +
    +

    어떻게 알림을 보낼까요?

    +
    + + + + +
    +
    +
    +

    언제까지 알림을 보낼까요?

    + +
    +
    + +
    ); }; From d326cc0a5fc392bd4228dd63b330a0182ba578ef Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:05:32 +0900 Subject: [PATCH 126/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=95=8C=EB=9E=8C?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC?= =?UTF-8?q?=EB=8A=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/ui/alarm/Alarm.tsx | 32 +++++++++++++++++++ .../frontend/src/components/ui/alarm/index.ts | 1 + packages/frontend/src/mocks/alarm.json | 9 ++++++ .../frontend/src/pages/my-page/AlarmInfo.tsx | 27 ++++++++++++++++ packages/frontend/src/utils/getCurrentDate.ts | 7 ++++ 5 files changed, 76 insertions(+) create mode 100644 packages/frontend/src/components/ui/alarm/Alarm.tsx create mode 100644 packages/frontend/src/components/ui/alarm/index.ts create mode 100644 packages/frontend/src/mocks/alarm.json create mode 100644 packages/frontend/src/pages/my-page/AlarmInfo.tsx create mode 100644 packages/frontend/src/utils/getCurrentDate.ts diff --git a/packages/frontend/src/components/ui/alarm/Alarm.tsx b/packages/frontend/src/components/ui/alarm/Alarm.tsx new file mode 100644 index 00000000..04750869 --- /dev/null +++ b/packages/frontend/src/components/ui/alarm/Alarm.tsx @@ -0,0 +1,32 @@ +import Date from '@/assets/date.svg?react'; +import Flag from '@/assets/flag.svg?react'; +import Bell from '@/assets/small-bell.svg?react'; + +export interface AlarmProps { + goalPrice?: number; + method?: 'push' | 'email'; + date?: string; +} + +export const Alarm = ({ goalPrice, method, date }: AlarmProps) => { + return ( +
    + + + 목표가: {goalPrice?.toLocaleString()}원 + + + + {method === 'push' ? '웹 푸시' : '이메일'} 알림 + + + + {date} + +
    + + +
    +
    + ); +}; diff --git a/packages/frontend/src/components/ui/alarm/index.ts b/packages/frontend/src/components/ui/alarm/index.ts new file mode 100644 index 00000000..4e63ddfb --- /dev/null +++ b/packages/frontend/src/components/ui/alarm/index.ts @@ -0,0 +1 @@ +export * from './Alarm'; diff --git a/packages/frontend/src/mocks/alarm.json b/packages/frontend/src/mocks/alarm.json new file mode 100644 index 00000000..5f3dbca5 --- /dev/null +++ b/packages/frontend/src/mocks/alarm.json @@ -0,0 +1,9 @@ +{ + "data": [ + { + "goalPrice": 1000, + "method": "push", + "date": "2024.11.05" + } + ] +} diff --git a/packages/frontend/src/pages/my-page/AlarmInfo.tsx b/packages/frontend/src/pages/my-page/AlarmInfo.tsx new file mode 100644 index 00000000..37baf801 --- /dev/null +++ b/packages/frontend/src/pages/my-page/AlarmInfo.tsx @@ -0,0 +1,27 @@ +import { GetLoginStatus } from '@/apis/queries/auth/schema'; +import { Alarm, AlarmProps } from '@/components/ui/Alarm'; +import mock from '@/mocks/alarm.json'; + +interface AlarmInfoProps { + loginStatus: GetLoginStatus; +} + +export const AlarmInfo = ({ loginStatus }: AlarmInfoProps) => { + const { goalPrice, method, date } = mock.data[0] as AlarmProps; + + return ( +
    +

    알림

    + {loginStatus?.message === 'Authenticated' ? ( + <> + + + + ) : ( +

    + 로그인 후 이용 가능합니다. +

    + )} +
    + ); +}; diff --git a/packages/frontend/src/utils/getCurrentDate.ts b/packages/frontend/src/utils/getCurrentDate.ts new file mode 100644 index 00000000..72f0f6c0 --- /dev/null +++ b/packages/frontend/src/utils/getCurrentDate.ts @@ -0,0 +1,7 @@ +export const getCurrentDate = (date: Date) => + date.toLocaleDateString('ko-KR', { + year: 'numeric', + month: '2-digit', + day: '2-digit', + weekday: 'long', + }); From 0a0ea6884b94de4437c5c496025bf3e70319b4ae Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:06:52 +0900 Subject: [PATCH 127/209] =?UTF-8?q?=E2=9C=A8=20feat:=20alarm=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A5=BC=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=9D=98=20=EC=95=8C=EB=A6=BC?= =?UTF-8?q?=EC=B0=BD=EC=97=90=EC=84=9C=20=EB=A0=8C=EB=8D=94=EB=A7=81?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/assets/date.svg | 5 +++ packages/frontend/src/assets/flag.svg | 3 ++ packages/frontend/src/assets/small-bell.svg | 5 +++ .../pages/stock-detail/NotificationPanel.tsx | 33 +++++++++++++++++-- .../src/pages/stock-detail/StockDetail.tsx | 16 ++++----- .../frontend/src/pages/stock-detail/index.ts | 1 + 6 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 packages/frontend/src/assets/date.svg create mode 100644 packages/frontend/src/assets/flag.svg create mode 100644 packages/frontend/src/assets/small-bell.svg diff --git a/packages/frontend/src/assets/date.svg b/packages/frontend/src/assets/date.svg new file mode 100644 index 00000000..58bbe242 --- /dev/null +++ b/packages/frontend/src/assets/date.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/frontend/src/assets/flag.svg b/packages/frontend/src/assets/flag.svg new file mode 100644 index 00000000..b0091af3 --- /dev/null +++ b/packages/frontend/src/assets/flag.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/frontend/src/assets/small-bell.svg b/packages/frontend/src/assets/small-bell.svg new file mode 100644 index 00000000..00084054 --- /dev/null +++ b/packages/frontend/src/assets/small-bell.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx b/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx index e7db6e95..0ce5f804 100644 --- a/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/NotificationPanel.tsx @@ -1,7 +1,34 @@ -export const NotificationPanel = () => { +import { useGetLoginStatus } from '@/apis/queries/auth'; +import { Alarm, AlarmProps } from '@/components/ui/Alarm'; +import mock from '@/mocks/alarm.json'; +import { cn } from '@/utils/cn'; + +interface NotificationPanelProps { + className?: string; +} + +export const NotificationPanel = ({ className }: NotificationPanelProps) => { + const { goalPrice, method, date } = mock.data[0] as AlarmProps; + const { data: loginStatus } = useGetLoginStatus(); + return ( -
    -

    알림

    +
    +

    알림

    + {!loginStatus || loginStatus.message === 'Not Authenticated' ? ( +

    로그인 후 이용 가능합니다.

    + ) : goalPrice ? ( + <> + + + + ) : ( +

    현재 설정된 알림이 없어요.

    + )}
    ); }; diff --git a/packages/frontend/src/pages/stock-detail/StockDetail.tsx b/packages/frontend/src/pages/stock-detail/StockDetail.tsx index ba67e5f7..c2964b43 100644 --- a/packages/frontend/src/pages/stock-detail/StockDetail.tsx +++ b/packages/frontend/src/pages/stock-detail/StockDetail.tsx @@ -1,40 +1,38 @@ import { useParams } from 'react-router-dom'; -import { TradingChart } from './TradingChart'; import { AddAlarmForm, ChatPanel, NotificationPanel, StockMetricsPanel, + TradingChart, } from '.'; import { useGetStockDetail } from '@/apis/queries/stock-detail'; import Plus from '@/assets/plus.svg?react'; import { Button } from '@/components/ui/button'; -import stockData from '@/mocks/stock.json'; export const StockDetail = () => { const { stockId } = useParams(); const { data } = useGetStockDetail({ stockId: stockId ?? '' }); - return ( -
    +

    {data?.name}

    -
    +
    -
    +
    -
    - - +
    + +
    diff --git a/packages/frontend/src/pages/stock-detail/index.ts b/packages/frontend/src/pages/stock-detail/index.ts index 8887d490..dbff368f 100644 --- a/packages/frontend/src/pages/stock-detail/index.ts +++ b/packages/frontend/src/pages/stock-detail/index.ts @@ -3,3 +3,4 @@ export * from './AddAlarmForm'; export * from './ChatPanel'; export * from './NotificationPanel'; export * from './StockMetricsPanel'; +export * from './TradingChart'; From 2e795893fd02bf3010988b9b96bb015fc9f5479e Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:07:21 +0900 Subject: [PATCH 128/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EB=93=9C=EB=B0=94=EC=9D=98=20=EC=95=8C=EB=A6=BC=EC=B0=BD=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/layouts/Sidebar.tsx | 16 +++++++++- .../src/components/layouts/alarm/Alarm.tsx | 30 +++++++++++++++++++ .../src/components/layouts/alarm/index.ts | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/src/components/layouts/alarm/Alarm.tsx create mode 100644 packages/frontend/src/components/layouts/alarm/index.ts diff --git a/packages/frontend/src/components/layouts/Sidebar.tsx b/packages/frontend/src/components/layouts/Sidebar.tsx index 1a5f6fd8..88d60163 100644 --- a/packages/frontend/src/components/layouts/Sidebar.tsx +++ b/packages/frontend/src/components/layouts/Sidebar.tsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import logoCharacter from '/logoCharacter.png'; import logoTitle from '/logoTitle.png'; +import { Alarm } from './alarm'; import { MenuList } from './MenuList'; import { Search } from './search'; import { BOTTOM_MENU_ITEMS, TOP_MENU_ITEMS } from '@/constants/menuItems'; @@ -11,16 +12,28 @@ import { cn } from '@/utils/cn'; export const Sidebar = () => { const [isHovered, setIsHovered] = useState(false); const [showSearch, setShowSearch] = useState(false); + const [showAlarm, setShowAlarm] = useState(false); const ref = useOutsideClick(() => { if (showSearch) { setShowSearch(false); } + + if (showAlarm) { + setShowAlarm(false); + } }); const handleMenuItemClick = (item: MenuSection) => { + console.log(item.text); if (item.text === '검색') { - setShowSearch((prev) => !prev); + setShowSearch(true); + setShowAlarm(false); + } + + if (item.text === '알림') { + setShowSearch(false); + setShowAlarm(true); } }; @@ -68,6 +81,7 @@ export const Sidebar = () => { )} > {showSearch && } + {showAlarm && }
    ); diff --git a/packages/frontend/src/components/layouts/alarm/Alarm.tsx b/packages/frontend/src/components/layouts/alarm/Alarm.tsx new file mode 100644 index 00000000..9dd90c37 --- /dev/null +++ b/packages/frontend/src/components/layouts/alarm/Alarm.tsx @@ -0,0 +1,30 @@ +import { cn } from '@/utils/cn'; + +interface SearchProps { + className?: string; +} + +export const Alarm = ({ className }: SearchProps) => { + return ( +
    +
    +

    알림

    +

    + 1개의 알림이 있어요. +

    +
    +
    +

    오늘

    +
    +
    +

    + 삼성전자의 현재가는 00원이에요. +

    +
    +
    +
    +

    이전

    +
    +
    + ); +}; diff --git a/packages/frontend/src/components/layouts/alarm/index.ts b/packages/frontend/src/components/layouts/alarm/index.ts new file mode 100644 index 00000000..4e63ddfb --- /dev/null +++ b/packages/frontend/src/components/layouts/alarm/index.ts @@ -0,0 +1 @@ +export * from './Alarm'; From be89481f67b5870d569f73984ee201226d5af783 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:07:54 +0900 Subject: [PATCH 129/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=95=8C=EB=A6=BC,=20=EC=A3=BC?= =?UTF-8?q?=EC=8B=9D=20=EC=A0=95=EB=B3=B4=20=EA=B8=B0=EB=B3=B8=20UI=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/pages/my-page/MyPage.tsx | 14 ++++++------- .../frontend/src/pages/my-page/StockInfo.tsx | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 packages/frontend/src/pages/my-page/StockInfo.tsx diff --git a/packages/frontend/src/pages/my-page/MyPage.tsx b/packages/frontend/src/pages/my-page/MyPage.tsx index 683ac4e9..7e88ebb9 100644 --- a/packages/frontend/src/pages/my-page/MyPage.tsx +++ b/packages/frontend/src/pages/my-page/MyPage.tsx @@ -1,15 +1,19 @@ import { Link } from 'react-router-dom'; +import { AlarmInfo } from './AlarmInfo'; +import { StockInfo } from './StockInfo'; import { useGetLoginStatus } from '@/apis/queries/auth'; export const MyPage = () => { const { data: loginStatus } = useGetLoginStatus(); + if (!loginStatus) return <>; + return (

    마이페이지

    -
    +
    {loginStatus?.message === 'Authenticated' ? ( '내정보' ) : ( @@ -21,13 +25,9 @@ export const MyPage = () => { )}
    -
    - 알림 -
    -
    -
    - 주식 정보 +
    +
    ); diff --git a/packages/frontend/src/pages/my-page/StockInfo.tsx b/packages/frontend/src/pages/my-page/StockInfo.tsx new file mode 100644 index 00000000..c1e25a5e --- /dev/null +++ b/packages/frontend/src/pages/my-page/StockInfo.tsx @@ -0,0 +1,20 @@ +import { GetLoginStatus } from '@/apis/queries/auth/schema'; + +interface StockInfoProps { + loginStatus: GetLoginStatus; +} + +export const StockInfo = ({ loginStatus }: StockInfoProps) => { + return ( +
    +

    주식 정보

    + {loginStatus?.message === 'Authenticated' ? ( + <> + ) : ( +

    + 로그인 후 이용 가능합니다. +

    + )} +
    + ); +}; From 606fa733679e549a5d9fa959161c5d335b334bc2 Mon Sep 17 00:00:00 2001 From: baegyeong Date: Mon, 25 Nov 2024 22:08:25 +0900 Subject: [PATCH 130/209] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=B1=84=ED=8C=85?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EC=9D=84=20=EB=95=8C=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EC=95=88=EB=82=B4=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/stock-detail/ChatPanel.tsx | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx index 6404c9bc..a8eed251 100644 --- a/packages/frontend/src/pages/stock-detail/ChatPanel.tsx +++ b/packages/frontend/src/pages/stock-detail/ChatPanel.tsx @@ -49,22 +49,26 @@ export const ChatPanel = () => { return (
    -

    채팅

    +

    채팅