Skip to content

Commit

Permalink
merge me
Browse files Browse the repository at this point in the history
  • Loading branch information
imsoohyeok committed Jun 15, 2024
2 parents 48824e5 + 75f382b commit 7ab4836
Show file tree
Hide file tree
Showing 50 changed files with 614 additions and 233 deletions.
21 changes: 21 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<!-- SEO 메타 태그 -->
<meta name="description" content="Taskify는 일의 우선순위를 정해 효율적으로 관리할 수 있도록 도와주는 일정 관리 서비스 입니다." />
<meta name="keywords" content="Taskify, 작업 관리, 일정, 할 일 목록, 생산성 도구" />
<meta name="author" content="codeit-5-8" />

<!-- Open Graph 메타 태그 (소셜 미디어) -->
<meta property="og:title" content="Taskify" />
<meta property="og:description" content="Taskify는 일의 우선순위를 정해 효율적으로 관리할 수 있도록 도와주는 일정 관리 서비스 입니다." />
<meta property="og:image" content="https://i.ibb.co/dQp7gY8/desktop.png" />
<!-- <meta property="og:url" content="배포 시 변경" /> -->
<meta property="og:type" content="website" />

<!-- Twitter 메타 태그 -->
<meta name="twitter:card" content="https://i.ibb.co/dQp7gY8/desktop.png" />
<meta name="twitter:title" content="Taskify" />
<meta name="twitter:description" content="Taskify는 일의 우선순위를 정해 효율적으로 관리할 수 있도록 도와주는 일정 관리 서비스 입니다." />
<meta name="twitter:image" content="https://yourdomain.com/path/to/image.jpg" />

<!-- Google Fonts 및 Pretendard 폰트 -->
<link
rel="stylesheet"
as="style"
Expand All @@ -16,6 +36,7 @@
href="https://fonts.googleapis.com/css2?family=Abel&family=Acme&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Noto+Sans+KR:[email protected]&display=swap"
rel="stylesheet"
/>

<title>Taskify</title>
</head>
<body>
Expand Down
3 changes: 3 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SignUp from './pages/login-signup/signup/SignUp';
import MyPage from './pages/mypage/MyPage';
import { DashboardProvider } from './contexts/DashboardContext';
import { UserProvider } from './contexts/UserContext';
import NotFound from './pages/NotFound/NotFound';

/*
페이지 라우팅 분리,
Expand All @@ -23,6 +24,7 @@ function AppLayout() {
<Route path="/mypage" element={<MyPage />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
Expand All @@ -42,6 +44,7 @@ function App() {
</UserProvider>
)}
/>
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
Expand Down
12 changes: 11 additions & 1 deletion src/components/UserProfileImg/UserProfileImg.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
border-radius: 50%;
width: 38px;
height: 38px;
border: 1px solid #d9d9d9;
object-fit: cover;
}

.MembersProfileImg {
Expand All @@ -30,5 +32,13 @@
justify-content: center;
border-radius: 50%;
margin-right: -10px;
border: 2px solid white;
border: 1px solid #d9d9d9;

.Img {
width: 100%;
height: 100%;
object-fit: cover; /* 이미지가 크기를 벗어나지 않도록 설정 */

border-radius: 50%;
}
}
12 changes: 9 additions & 3 deletions src/components/UserProfileImg/UserProfileImg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ export function MembersProfileImg({
return (
<div
className={styles.MembersProfileImg}
style={!isImg ? { backgroundColor: profileImageUrl } : {}}
style={{
backgroundColor: profileImageUrl || '#fff',
}}
>
{isImg ? (
<img src={profileImageUrl} alt="프로필 이미지" className={styles.Img} />
Expand All @@ -60,12 +62,16 @@ svg 생성기가 있으면, 사용할 프로필 이미지 컴포넌트
props로 url 하나만 받아옵니다.
*/
interface UserProfileImgSvgProps {
profileImageUrl: string;
profileImageUrl: string | undefined;
}

export function UserProfileImgSvg({ profileImageUrl }: UserProfileImgSvgProps) {
return (
<img src={profileImageUrl} alt="프로필 이미지" className={styles.UserProfileImgSvg} />
<img
src={profileImageUrl}
alt="프로필 이미지"
className={styles.UserProfileImgSvg}
/>
);
}

Expand Down
41 changes: 32 additions & 9 deletions src/components/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,27 @@ function SideBar() {

// 상태 관리
const [dashboardItems, setDashboardItems] = useState<DashboardDetail[]>([]);
const [currentPage, setCurrentPage] = useState(1);
const [currentPage, setCurrentPage] = useState(() => {
const savedPage = localStorage.getItem('currentPage');
return savedPage ? Number(savedPage) : 1;
});
const [prevBtnPage, setprevBtnPage] = useState(() => {
const savedPage = localStorage.getItem('currentPage');
return savedPage ? Number(savedPage) : 1;
});
const [totalPages, setTotalPages] = useState(1);
const [isError, setIsError] = useState(false);
const [errorMessage, setErrorMessage] = useState('');

// 화면 크기에 따라 한 페이지당 보여줄 대시보드 수를 결정
const isMobile = useMediaQuery({ maxWidth: 768 });
const isMobile = useMediaQuery({ maxWidth: 767 });
const itemsPerPage = isMobile ? ITEMS_PER_PAGE_MOBILE : ITEMS_PER_PAGE;

// 데이터 로드 및 페이지 설정
useEffect(() => {
const fetchData = async () => {
try {
const { items: dashboards, totalCount } = await fetchDashboards(1, itemsPerPage);
const { items: dashboards, totalCount } = await fetchDashboards(currentPage, itemsPerPage);
setDashboardItems(dashboards);
setTotalPages(Math.ceil(totalCount / itemsPerPage));
} catch (error) {
Expand All @@ -75,7 +82,25 @@ function SideBar() {
};

fetchData();
}, [itemsPerPage]);
}, [itemsPerPage, currentPage, prevBtnPage]);

useEffect(() => {
localStorage.setItem('currentPage', currentPage.toString());
}, [currentPage]);

useEffect(() => {
const isMobileSetPage = () => {
if (isMobile) {
localStorage.setItem('currentPage', '1');
setCurrentPage(1);
} else {
localStorage.setItem('currentPage', prevBtnPage.toString());
setCurrentPage(prevBtnPage);
}
};

isMobileSetPage();
}, [prevBtnPage, isMobile]);

const fetchPageData = async (page: number) => {
try {
Expand All @@ -92,6 +117,7 @@ function SideBar() {
const prevPage = currentPage - 1;
fetchPageData(prevPage);
setCurrentPage(prevPage);
setprevBtnPage(prevPage);
}
};

Expand All @@ -100,6 +126,7 @@ function SideBar() {
const nextPage = currentPage + 1;
fetchPageData(nextPage);
setCurrentPage(nextPage);
setprevBtnPage(nextPage);
}
};

Expand Down Expand Up @@ -135,11 +162,7 @@ function SideBar() {
</button>
<NewDashModal />
</div>
{isError && (
<div className={styles.ErrorMessage}>
{errorMessage}
</div>
)}
{isError && <div className={styles.ErrorMessage}>{errorMessage}</div>}
<div className={styles.DashboardsList}>
{dashboardItems.map((dashboard) => (
<SideDashBoard
Expand Down
64 changes: 31 additions & 33 deletions src/contexts/DashboardContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ReactNode,
useMemo,
} from 'react';
import { useLocation } from 'react-router-dom';

/*
사이드 바 대시보드 클릭에 따라 데이터를 옮기고 Navigate 하기 위한 상태관리 Context 입니다.
Expand All @@ -20,32 +21,28 @@ interface DashboardContextProps {
setActiveTitle: (dashboard: string) => void;
}

export const DashboardContext = createContext<DashboardContextProps | null>(
null,
);
export const DashboardContext = createContext<DashboardContextProps | null>(null);

interface DashboardProviderProps {
children: ReactNode;
}

export function DashboardProvider({ children }: DashboardProviderProps) {
const [activeDashboard, setActiveDashboard] = useState<number | undefined>(
() => {
const savedDashboardId = localStorage.getItem('activeDashboard');
return savedDashboardId ? Number(savedDashboardId) : undefined;
},
);
const [isCreateByMe, setIsCreateByMe] = useState<boolean | undefined>(
() => {
const savedIsCreatedByMe = localStorage.getItem('isCreatedByMe');
return savedIsCreatedByMe ? Boolean(savedIsCreatedByMe) : undefined;
},
);
const [activeDashboard, setActiveDashboard] = useState<number | undefined>(() => {
const savedDashboardId = localStorage.getItem('activeDashboard');
return savedDashboardId ? Number(savedDashboardId) : undefined;
});
const [isCreateByMe, setIsCreateByMe] = useState<boolean | undefined>(() => {
const savedIsCreatedByMe = localStorage.getItem('isCreatedByMe');
return savedIsCreatedByMe ? savedIsCreatedByMe === 'true' : undefined;
});
const [activeTitle, setActiveTitle] = useState<string | undefined>(() => {
const savedTitle = localStorage.getItem('activeTitle');
return savedTitle || undefined;
});

const location = useLocation();

useEffect(() => {
if (activeDashboard !== undefined) {
localStorage.setItem('activeDashboard', activeDashboard.toString());
Expand All @@ -64,24 +61,25 @@ export function DashboardProvider({ children }: DashboardProviderProps) {
}
}, [activeTitle]);

const contextValue = useMemo(
() => ({
activeDashboard,
setActiveDashboard,
isCreateByMe,
setIsCreateByMe,
activeTitle,
setActiveTitle,
}),
[
activeDashboard,
setActiveDashboard,
isCreateByMe,
setIsCreateByMe,
activeTitle,
setActiveTitle,
],
);
useEffect(() => {
if (location.pathname === '/mydashboard' || location.pathname === '/mypage') {
setActiveDashboard(undefined);
setActiveTitle(undefined);
setIsCreateByMe(undefined);
localStorage.removeItem('activeDashboard');
localStorage.removeItem('isCreatedByMe');
localStorage.removeItem('activeTitle');
}
}, [location.pathname]);

const contextValue = useMemo(() => ({
activeDashboard,
setActiveDashboard,
isCreateByMe,
setIsCreateByMe,
activeTitle,
setActiveTitle,
}), [activeDashboard, isCreateByMe, activeTitle]);

return (
<DashboardContext.Provider value={contextValue}>
Expand Down
29 changes: 24 additions & 5 deletions src/contexts/UserContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
createContext, useState, useEffect, ReactNode, useMemo,
} from 'react';
import { useNavigate } from 'react-router-dom';
import { useNavigate, useLocation } from 'react-router-dom';
import { apiInquireMyInfo } from '../api/apiModule';

/*
Expand All @@ -23,7 +23,7 @@ export interface UserInfo {

interface UserContextProps {
userInfo: UserInfo | null;
setUserInfo: (info: UserInfo) => void;
setUserInfo: (info: UserInfo | null) => void;
}

interface UserProviderProps {
Expand All @@ -37,12 +37,13 @@ export const UserContext = createContext<UserContextProps | null>(null);
export function UserProvider({ children }: UserProviderProps) {
const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
const navigate = useNavigate();
const location = useLocation();

useEffect(() => {
const fetchUserInfo = async () => {
try {
const Info = await apiInquireMyInfo();
setUserInfo(Info);
const info = await apiInquireMyInfo();
setUserInfo(info);
} catch (error) {
setUserInfo(null);
navigate('/login');
Expand All @@ -52,7 +53,25 @@ export function UserProvider({ children }: UserProviderProps) {
fetchUserInfo();
}, [navigate]);

const value = useMemo(() => ({ userInfo, setUserInfo }), [userInfo]);
useEffect(() => {
const checkAuthOnUrlChange = async () => {
if (userInfo === null) {
try {
const info = await apiInquireMyInfo();
setUserInfo(info);
} catch (error) {
navigate('/login');
}
}
};

checkAuthOnUrlChange();
}, [location.pathname, userInfo, navigate]);

const value = useMemo(
() => ({ userInfo, setUserInfo }),
[userInfo],
);

return <UserContext.Provider value={value}>{children}</UserContext.Provider>;
}
Loading

0 comments on commit 7ab4836

Please sign in to comment.