From c38b8dbcc0921be2e4075d534d19cd132dab5cec Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 03:25:03 +0900 Subject: [PATCH 01/20] =?UTF-8?q?:lipstick:=20design:=20semantic=20negativ?= =?UTF-8?q?e=20hex=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grass-diary/src/styles/semantic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grass-diary/src/styles/semantic.ts b/grass-diary/src/styles/semantic.ts index 215af460..018f362d 100644 --- a/grass-diary/src/styles/semantic.ts +++ b/grass-diary/src/styles/semantic.ts @@ -115,7 +115,7 @@ export const semantic = { inverse: { solid: { accent: '#00A66E' as HexColor, - negative: '#F17961' as HexColor, + negative: '#D93526' as HexColor, hero: '#ffffff' as HexColor, normal: '#E2E2E2' as HexColor, bg: '#2B2B2B' as HexColor, From 15733b445ab55267f8cf10c0163a26a51b04d961 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 03:26:12 +0900 Subject: [PATCH 02/20] =?UTF-8?q?:sparkles:=20feat:=20useTheme=20custom=20?= =?UTF-8?q?hook=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grass-diary/src/hooks/useTheme.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 grass-diary/src/hooks/useTheme.ts diff --git a/grass-diary/src/hooks/useTheme.ts b/grass-diary/src/hooks/useTheme.ts new file mode 100644 index 00000000..b9318d3a --- /dev/null +++ b/grass-diary/src/hooks/useTheme.ts @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +const useTheme = () => { + const localTheme = localStorage.getItem('theme'); + const [isDarkMode, setIsDarkMode] = useState( + localTheme === 'dark' ? true : false, + ); + + const switchTheme = () => { + setIsDarkMode(prev => { + const changeTheme = !prev; + localStorage.setItem('theme', changeTheme ? 'dark' : 'light'); + + return changeTheme; + }); + }; + + return { isDarkMode, switchTheme }; +}; + +export default useTheme; From 2cd9aee81ccb5dbcdca8241b8cafcf6abdd2104b Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 03:28:23 +0900 Subject: [PATCH 03/20] =?UTF-8?q?:sparkles:=20feat:=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=8B=A4=ED=81=AC=20=EB=AA=A8?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grass-diary/src/constants/message.ts | 3 +- grass-diary/src/pages/Setting/Setting.tsx | 286 ++++++++++-------- .../src/styles/Setting/SettingStyles.ts | 38 ++- 3 files changed, 171 insertions(+), 156 deletions(-) diff --git a/grass-diary/src/constants/message.ts b/grass-diary/src/constants/message.ts index 79044f92..5894633c 100644 --- a/grass-diary/src/constants/message.ts +++ b/grass-diary/src/constants/message.ts @@ -128,7 +128,7 @@ export const SETTING_MESSAGES = { label: { nickname: '닉네임', email: '이메일 주소', - theme: '테마', + theme: '테마 변경', withdraw: '회원 탈퇴', }, message: { @@ -255,4 +255,3 @@ export const SNACKBAR = { page: '/rewardpage', }, } as const; - diff --git a/grass-diary/src/pages/Setting/Setting.tsx b/grass-diary/src/pages/Setting/Setting.tsx index 48394a1e..55e3bd9e 100644 --- a/grass-diary/src/pages/Setting/Setting.tsx +++ b/grass-diary/src/pages/Setting/Setting.tsx @@ -1,19 +1,23 @@ import React, { useState } from 'react'; +import { ThemeProvider } from 'styled-components'; import { QueryClient, useMutation, useQueryClient, } from '@tanstack/react-query'; -import * as S from '../../styles/Setting/SettingStyles'; import API from '@services/index'; +import useTheme from '@hooks/useTheme'; +import { semantic } from '@styles/semantic'; +import * as S from '@styles/Setting/SettingStyles'; import { Profile } from '@components/index'; -import { END_POINT } from '@constants/api'; -import { CONSOLE_ERROR, SETTING_MESSAGES } from '@constants/message'; import { useProfile } from '@state/profile/useProfile'; import { useProfileActions } from '@state/profile/ProfileStore'; +import { END_POINT } from '@constants/api'; +import { CONSOLE_ERROR, SETTING_MESSAGES } from '@constants/message'; const Setting = () => { + const { isDarkMode, switchTheme } = useTheme(); const queryClient: QueryClient = useQueryClient(); const { nickname, profileIntro }: omitProfileImageURL = useProfile(); const { setNickName, setProfileIntro } = useProfileActions(); @@ -49,144 +53,158 @@ const Setting = () => { }); return ( - - - - - - - - - - {nickname} - - - - {SETTING_MESSAGES.button.image('업로드')} - - - {SETTING_MESSAGES.button.image('삭제')} - - - - - - - - setIsFocused(true)} - onBlur={() => setIsFocused(false)} + + + + + + + + + + + {nickname} + + + + {SETTING_MESSAGES.button.image('업로드')} + + + {SETTING_MESSAGES.button.image('삭제')} + + + + + + + + setIsFocused(true)} + onBlur={() => setIsFocused(false)} + /> + + + + + + {profileIntro.length}/150자 + + + + + + + + + {SETTING_MESSAGES.label.nickname} + + {isEditingNickname ? ( + - - - - - - {profileIntro.length}/150자 - - - - - - - - - {SETTING_MESSAGES.label.nickname} - + ) : ( + {nickname} + )} + {isEditingNickname ? ( - + + updateProfile.mutate({ + nickname: editNickname, + profileIntro, + }) + } + > + {SETTING_MESSAGES.button.save} + ) : ( - {nickname} + setIsEditingNickname(true)}> + {SETTING_MESSAGES.button.amend} + )} - - {isEditingNickname ? ( - - updateProfile.mutate({ - nickname: editNickname, - profileIntro, - }) - } - > - {SETTING_MESSAGES.button.save} - - ) : ( - setIsEditingNickname(true)}> - {SETTING_MESSAGES.button.amend} - - )} - - - {SETTING_MESSAGES.message.nickname} - - - - - - - {SETTING_MESSAGES.label.email} - username@gmail.com - - - - {SETTING_MESSAGES.message.email} - - - {/* + + + {SETTING_MESSAGES.message.nickname} + + + + + + + + {SETTING_MESSAGES.label.email} + + username@gmail.com + + + + {SETTING_MESSAGES.message.email} + + + {/* */} - - - - {SETTING_MESSAGES.label.theme} + + + + {SETTING_MESSAGES.label.theme} + + {SETTING_MESSAGES.message.theme} + + + + + + + + + + + + {SETTING_MESSAGES.label.withdraw} + + + {SETTING_MESSAGES.button.withdraw} + + - {SETTING_MESSAGES.message.theme} + {SETTING_MESSAGES.message.withdraw} - - - - - - - - - - {SETTING_MESSAGES.label.withdraw} - - {SETTING_MESSAGES.button.withdraw} - - - - {SETTING_MESSAGES.message.withdraw} - - - - - updateProfile.mutate({ - nickname: nickname, - profileIntro: profileIntro, - }) - } - > - {SETTING_MESSAGES.button.apply} - - - {SETTING_MESSAGES.button.navigate} - - - - - - + + + + updateProfile.mutate({ + nickname: nickname, + profileIntro: profileIntro, + }) + } + > + {SETTING_MESSAGES.button.apply} + + + {SETTING_MESSAGES.button.navigate} + + + + + + + ); }; diff --git a/grass-diary/src/styles/Setting/SettingStyles.ts b/grass-diary/src/styles/Setting/SettingStyles.ts index 56ed2381..fea430f1 100644 --- a/grass-diary/src/styles/Setting/SettingStyles.ts +++ b/grass-diary/src/styles/Setting/SettingStyles.ts @@ -12,12 +12,7 @@ const SettingContainer = styled.main` min-width: 20rem; gap: 1.5rem; - background: linear-gradient( - 180deg, - rgba(255, 255, 255, 0.3) 0%, - rgba(241, 241, 241, 0.3) 100% - ), - ${semantic.light.bg.solid.subtler}; + background: ${({ theme }) => theme.bg.solid.subtler}; `; const ContentContainer = styled.div` @@ -110,7 +105,7 @@ const UserNameText = styled.span` text-align: center; ${TYPO.title2} - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; const ProfileButtonBox = styled.div` @@ -123,7 +118,7 @@ const ProfileButtonBox = styled.div` gap: 1.125rem; `; -const ImageUploadButton = styled.button` +const ImageUploadButton = styled.button<{ isDarkMode: boolean }>` display: flex; justify-content: center; align-items: center; @@ -136,13 +131,13 @@ const ImageUploadButton = styled.button` border-radius: 0.5rem; - color: ${semantic.light.base.solid.white}; - background: ${semantic.light.accent.solid.normal}; + background: ${({ theme }) => theme.accent.solid.normal}; + color: ${({ theme }) => theme.base.solid.white}; - ${INTERACTION.default.normal(semantic.light.accent.solid.normal)} + ${INTERACTION.default.normal(semantic.light.accent.solid.normal)}; `; -const ImageDeleteButton = styled.button` +const ImageDeleteButton = styled.button<{ isDarkMode: boolean }>` display: flex; justify-content: center; align-items: center; @@ -155,8 +150,9 @@ const ImageDeleteButton = styled.button` border-radius: 0.5rem; - color: ${semantic.light.base.solid.white}; - background: ${semantic.light.object.solid.normal}; + background: ${({ theme }) => theme.object.solid.normal}; + color: ${({ theme, isDarkMode }) => + isDarkMode ? theme.base.solid.black : theme.base.solid.white}; ${INTERACTION.default.normal(semantic.light.object.solid.normal)} `; @@ -206,7 +202,7 @@ const UserIntroductionBox = styled.div<{ isFocused: boolean }>` box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.04), 0px 2px 4px 0px rgba(0, 0, 0, 0.08); - background: ${semantic.light.bg.solid.normal}; + background: ${({ theme }) => theme.bg.solid.normal}; `; const UserIntroduction = styled.textarea` @@ -219,10 +215,12 @@ const UserIntroduction = styled.textarea` resize: none; outline: none; - ${TYPO.caption2} overflow: hidden; text-overflow: ellipsis; + + ${TYPO.caption2} color: ${semantic.light.object.transparent.neutral}; + background: ${({ theme }) => theme.bg.solid.normal}; `; const IntroductionCountText = styled.span` @@ -317,12 +315,12 @@ const SettingLabel = styled.label` width: 7rem; ${TYPO.title1} - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; const SettingText = styled.span` ${TYPO.label2} - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; const AmendButton = styled.button` @@ -343,7 +341,7 @@ const NicknameInput = styled.input` border-radius: 0.5rem; border: 1px solid ${semantic.light.border.transparent.alternative}; - background: #fff; + background: ${({ theme }) => theme.bg.solid.normal}; &:focus { border: 1px solid ${semantic.light.accent.solid.alternative}; @@ -383,7 +381,7 @@ const SettingMessage = styled.span` align-self: stretch; ${TYPO.caption1}; - color: ${semantic.light.object.transparent.neutral}; + color: ${({ theme }) => theme.object.transparent.neutral}; `; const DividerLine = styled.div` From ef4968648c465dcc7baae3db9418e6ba60276805 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 03:33:55 +0900 Subject: [PATCH 04/20] =?UTF-8?q?:fire:=20remove:=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=8A=A4=ED=83=80=EC=9D=BC=20props=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 --- grass-diary/src/styles/Setting/SettingStyles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grass-diary/src/styles/Setting/SettingStyles.ts b/grass-diary/src/styles/Setting/SettingStyles.ts index fea430f1..4dfece13 100644 --- a/grass-diary/src/styles/Setting/SettingStyles.ts +++ b/grass-diary/src/styles/Setting/SettingStyles.ts @@ -118,7 +118,7 @@ const ProfileButtonBox = styled.div` gap: 1.125rem; `; -const ImageUploadButton = styled.button<{ isDarkMode: boolean }>` +const ImageUploadButton = styled.button` display: flex; justify-content: center; align-items: center; From 18a7af6c5a384ee1b1b312b073787fbce598ef61 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 09:49:43 +0900 Subject: [PATCH 05/20] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=86=8C=EA=B0=9C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=8B=A4=ED=81=AC=20=EB=AA=A8?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../img => src/assets/svg}/banner_record.svg | 6 ++-- .../icons => src/assets/svg}/expand-more.svg | 2 +- grass-diary/src/pages/Intro/Intro.tsx | 20 +++++++++---- .../src/pages/Intro/introComponents.tsx | 16 ++++++++-- grass-diary/src/styles/Intro/IntroStyles.ts | 30 +++++++++---------- 5 files changed, 45 insertions(+), 29 deletions(-) rename grass-diary/{public/assets/img => src/assets/svg}/banner_record.svg (99%) rename grass-diary/{public/assets/icons => src/assets/svg}/expand-more.svg (76%) diff --git a/grass-diary/public/assets/img/banner_record.svg b/grass-diary/src/assets/svg/banner_record.svg similarity index 99% rename from grass-diary/public/assets/img/banner_record.svg rename to grass-diary/src/assets/svg/banner_record.svg index e3322b9d..641ffc46 100644 --- a/grass-diary/public/assets/img/banner_record.svg +++ b/grass-diary/src/assets/svg/banner_record.svg @@ -4,10 +4,10 @@ - - + + - + diff --git a/grass-diary/public/assets/icons/expand-more.svg b/grass-diary/src/assets/svg/expand-more.svg similarity index 76% rename from grass-diary/public/assets/icons/expand-more.svg rename to grass-diary/src/assets/svg/expand-more.svg index 0970b8e1..e0b25c01 100644 --- a/grass-diary/public/assets/icons/expand-more.svg +++ b/grass-diary/src/assets/svg/expand-more.svg @@ -1,5 +1,5 @@ - + diff --git a/grass-diary/src/pages/Intro/Intro.tsx b/grass-diary/src/pages/Intro/Intro.tsx index 388d0a3c..2efe8976 100644 --- a/grass-diary/src/pages/Intro/Intro.tsx +++ b/grass-diary/src/pages/Intro/Intro.tsx @@ -1,4 +1,8 @@ +import { ThemeProvider } from 'styled-components'; + import * as S from '@styles/Intro/IntroStyles'; +import { semantic } from '@styles/semantic'; +import useTheme from '@hooks/useTheme'; import { FirstSection, LastSection, @@ -7,13 +11,17 @@ import { } from './introComponents'; const Intro = () => { + const { isDarkMode } = useTheme(); + return ( - - - - - - + + + + + + + + ); }; diff --git a/grass-diary/src/pages/Intro/introComponents.tsx b/grass-diary/src/pages/Intro/introComponents.tsx index 25e92b38..6e179a26 100644 --- a/grass-diary/src/pages/Intro/introComponents.tsx +++ b/grass-diary/src/pages/Intro/introComponents.tsx @@ -5,12 +5,16 @@ import { useModal } from '@state/modal/useModal'; import { checkAuth } from '@utils/authUtils'; import * as S from '@styles/Intro/IntroStyles'; +import useTheme from '@hooks/useTheme'; +import useIsMobile from '@hooks/useIsMobile'; import { Divider } from '@components/index'; import { INTRO_MESSAGES } from '@constants/message'; -import useIsMobile from '@hooks/useIsMobile'; +import { ReactComponent as ScrollIcon } from '@svg/expand-more.svg'; +import { ReactComponent as RecordImage } from '@svg/banner_record.svg'; const OpenModalButton = () => { const navigate: NavigateFunction = useNavigate(); + const { loginModal } = useModal(); const [isLoggedIn, setIsLoggedIn] = useState(false); @@ -45,6 +49,7 @@ const OpenModalButton = () => { const FirstSection = () => { const isMobile = useIsMobile(); + const { isDarkMode } = useTheme(); return ( <> @@ -64,7 +69,11 @@ const FirstSection = () => { {INTRO_MESSAGES.firstSection.scrollMessage(isMobile)} - + ); @@ -72,6 +81,7 @@ const FirstSection = () => { const SecondSection = () => { const isMobile = useIsMobile(); + const { isDarkMode } = useTheme(); return ( @@ -86,7 +96,7 @@ const SecondSection = () => { {INTRO_MESSAGES.secondSection.secondIntroduction(isMobile)} - + ); diff --git a/grass-diary/src/styles/Intro/IntroStyles.ts b/grass-diary/src/styles/Intro/IntroStyles.ts index 2f8ac0e4..7292d0e5 100644 --- a/grass-diary/src/styles/Intro/IntroStyles.ts +++ b/grass-diary/src/styles/Intro/IntroStyles.ts @@ -1,16 +1,20 @@ +import styled from 'styled-components'; + import { INTERACTION } from '@styles/interaction'; import { semantic } from '@styles/semantic'; import { TYPO } from '@styles/typo'; -import styled from 'styled-components'; -const IntroContainer = styled.main` +const IntroContainer = styled.main<{ isDarkMode: boolean }>` display: flex; flex-direction: column; align-items: center; min-width: 20rem; - background: linear-gradient(180deg, #fff 0%, #ebebeb 100%); + background: ${({ isDarkMode }) => + isDarkMode + ? 'linear-gradient(180deg, #2B2B2B 0%, #1B1B1B 100%)' + : 'linear-gradient(180deg, #fff 0%, #ebebeb 100%)'}; `; const CommonSection = styled.section` @@ -71,7 +75,7 @@ const LogoImg = styled.img` const MainTitle = styled.h2` ${TYPO.display2}; - color: ${semantic.light.object.solid.hero}; + color: ${({ theme }) => theme.object.solid.hero}; `; const MainIntrouctionText = styled.small` @@ -79,7 +83,7 @@ const MainIntrouctionText = styled.small` text-align: center; ${TYPO.title1} - color: ${semantic.light.object.transparent.alternative}; + color: ${({ theme }) => theme.object.transparent.alternative}; `; /** common login button */ @@ -130,17 +134,12 @@ const ScrollMessageContainer = styled.div` gap: 0.5rem; `; -const ScrollText = styled.small` +const ScrollText = styled.p` align-self: stretch; - text-align: center; - ${TYPO.label2} - color: ${semantic.light.object.transparent.alternative}; -`; -const ScrollImg = styled.img` - width: 1.25rem; - height: 1.25rem; + ${TYPO.label2} + color: ${({ theme }) => theme.object.transparent.alternative}; `; /** second section */ @@ -171,14 +170,14 @@ const CommonTitle = styled.h1` text-align: center; ${TYPO.title3} - color: ${semantic.light.object.solid.hero}; + color: ${({ theme }) => theme.object.solid.hero}; `; const CommonIntroductionText = styled.p` text-align: center; ${TYPO.label3} - color: ${semantic.light.object.transparent.alternative}; + color:${({ theme }) => theme.object.transparent.alternative}; `; const HighlightText = styled.span` @@ -248,7 +247,6 @@ export { ButtonText, ScrollMessageContainer, ScrollText, - ScrollImg, CommonArticle, CommonTitleContainer, CommonTitle, From 9423e0fe33aacb5e418a3615d9082b631c667063 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 11:40:35 +0900 Subject: [PATCH 06/20] =?UTF-8?q?:sparkles:=20feat:=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=8B=A4=ED=81=AC=20=EB=AA=A8?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/svg}/icon-btn-chevron-left.svg | 2 +- .../assets/svg}/icon-btn-chevron-right.svg | 2 +- .../assets/svg}/icon-btn-first-page.svg | 2 +- .../assets/svg}/icon-btn-last-page.svg | 2 +- grass-diary/src/components/Divider.tsx | 7 +- grass-diary/src/pages/MyPage/Diary.tsx | 26 +++++--- grass-diary/src/pages/MyPage/Grass.tsx | 11 +++- grass-diary/src/pages/MyPage/MyPage.tsx | 13 +++- grass-diary/src/pages/MyPage/myComponents.tsx | 4 +- grass-diary/src/styles/MyPage/MyStyles.ts | 64 +++++++++---------- 10 files changed, 75 insertions(+), 58 deletions(-) rename grass-diary/{public/assets/icons => src/assets/svg}/icon-btn-chevron-left.svg (80%) rename grass-diary/{public/assets/icons => src/assets/svg}/icon-btn-chevron-right.svg (78%) rename grass-diary/{public/assets/icons => src/assets/svg}/icon-btn-first-page.svg (90%) rename grass-diary/{public/assets/icons => src/assets/svg}/icon-btn-last-page.svg (90%) diff --git a/grass-diary/public/assets/icons/icon-btn-chevron-left.svg b/grass-diary/src/assets/svg/icon-btn-chevron-left.svg similarity index 80% rename from grass-diary/public/assets/icons/icon-btn-chevron-left.svg rename to grass-diary/src/assets/svg/icon-btn-chevron-left.svg index 76053fa4..1be4742a 100644 --- a/grass-diary/public/assets/icons/icon-btn-chevron-left.svg +++ b/grass-diary/src/assets/svg/icon-btn-chevron-left.svg @@ -1,5 +1,5 @@ - + diff --git a/grass-diary/public/assets/icons/icon-btn-chevron-right.svg b/grass-diary/src/assets/svg/icon-btn-chevron-right.svg similarity index 78% rename from grass-diary/public/assets/icons/icon-btn-chevron-right.svg rename to grass-diary/src/assets/svg/icon-btn-chevron-right.svg index 9faa6e06..0afdc26c 100644 --- a/grass-diary/public/assets/icons/icon-btn-chevron-right.svg +++ b/grass-diary/src/assets/svg/icon-btn-chevron-right.svg @@ -1,5 +1,5 @@ - + diff --git a/grass-diary/public/assets/icons/icon-btn-first-page.svg b/grass-diary/src/assets/svg/icon-btn-first-page.svg similarity index 90% rename from grass-diary/public/assets/icons/icon-btn-first-page.svg rename to grass-diary/src/assets/svg/icon-btn-first-page.svg index d94a940a..d631acc6 100644 --- a/grass-diary/public/assets/icons/icon-btn-first-page.svg +++ b/grass-diary/src/assets/svg/icon-btn-first-page.svg @@ -1,5 +1,5 @@ - + diff --git a/grass-diary/public/assets/icons/icon-btn-last-page.svg b/grass-diary/src/assets/svg/icon-btn-last-page.svg similarity index 90% rename from grass-diary/public/assets/icons/icon-btn-last-page.svg rename to grass-diary/src/assets/svg/icon-btn-last-page.svg index 2bbea4d6..ef9f986e 100644 --- a/grass-diary/public/assets/icons/icon-btn-last-page.svg +++ b/grass-diary/src/assets/svg/icon-btn-last-page.svg @@ -1,5 +1,5 @@ - + diff --git a/grass-diary/src/components/Divider.tsx b/grass-diary/src/components/Divider.tsx index 93e6d4f3..e9d3de55 100644 --- a/grass-diary/src/components/Divider.tsx +++ b/grass-diary/src/components/Divider.tsx @@ -1,4 +1,3 @@ -import { semantic } from '@styles/semantic'; import styled from 'styled-components'; interface IDividerProps { @@ -19,8 +18,6 @@ const DividerLine = styled.div<{ width: ${({ $dividerWidth }) => $dividerWidth || '20rem'}; height: 0.0625rem; - background: ${({ $dividerColor }) => - $dividerColor - ? $dividerColor - : `${semantic.light.border.transparent.neutral}`}; + background: ${({ $dividerColor, theme }) => + $dividerColor ? $dividerColor : `${theme.border.transparent.neutral}`}; `; diff --git a/grass-diary/src/pages/MyPage/Diary.tsx b/grass-diary/src/pages/MyPage/Diary.tsx index 5a1d4ebc..04290115 100644 --- a/grass-diary/src/pages/MyPage/Diary.tsx +++ b/grass-diary/src/pages/MyPage/Diary.tsx @@ -5,16 +5,21 @@ import { useState, useEffect } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useNavigate, useSearchParams } from 'react-router-dom'; -import API from '@services/index'; - -import { semantic } from '@styles/semantic'; -import useDiary from '@hooks/api/useDiary'; -import { useUser } from '@state/user/useUser'; import { ReactComponent as FavoriteIcon } from '@svg/favorite.svg'; import { ReactComponent as CommentIcon } from '@svg/comment.svg'; -import { MoodProfile, Profile, Divider } from '@components/index'; +import { ReactComponent as FirstPage } from '@svg/icon-btn-first-page.svg'; +import { ReactComponent as LastPage } from '@svg/icon-btn-last-page.svg'; +import { ReactComponent as PreviousPage } from '@svg/icon-btn-chevron-left.svg'; +import { ReactComponent as NextPage } from '@svg/icon-btn-chevron-right.svg'; + +import API from '@services/index'; +import useDiary from '@hooks/api/useDiary'; import Setting from '@pages/DiaryDetail/Setting'; +import { semantic } from '@styles/semantic'; +import { useUser } from '@state/user/useUser'; import { END_POINT } from '@constants/api'; +import { MoodProfile, Profile, Divider } from '@components/index'; +import useTheme from '@hooks/useTheme'; interface IPagination { pageSize: number; @@ -23,6 +28,7 @@ interface IPagination { } const Pagination = ({ pageSize, currentPage, onPageChange }: IPagination) => { + const { isDarkMode } = useTheme(); const handleFirstPage = () => onPageChange(0); const handlePreviousPage = () => { @@ -40,10 +46,10 @@ const Pagination = ({ pageSize, currentPage, onPageChange }: IPagination) => { return ( - + - + {Array.from({ length: pageSize }, (_, index) => ( onPageChange(index)}> @@ -51,10 +57,10 @@ const Pagination = ({ pageSize, currentPage, onPageChange }: IPagination) => { ))} - + - + ); diff --git a/grass-diary/src/pages/MyPage/Grass.tsx b/grass-diary/src/pages/MyPage/Grass.tsx index c400cde0..7b9c6a10 100644 --- a/grass-diary/src/pages/MyPage/Grass.tsx +++ b/grass-diary/src/pages/MyPage/Grass.tsx @@ -33,10 +33,11 @@ const createGrass: TCreateGrass = () => { }; interface IGrass { + isDarkMode: boolean; setSelectedDiary: React.Dispatch>; } -const Grass = ({ setSelectedDiary }: IGrass) => { +const Grass = ({ setSelectedDiary, isDarkMode }: IGrass) => { const memberId = useUser(); const grassColors = useGrass(memberId); const { year, grass } = createGrass(); @@ -102,12 +103,18 @@ const Grass = ({ setSelectedDiary }: IGrass) => { onMouseOut={() => handleGrassHover(null)} $border={ !writeDay - ? `1px solid ${semantic.light.accent.solid.normal}` + ? isDarkMode + ? `1px solid ${semantic.dark.accent.solid.normal}` + : `1px solid ${semantic.light.accent.solid.normal}` + : isDarkMode + ? `1px solid ${semantic.dark.border.transparent.alternative}` : `1px solid ${semantic.light.border.transparent.alternative}` } $background={ grassColors[writeDay] ? `rgba(${grassColors[writeDay]})` + : isDarkMode + ? `${semantic.dark.fill.transparent.assistive}` : `${semantic.light.fill.transparent.assistive}` } /> diff --git a/grass-diary/src/pages/MyPage/MyPage.tsx b/grass-diary/src/pages/MyPage/MyPage.tsx index b06c2c99..28da5c3e 100644 --- a/grass-diary/src/pages/MyPage/MyPage.tsx +++ b/grass-diary/src/pages/MyPage/MyPage.tsx @@ -1,11 +1,18 @@ import { MainContainer } from './myComponents'; import * as S from '../../styles/MyPage/MyStyles'; +import { ThemeProvider } from 'styled-components'; +import { semantic } from '@styles/semantic'; +import useTheme from '@hooks/useTheme'; const MyPage = () => { + const { isDarkMode } = useTheme(); + return ( - - - + + + + + ); }; diff --git a/grass-diary/src/pages/MyPage/myComponents.tsx b/grass-diary/src/pages/MyPage/myComponents.tsx index f9e44ea8..45ef16f2 100644 --- a/grass-diary/src/pages/MyPage/myComponents.tsx +++ b/grass-diary/src/pages/MyPage/myComponents.tsx @@ -6,6 +6,7 @@ import Diary from './Diary'; import * as S from '../../styles/MyPage/MyStyles'; import { EllipsisBox, EllipsisIcon, Profile } from '@components/index'; import { useProfile } from '@state/profile/useProfile'; +import useTheme from '@hooks/useTheme'; const MainContainer = () => { const navigate = useNavigate(); @@ -58,6 +59,7 @@ interface IProfileSection { } const ProfileSection = ({ setSelectedDiary }: IProfileSection) => { + const { isDarkMode } = useTheme(); const { nickname, profileIntro } = useProfile(); return ( @@ -73,7 +75,7 @@ const ProfileSection = ({ setSelectedDiary }: IProfileSection) => { 2024년 잔디 현황 - + ); diff --git a/grass-diary/src/styles/MyPage/MyStyles.ts b/grass-diary/src/styles/MyPage/MyStyles.ts index 4e6f0691..5f4b3cde 100644 --- a/grass-diary/src/styles/MyPage/MyStyles.ts +++ b/grass-diary/src/styles/MyPage/MyStyles.ts @@ -1,22 +1,19 @@ import styled, { css } from 'styled-components'; import { TYPO } from '@styles/typo'; -import { semantic } from '@styles/semantic'; import { INTERACTION } from '@styles/interaction'; -export const SettingContainer = styled.div` +export const SettingContainer = styled.div<{ isDarkMode: boolean }>` display: flex; flex-direction: column; align-items: center; min-width: 20rem; - background: linear-gradient( - 180deg, - rgba(255, 255, 255, 0.3) 0%, - rgba(241, 241, 241, 0.3) 100% - ), - ${semantic.light.bg.solid.subtler}; + background: ${({ isDarkMode }) => + isDarkMode + ? 'linear-gradient(180deg, #2B2B2B 0%, #1B1B1B 100%)' + : 'linear-gradient(180deg, #fff 0%, #ebebeb 100%)'}; `; export const ViewportContainer = styled.div` @@ -49,14 +46,14 @@ export const UserNameText = styled.span` text-align: center; ${TYPO.title2}; - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; export const UserInfoText = styled.span` text-align: center; ${TYPO.body2}; - color: ${semantic.light.object.transparent.neutral}; + color: ${({ theme }) => theme.object.transparent.neutral}; `; /* 잔디 컨테이너 */ @@ -80,15 +77,15 @@ export const GrassYearTagBox = styled.div` padding: 0.5rem 1rem; border-radius: 0.75rem; - border: 1px solid ${semantic.light.border.transparent.alternative}; - background: ${semantic.light.fill.transparent.assistive}; + border: ${({ theme }) => `1px solid ${theme.border.transparent.alternative}`}; + background: ${({ theme }) => theme.fill.transparent.assistive}; `; export const GrassYearText = styled.span` text-align: center; ${TYPO.label2}; - color: ${semantic.light.object.transparent.alternative}; + color: ${({ theme }) => theme.object.transparent.alternative}; `; export const GrassContainer = styled.div` @@ -162,10 +159,10 @@ export const DateBubbleBox = styled.div` ${TYPO.label1}; text-align: center; - color: ${semantic.light.inverse.solid.normal}; + color: ${({ theme }) => theme.inverse.solid.normal}; border-radius: 0.75rem; - background: ${semantic.light.inverse.solid.bg}; + background: ${({ theme }) => theme.inverse.solid.bg}; box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.06), @@ -205,6 +202,7 @@ export const MainSection = styled.section` position: relative; max-width: 60rem; + min-height: 20.8rem; padding: 0rem 1.5rem 4.5rem 1.5rem; `; @@ -230,8 +228,8 @@ export const SearchBox = styled.div` padding: 1rem 1.25rem; border-radius: 1rem; - border: 1px solid ${semantic.light.border.transparent.alternative}; - background: ${semantic.light.bg.solid.normal}; + border: ${({ theme }) => `1px solid ${theme.border.transparent.alternative}`}; + background: ${({ theme }) => theme.bg.solid.normal}; @media screen and (max-width: 60em) { padding: 0.625rem 1rem; @@ -250,7 +248,7 @@ export const SearchInput = styled.input` width: 100%; ${TYPO.body2}; - color: ${semantic.light.object.transparent.assistive}; + color: ${({ theme }) => theme.object.transparent.assistive}; border: none; @@ -316,8 +314,8 @@ export const DiaryCardArticle = styled.article` padding: 1.25rem; border-radius: 1rem; - border: 1px solid ${semantic.light.border.transparent.assistive}; - background: ${semantic.light.bg.solid.normal}; + border: ${({ theme }) => `1px solid ${theme.border.transparent.assistive}`}; + background: ${({ theme }) => theme.bg.solid.normal}; box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.04), @@ -345,12 +343,12 @@ export const DiaryCardDateBox = styled.div` export const DiaryCardDateText = styled.span` ${TYPO.label1}; - color: ${semantic.light.object.transparent.neutral}; + color: ${({ theme }) => theme.object.transparent.neutral}; `; export const DiaryCardTimeText = styled.small` ${TYPO.caption1}; - color: ${semantic.light.object.transparent.assistive}; + color: ${({ theme }) => theme.object.transparent.assistive}; `; export const DiaryCardMoreBox = styled.div` @@ -385,7 +383,7 @@ export const DiaryCardText = styled.span` text-overflow: ellipsis; ${TYPO.body2}; - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; export const DiaryCardBottomBox = styled.div` @@ -417,8 +415,8 @@ export const HashtagBox = styled.div` padding: 0.25rem 0.625rem; border-radius: 0.5rem; - border: 1px solid ${semantic.light.border.transparent.alternative}; - background: ${semantic.light.fill.transparent.assistive}; + border: ${({ theme }) => `1px solid ${theme.border.transparent.alternative}`}; + background: ${({ theme }) => theme.fill.transparent.assistive}; `; export const HashtagImg = styled.img` @@ -428,7 +426,7 @@ export const HashtagImg = styled.img` export const HashtagText = styled.span` ${TYPO.caption1}; - color: ${semantic.light.object.transparent.alternative}; + color: ${({ theme }) => theme.object.transparent.alternative}; `; export const CommentFavoriteBox = styled.div` @@ -448,7 +446,7 @@ export const DiaryCardItemBox = styled.div` export const DiaryCardItemText = styled.span` ${TYPO.label3}; - color: ${semantic.light.object.transparent.assistive}; + color: ${({ theme }) => theme.object.transparent.assistive}; `; /* 페이지네이션 컴포넌트 */ @@ -499,8 +497,8 @@ export const HashtagAside = styled.aside` gap: 1rem; border-radius: 1rem; - border: 1px solid ${semantic.light.border.transparent.assistive}; - background: ${semantic.light.bg.solid.normal}; + border: ${({ theme }) => `1px solid ${theme.border.transparent.assistive}`}; + background: ${({ theme }) => theme.bg.solid.normal}; box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.04), @@ -516,7 +514,7 @@ export const HashtagListText = styled.span` height: 1.375rem; ${TYPO.label2}; - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; `; export const SideHashtagListBox = styled.ul` @@ -553,13 +551,13 @@ export const SideHashtagList = styled.li` export const SideHashtagText = styled.span<{ $variant?: boolean }>` ${TYPO.label1}; - color: ${semantic.light.object.solid.normal}; + color: ${({ theme }) => theme.object.solid.normal}; text-align: center; ${({ $variant }) => { if ($variant) { return css` - color: ${semantic.light.accent.solid.hero}; + color: ${({ theme }) => theme.accent.solid.hero}; `; } }} @@ -567,5 +565,5 @@ export const SideHashtagText = styled.span<{ $variant?: boolean }>` export const SideHashtagUsageText = styled.span` ${TYPO.label1}; - color: ${semantic.light.object.transparent.assistive}; + color: ${({ theme }) => theme.object.transparent.assistive}; `; From f4e628f240e76681358a4d6078fd5add1c4514a3 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 12:30:00 +0900 Subject: [PATCH 07/20] =?UTF-8?q?:sparkles:=20feat:=20header=20component?= =?UTF-8?q?=20=EB=8B=A4=ED=81=AC=20=EB=AA=A8=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grass-diary/src/components/Layout/Header.tsx | 52 +++++++++++-------- .../styles/component/Button/Menu.style.tsx | 2 +- .../styles/component/Button/Menus.style.tsx | 9 ++-- .../styles/component/Layout/Header.style.tsx | 19 +++---- 4 files changed, 46 insertions(+), 36 deletions(-) diff --git a/grass-diary/src/components/Layout/Header.tsx b/grass-diary/src/components/Layout/Header.tsx index 03cac254..6a1bcd96 100644 --- a/grass-diary/src/components/Layout/Header.tsx +++ b/grass-diary/src/components/Layout/Header.tsx @@ -1,37 +1,45 @@ -import * as S from '@styles/component/Layout/Header.style'; -import sampleLogo from '@image/sampleLogo.png'; +import { useNavigate } from 'react-router-dom'; +import { ThemeProvider } from 'styled-components'; + import MenuBar from './MenuBar'; +import sampleLogo from '@image/sampleLogo.png'; +import useTheme from '@hooks/useTheme'; +import * as S from '@styles/component/Layout/Header.style'; +import { semantic } from '@styles/semantic'; import { Profile } from '@components/index'; -import { useNavigate } from 'react-router-dom'; import { useUser } from '@state/user/useUser'; const Header = () => { const memberId = useUser(); const navigate = useNavigate(); + const { isDarkMode } = useTheme(); + const handleGoogleLogin: TGoogleLogin = () => { window.open(`http://localhost:8080/api/auth/google`, '_self'); }; return ( - - - - navigate('/main')}> - - - - - navigate('/share')}>피드 - {memberId ? ( - - - - - ) : ( - 로그인 - )} - - + + + + + navigate('/main')}> + + + + + navigate('/share')}>피드 + {memberId ? ( + + + + + ) : ( + 로그인 + )} + + + ); }; diff --git a/grass-diary/src/styles/component/Button/Menu.style.tsx b/grass-diary/src/styles/component/Button/Menu.style.tsx index 842c9a58..1ea23e1a 100644 --- a/grass-diary/src/styles/component/Button/Menu.style.tsx +++ b/grass-diary/src/styles/component/Button/Menu.style.tsx @@ -15,7 +15,7 @@ export const MenuBox = styled.div` export const MenuText = styled.p<{ color?: string }>` ${TYPO.label2}; flex: 1 0 0; - color: ${props => props.color || semantic.light.object.solid.normal}; + color: ${props => props.color || props.theme.object.solid.normal}; text-align: left; `; diff --git a/grass-diary/src/styles/component/Button/Menus.style.tsx b/grass-diary/src/styles/component/Button/Menus.style.tsx index 1127cae7..af3b09a1 100644 --- a/grass-diary/src/styles/component/Button/Menus.style.tsx +++ b/grass-diary/src/styles/component/Button/Menus.style.tsx @@ -1,5 +1,4 @@ import styled from 'styled-components'; -import { semantic } from '@styles/semantic'; import { INTERACTION } from '@styles/interaction'; export const MenusWrapper = styled.div` @@ -25,10 +24,12 @@ export const MenusNav = styled.nav<{ $toggle: boolean }>` align-items: flex-start; border-radius: var(--radius-md, 1rem); - background: ${semantic.light.bg.solid.normal}; + background: ${({ theme }) => theme.bg.solid.normal}; - box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.06), - 0px 2px 4px 0px rgba(0, 0, 0, 0.06), 0px 4px 8px 0px rgba(0, 0, 0, 0.13); + box-shadow: + 0px 0px 2px 0px rgba(0, 0, 0, 0.06), + 0px 2px 4px 0px rgba(0, 0, 0, 0.06), + 0px 4px 8px 0px rgba(0, 0, 0, 0.13); position: absolute; top: 0; diff --git a/grass-diary/src/styles/component/Layout/Header.style.tsx b/grass-diary/src/styles/component/Layout/Header.style.tsx index 4b021d7f..633881a8 100644 --- a/grass-diary/src/styles/component/Layout/Header.style.tsx +++ b/grass-diary/src/styles/component/Layout/Header.style.tsx @@ -11,12 +11,12 @@ export const FeedButton = styled.button` justify-content: center; align-items: center; border-radius: var(--radius-xs, 0.5rem); - color: ${semantic.light.object.solid.normal}; text-align: center; white-space: nowrap; - ${TYPO.title1} + ${TYPO.title1} ${INTERACTION.default.normal()} + color: ${({ theme }) => theme.object.solid.normal}; `; export const Header = styled.header` @@ -27,9 +27,9 @@ export const Header = styled.header` justify-content: center; align-items: center; - border-bottom: var(--stroke-thin, 1px) solid - ${semantic.light.border.transparent.alternative}; - background: ${semantic.light.bg.solid.subtlest}; + border-bottom: ${({ theme }) => `var(--stroke-thin, 1px) solid + ${theme.border.transparent.alternative}`}; + background: ${({ theme }) => theme.bg.solid.subtlest}; @media screen and (max-width: 60em) { min-width: 20em; @@ -66,7 +66,7 @@ export const LogoImage = styled.img` export const LogoIcon = styled(LogoSVG)` width: 4.47663rem; height: 1.125rem; - fill: ${semantic.light.object.solid.normal}; + fill: ${({ theme }) => theme.object.solid.normal}; `; export const MenuBarBox = styled.div` @@ -82,10 +82,11 @@ export const LoginButton = styled.button` justify-content: center; align-items: center; + white-space: nowrap; gap: var(--gap-2xs, 0.5rem); - color: ${semantic.light.base.solid.white}; border-radius: var(--radius-xs, 0.5rem); - background: ${semantic.light.accent.solid.normal}; - white-space: nowrap; + + color: ${({ theme }) => theme.base.solid.white}; + background: ${({ theme }) => theme.accent.solid.normal}; ${INTERACTION.default.normal(semantic.light.accent.solid.normal)} `; From 32aa31ed507f9f3e2a5192676014f770a2f1c3a5 Mon Sep 17 00:00:00 2001 From: ccconac Date: Mon, 23 Sep 2024 13:06:50 +0900 Subject: [PATCH 08/20] =?UTF-8?q?:hammer:=20fix:=20layout=20theme=20provid?= =?UTF-8?q?er=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- grass-diary/src/components/Layout/Header.tsx | 44 +++++++++----------- grass-diary/src/components/Layout/Layout.tsx | 9 +++- grass-diary/src/pages/MyPage/MyPage.tsx | 10 ++--- grass-diary/src/pages/Setting/Setting.tsx | 2 +- grass-diary/src/styles/MyPage/MyStyles.ts | 8 ---- 5 files changed, 30 insertions(+), 43 deletions(-) diff --git a/grass-diary/src/components/Layout/Header.tsx b/grass-diary/src/components/Layout/Header.tsx index 6a1bcd96..f83afdf6 100644 --- a/grass-diary/src/components/Layout/Header.tsx +++ b/grass-diary/src/components/Layout/Header.tsx @@ -1,45 +1,39 @@ import { useNavigate } from 'react-router-dom'; -import { ThemeProvider } from 'styled-components'; import MenuBar from './MenuBar'; import sampleLogo from '@image/sampleLogo.png'; -import useTheme from '@hooks/useTheme'; import * as S from '@styles/component/Layout/Header.style'; -import { semantic } from '@styles/semantic'; import { Profile } from '@components/index'; import { useUser } from '@state/user/useUser'; const Header = () => { const memberId = useUser(); const navigate = useNavigate(); - const { isDarkMode } = useTheme(); const handleGoogleLogin: TGoogleLogin = () => { window.open(`http://localhost:8080/api/auth/google`, '_self'); }; return ( - - - - - navigate('/main')}> - - - - - navigate('/share')}>피드 - {memberId ? ( - - - - - ) : ( - 로그인 - )} - - - + + + + navigate('/main')}> + + + + + navigate('/share')}>피드 + {memberId ? ( + + + + + ) : ( + 로그인 + )} + + ); }; diff --git a/grass-diary/src/components/Layout/Layout.tsx b/grass-diary/src/components/Layout/Layout.tsx index 2a845ce1..72b94a79 100644 --- a/grass-diary/src/components/Layout/Layout.tsx +++ b/grass-diary/src/components/Layout/Layout.tsx @@ -3,17 +3,22 @@ import Header from './Header'; import Footer from './Footer'; import SnackBar from './SnackBar'; import { Toast, Modal } from '@components/index'; +import { ThemeProvider } from 'styled-components'; +import { semantic } from '@styles/semantic'; +import useTheme from '@hooks/useTheme'; const Layout = () => { + const { isDarkMode } = useTheme(); + return ( - <> +