diff --git a/packages/frontend/src/apis/queries/auth/schema.ts b/packages/frontend/src/apis/queries/auth/schema.ts index e82b0bef..fc847ddd 100644 --- a/packages/frontend/src/apis/queries/auth/schema.ts +++ b/packages/frontend/src/apis/queries/auth/schema.ts @@ -14,42 +14,8 @@ export const GetTestLoginSchema = z.object({ export type GetTestLogin = z.infer; -export const GetUserInfoSchema = z.object({ - nickname: z.string(), - subName: z.string(), - createdAt: z.string().datetime(), - email: z.string(), - type: z.string(), -}); - -export type GetUserInfo = z.infer; - -export const PostUserNicknameSchema = z.object({ - message: z.string(), - date: z.string().datetime(), -}); - -export type PostUserNickname = z.infer; - export const PostLogoutSchema = z.object({ message: z.string(), }); export type PostLogout = z.infer; - -export const GetUserStockSchema = z.object({ - id: z.number(), - stockId: z.string(), - name: z.string(), - isTrading: z.boolean(), - groupCode: z.string(), - createdAt: z.string().datetime(), -}); - -export type GetUserStock = z.infer; - -export const GetUserStockResponseSchema = z.object({ - userStocks: z.array(GetUserStockSchema), -}); - -export type GetUserStockResponse = z.infer; diff --git a/packages/frontend/src/apis/queries/user/index.ts b/packages/frontend/src/apis/queries/user/index.ts new file mode 100644 index 00000000..9e26a7fd --- /dev/null +++ b/packages/frontend/src/apis/queries/user/index.ts @@ -0,0 +1,4 @@ +export * from './schema'; +export * from './useGetUserInfo'; +export * from './useGetUserStock'; +export * from './usePostUserNickname'; diff --git a/packages/frontend/src/apis/queries/user/schema.ts b/packages/frontend/src/apis/queries/user/schema.ts new file mode 100644 index 00000000..bc716011 --- /dev/null +++ b/packages/frontend/src/apis/queries/user/schema.ts @@ -0,0 +1,41 @@ +import { z } from 'zod'; + +export const GetUserInfoSchema = z.object({ + nickname: z.string(), + subName: z.string(), + createdAt: z.string().datetime(), + email: z.string(), + type: z.string(), +}); + +export type GetUserInfo = z.infer; + +export const GetUserStockSchema = z.object({ + id: z.number(), + stockId: z.string(), + name: z.string(), + isTrading: z.boolean(), + groupCode: z.string(), + createdAt: z.string().datetime(), +}); + +export type GetUserStock = z.infer; + +export const GetUserStockResponseSchema = z.object({ + userStocks: z.array(GetUserStockSchema), +}); + +export type GetUserStockResponse = z.infer; + +export const PostUserNicknameSchema = z.object({ + message: z.string(), + date: z.string().datetime(), +}); + +export type PostUserNickname = z.infer; + +export const GetUserThemeSchema = z.object({ + theme: z.enum(['light', 'dark']), +}); + +export type GetUserTheme = z.infer; diff --git a/packages/frontend/src/apis/queries/auth/useGetUserInfo.ts b/packages/frontend/src/apis/queries/user/useGetUserInfo.ts similarity index 100% rename from packages/frontend/src/apis/queries/auth/useGetUserInfo.ts rename to packages/frontend/src/apis/queries/user/useGetUserInfo.ts diff --git a/packages/frontend/src/apis/queries/auth/useGetUserStock.ts b/packages/frontend/src/apis/queries/user/useGetUserStock.ts similarity index 100% rename from packages/frontend/src/apis/queries/auth/useGetUserStock.ts rename to packages/frontend/src/apis/queries/user/useGetUserStock.ts diff --git a/packages/frontend/src/apis/queries/auth/usePostUserNickname.ts b/packages/frontend/src/apis/queries/user/usePostUserNickname.ts similarity index 100% rename from packages/frontend/src/apis/queries/auth/usePostUserNickname.ts rename to packages/frontend/src/apis/queries/user/usePostUserNickname.ts diff --git a/packages/frontend/src/assets/google.png b/packages/frontend/src/assets/google.png deleted file mode 100644 index 33d8f0ee..00000000 Binary files a/packages/frontend/src/assets/google.png and /dev/null differ diff --git a/packages/frontend/src/assets/google.svg b/packages/frontend/src/assets/google.svg new file mode 100644 index 00000000..088288fa --- /dev/null +++ b/packages/frontend/src/assets/google.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/frontend/src/components/layouts/Layout.tsx b/packages/frontend/src/components/layouts/Layout.tsx index d3d77474..0bb93b7d 100644 --- a/packages/frontend/src/components/layouts/Layout.tsx +++ b/packages/frontend/src/components/layouts/Layout.tsx @@ -3,7 +3,7 @@ import { Sidebar } from './Sidebar'; export const Layout = () => { return ( -
+
diff --git a/packages/frontend/src/components/layouts/Sidebar.tsx b/packages/frontend/src/components/layouts/Sidebar.tsx index f17273c8..2a166981 100644 --- a/packages/frontend/src/components/layouts/Sidebar.tsx +++ b/packages/frontend/src/components/layouts/Sidebar.tsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import logoCharacter from '/logoCharacter.png'; import logoTitle from '/logoTitle.png'; import { Alarm } from './alarm'; @@ -9,30 +10,41 @@ import { useOutsideClick } from '@/hooks/useOutsideClick'; import { type MenuSection } from '@/types/menu'; import { cn } from '@/utils/cn'; +type TabKey = 'search' | 'alarm'; + export const Sidebar = () => { + const navigate = useNavigate(); const [isHovered, setIsHovered] = useState(false); - const [showSearch, setShowSearch] = useState(false); - const [showAlarm, setShowAlarm] = useState(false); + const [showTabs, setShowTabs] = useState>({ + search: false, + alarm: false, + }); const ref = useOutsideClick(() => { - if (showSearch) { - setShowSearch(false); - } - - if (showAlarm) { - setShowAlarm(false); - } + setShowTabs({ search: false, alarm: false }); }); const handleMenuItemClick = (item: MenuSection) => { - if (item.text === '검색') { - setShowSearch(true); - setShowAlarm(false); + const tab: Record = { + 검색: 'search', + 알림: 'alarm', + }; + + const tabKey = tab[item.text]; + if (tabKey) { + setShowTabs((prev) => + Object.keys(prev).reduce( + (acc, key) => ({ + ...acc, + [key]: key === tabKey, + }), + {} as Record, + ), + ); } - if (item.text === '알림') { - setShowSearch(false); - setShowAlarm(true); + if (item.text === '다크모드') { + document.body.classList.toggle('dark'); } }; @@ -48,7 +60,10 @@ export const Sidebar = () => { onMouseLeave={() => setIsHovered(false)} >
-
+
navigate('/')} + > 로고 캐릭터 { isHovered={isHovered} onItemClick={handleMenuItemClick} /> - +
@@ -79,8 +98,8 @@ export const Sidebar = () => { isHovered ? 'left-60' : 'left-24', )} > - {showSearch && } - {showAlarm && } + {showTabs.search && } + {showTabs.alarm && }
); diff --git a/packages/frontend/src/components/ui/alarm/Alarm.tsx b/packages/frontend/src/components/ui/alarm/Alarm.tsx index 04750869..1057c6ee 100644 --- a/packages/frontend/src/components/ui/alarm/Alarm.tsx +++ b/packages/frontend/src/components/ui/alarm/Alarm.tsx @@ -10,7 +10,7 @@ export interface AlarmProps { export const Alarm = ({ goalPrice, method, date }: AlarmProps) => { return ( -
+
목표가: {goalPrice?.toLocaleString()}원 diff --git a/packages/frontend/src/components/ui/input/Input.tsx b/packages/frontend/src/components/ui/input/Input.tsx index dea815e4..fb4fce4f 100644 --- a/packages/frontend/src/components/ui/input/Input.tsx +++ b/packages/frontend/src/components/ui/input/Input.tsx @@ -10,7 +10,7 @@ export const Input = ({ placeholder, className, ...props }: InputProps) => { void; -} - export const Login = () => { - const navigate = useNavigate(); const googleLoginUrl = '/api/auth/google/login'; const { refetch } = useGetTestLogin({ password: 'test', username: 'test' }); return (
-
+

스마트한 투자의 첫걸음,

주춤주춤과 함께해요!

- - + + + + + +
); }; - -export const LoginButton = ({ to, src, alt, onClick }: LoginButtonProps) => { - return ( - - {alt} - - ); -}; diff --git a/packages/frontend/src/pages/my-page/StockInfo.tsx b/packages/frontend/src/pages/my-page/StockInfo.tsx index e104f150..0cec9256 100644 --- a/packages/frontend/src/pages/my-page/StockInfo.tsx +++ b/packages/frontend/src/pages/my-page/StockInfo.tsx @@ -1,8 +1,8 @@ import { useQueryClient } from '@tanstack/react-query'; import { useNavigate } from 'react-router-dom'; import { GetLoginStatus } from '@/apis/queries/auth/schema'; -import { useGetUserStock } from '@/apis/queries/auth/useGetUserStock'; import { useDeleteStockUser } from '@/apis/queries/stock-detail'; +import { useGetUserStock } from '@/apis/queries/user/useGetUserStock'; import { Button } from '@/components/ui/button'; interface StockInfoProps { diff --git a/packages/frontend/src/pages/my-page/UserInfo.tsx b/packages/frontend/src/pages/my-page/UserInfo.tsx index 8e8e9d1a..0fceeb1a 100644 --- a/packages/frontend/src/pages/my-page/UserInfo.tsx +++ b/packages/frontend/src/pages/my-page/UserInfo.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; -import { useGetUserInfo } from '@/apis/queries/auth/useGetUserInfo'; import { usePostLogout } from '@/apis/queries/auth/usePostLogout'; -import { usePostUserNickname } from '@/apis/queries/auth/usePostUserNickname'; +import { useGetUserInfo } from '@/apis/queries/user/useGetUserInfo'; +import { usePostUserNickname } from '@/apis/queries/user/usePostUserNickname'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; diff --git a/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx index 3bffa75a..dfdf938b 100644 --- a/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx +++ b/packages/frontend/src/pages/stock-detail/AddAlarmForm.tsx @@ -1,4 +1,5 @@ import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; import { ALARM_OPTIONS } from '@/constants/alarmOptions'; import { cn } from '@/utils/cn'; @@ -25,28 +26,34 @@ export const AddAlarmForm = ({ className }: AddAlarmFormProps) => {

언제 알림을 보낼까요?

- {ALARM_OPTIONS.map((option) => ( ))} -

어떻게 알림을 보낼까요?

- + - + @@ -54,10 +61,7 @@ export const AddAlarmForm = ({ className }: AddAlarmFormProps) => {

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

- +
diff --git a/packages/frontend/src/pages/stock-detail/components/TextArea.tsx b/packages/frontend/src/pages/stock-detail/components/TextArea.tsx index 5b1f9739..515062ad 100644 --- a/packages/frontend/src/pages/stock-detail/components/TextArea.tsx +++ b/packages/frontend/src/pages/stock-detail/components/TextArea.tsx @@ -29,7 +29,7 @@ export const TextArea = ({ disabled, onSend, placeholder }: TextAreaProps) => { disabled={disabled} autoFocus className={cn( - 'display-medium12 border-light-yellow h-20 w-full resize-none rounded-md border-4 p-3 pr-10 focus:outline-none', + 'display-medium12 border-light-yellow h-20 w-full resize-none rounded-md border-4 bg-white p-3 pr-10 focus:outline-none', disabled && 'bg-light-gray/40 cursor-not-allowed', )} onChange={(e) => { diff --git a/packages/frontend/src/styles/theme/darkTheme.ts b/packages/frontend/src/styles/theme/darkTheme.ts index 2122b987..bf6b3d91 100644 --- a/packages/frontend/src/styles/theme/darkTheme.ts +++ b/packages/frontend/src/styles/theme/darkTheme.ts @@ -1,8 +1,4 @@ -import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; -import tailwindConfig from '@/../tailwind.config'; - -const colorConfig = resolveConfig(tailwindConfig).theme.colors; export const darkTheme: ChartTheme = { background: '#1a1a1a', @@ -10,11 +6,11 @@ export const darkTheme: ChartTheme = { gridLines: '#334158', borderColor: '#485c7b', candlestick: { - upColor: colorConfig.red.toString(), - downColor: colorConfig.blue.toString(), - borderUpColor: colorConfig.red.toString(), - borderDownColor: colorConfig.blue.toString(), - wickUpColor: '#838ca1', - wickDownColor: '#838ca1', + upColor: '#ff4d4d', + downColor: '#1a75ff', + borderUpColor: '#ff4d4d', + borderDownColor: '#1a75ff', + wickUpColor: '#737375', + wickDownColor: '#737375', }, }; diff --git a/packages/frontend/src/styles/theme/lightTheme.ts b/packages/frontend/src/styles/theme/lightTheme.ts index c1f2698d..08a436a7 100644 --- a/packages/frontend/src/styles/theme/lightTheme.ts +++ b/packages/frontend/src/styles/theme/lightTheme.ts @@ -1,19 +1,15 @@ -import resolveConfig from 'tailwindcss/resolveConfig'; import { ChartTheme } from '.'; -import tailwindConfig from '@/../tailwind.config'; - -const colorConfig = resolveConfig(tailwindConfig).theme.colors; export const lightTheme: ChartTheme = { - background: colorConfig.white, + background: '#ffffff', textColor: '#000000e6', gridLines: '#e0e3eb', borderColor: '#d6dcde', candlestick: { - upColor: colorConfig.red.toString(), - downColor: colorConfig.blue.toString(), - borderUpColor: colorConfig.red.toString(), - borderDownColor: colorConfig.blue.toString(), + upColor: '#ff4d4d', + downColor: '#1a75ff', + borderUpColor: '#ff4d4d', + borderDownColor: '#1a75ff', wickUpColor: '#737375', wickDownColor: '#737375', }, diff --git a/packages/frontend/src/utils/getHistogramColorData.ts b/packages/frontend/src/utils/getHistogramColorData.ts index 397144ee..d3b98029 100644 --- a/packages/frontend/src/utils/getHistogramColorData.ts +++ b/packages/frontend/src/utils/getHistogramColorData.ts @@ -1,19 +1,14 @@ -import resolveConfig from 'tailwindcss/resolveConfig'; -import tailwindConfig from '@/../tailwind.config'; - 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; + ? '#ff4d4d' + : '#1a75ff'; return { ...item, color }; }); diff --git a/packages/frontend/tailwind.config.ts b/packages/frontend/tailwind.config.ts index 10590b9f..883d3320 100644 --- a/packages/frontend/tailwind.config.ts +++ b/packages/frontend/tailwind.config.ts @@ -1,24 +1,26 @@ -import type { Config } from 'tailwindcss' +import type { Config } from 'tailwindcss'; const config: Config = { content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], + darkMode: 'selector', theme: { extend: {}, colors: { - 'light-gray': '#d9d9d9', - gray: '#8c8c8c', - 'dark-gray': '#4f4f4f', - black: '#000000', - white: '#ffffff', - 'light-yellow': '#ffdcac', - 'light-orange': '#ffcfac', - orange: '#ffa868', - red: '#ff4d4d', - green: '#7eeb7e', - blue: '#1a75ff', + 'extra-light-gray': 'var(--extra-light-gray)', + 'light-gray': 'var(--light-gray)', + gray: 'var(--gray)', + 'dark-gray': 'var(--dark-gray)', + black: 'var(--black)', + white: 'var(--white)', + 'light-yellow': 'var(--light-yellow)', + 'light-orange': 'var(--light-orange)', + orange: 'var(--orange)', + red: 'var(--red)', + green: 'var(--green)', + blue: 'var(--blue)', }, }, plugins: [], -} +}; -export default config \ No newline at end of file +export default config;