diff --git a/public/assets/baekgyeong-speaker.png b/public/assets/baekgyeong-speaker.png
deleted file mode 100644
index c8177981..00000000
Binary files a/public/assets/baekgyeong-speaker.png and /dev/null differ
diff --git a/public/assets/baekgyeong-whalebe.png b/public/assets/baekgyeong-whalebe.png
deleted file mode 100644
index d0a04d46..00000000
Binary files a/public/assets/baekgyeong-whalebe.png and /dev/null differ
diff --git a/public/assets/pknu.png b/public/assets/pknu.png
deleted file mode 100644
index 4b5a391a..00000000
Binary files a/public/assets/pknu.png and /dev/null differ
diff --git a/public/assets/tipImages/png/baekgyeong_camera.png b/public/assets/tipImages/png/baekgyeong_camera.png
new file mode 100644
index 00000000..7bf0a0d3
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_camera.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_guide.png b/public/assets/tipImages/png/baekgyeong_guide.png
new file mode 100644
index 00000000..954263d9
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_guide.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_hi.png b/public/assets/tipImages/png/baekgyeong_hi.png
new file mode 100644
index 00000000..3e414283
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_hi.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_love.png b/public/assets/tipImages/png/baekgyeong_love.png
new file mode 100644
index 00000000..2057fcf4
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_love.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_search.png b/public/assets/tipImages/png/baekgyeong_search.png
new file mode 100644
index 00000000..5ebe84e0
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_search.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_suprised.png b/public/assets/tipImages/png/baekgyeong_suprised.png
new file mode 100644
index 00000000..781114ef
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_suprised.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_teach.png b/public/assets/tipImages/png/baekgyeong_teach.png
new file mode 100644
index 00000000..9a774224
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_teach.png differ
diff --git a/public/assets/tipImages/png/baekgyeong_underpin.png b/public/assets/tipImages/png/baekgyeong_underpin.png
new file mode 100644
index 00000000..1ddc29fa
Binary files /dev/null and b/public/assets/tipImages/png/baekgyeong_underpin.png differ
diff --git a/public/assets/tipImages/png/pknu.png b/public/assets/tipImages/png/pknu.png
new file mode 100644
index 00000000..126c52ac
Binary files /dev/null and b/public/assets/tipImages/png/pknu.png differ
diff --git a/public/assets/tipImages/webp/baekgyeong_camera.webp b/public/assets/tipImages/webp/baekgyeong_camera.webp
new file mode 100644
index 00000000..0f347d75
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_camera.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_guide.webp b/public/assets/tipImages/webp/baekgyeong_guide.webp
new file mode 100644
index 00000000..3d1a92ae
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_guide.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_hi.webp b/public/assets/tipImages/webp/baekgyeong_hi.webp
new file mode 100644
index 00000000..c3d32756
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_hi.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_love.webp b/public/assets/tipImages/webp/baekgyeong_love.webp
new file mode 100644
index 00000000..0ec1e410
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_love.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_search.webp b/public/assets/tipImages/webp/baekgyeong_search.webp
new file mode 100644
index 00000000..e870bb12
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_search.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_suprised.webp b/public/assets/tipImages/webp/baekgyeong_suprised.webp
new file mode 100644
index 00000000..aa2881cc
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_suprised.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_teach.webp b/public/assets/tipImages/webp/baekgyeong_teach.webp
new file mode 100644
index 00000000..57de4586
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_teach.webp differ
diff --git a/public/assets/tipImages/webp/baekgyeong_underpin.webp b/public/assets/tipImages/webp/baekgyeong_underpin.webp
new file mode 100644
index 00000000..feb62201
Binary files /dev/null and b/public/assets/tipImages/webp/baekgyeong_underpin.webp differ
diff --git a/public/assets/tipImages/webp/pknu.webp b/public/assets/tipImages/webp/pknu.webp
new file mode 100644
index 00000000..4e44b20b
Binary files /dev/null and b/public/assets/tipImages/webp/pknu.webp differ
diff --git a/src/App.tsx b/src/App.tsx
index 975aada4..f7d013ef 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -25,7 +25,7 @@ const App = () => {
} />
} />
} />
- } />
+ } />
} />
}>
diff --git a/src/components/Card/TipCard/TipImage.tsx b/src/components/Card/TipCard/TipImage.tsx
new file mode 100644
index 00000000..10db07ed
--- /dev/null
+++ b/src/components/Card/TipCard/TipImage.tsx
@@ -0,0 +1,32 @@
+import Image from '@components/Common/Image';
+import { css } from '@emotion/react';
+import React from 'react';
+
+interface TipImageProps {
+ title: string;
+ webpPath: string;
+ pngPath: string;
+}
+
+const TipImage = ({ title, webpPath, pngPath }: TipImageProps) => {
+ return (
+
+ );
+};
+
+export default TipImage;
diff --git a/src/components/Card/TipCard/TipSubTitle.tsx b/src/components/Card/TipCard/TipSubTitle.tsx
new file mode 100644
index 00000000..d851bbb3
--- /dev/null
+++ b/src/components/Card/TipCard/TipSubTitle.tsx
@@ -0,0 +1,25 @@
+import styled from '@emotion/styled';
+import React from 'react';
+
+interface TipSubTitleProps {
+ subTitle: string;
+}
+
+const TipSubTitle = ({ subTitle }: TipSubTitleProps) => {
+ const seperatedSubTitle = subTitle.split('\n');
+ return (
+
+ {seperatedSubTitle.map((subTitle, index) => (
+ {subTitle}
+ ))}
+
+ );
+};
+
+export default TipSubTitle;
+
+const SubTitle = styled.span`
+ padding: 0 0 0 16px;
+ line-height: 1rem;
+ font-size: 0.8rem;
+`;
diff --git a/src/components/Card/TipCard/TipTitle.tsx b/src/components/Card/TipCard/TipTitle.tsx
new file mode 100644
index 00000000..d3b749f3
--- /dev/null
+++ b/src/components/Card/TipCard/TipTitle.tsx
@@ -0,0 +1,26 @@
+import styled from '@emotion/styled';
+import React from 'react';
+
+interface TipTitleProps {
+ title: string;
+}
+
+const TipTitle = ({ title }: TipTitleProps) => {
+ const seperatedTitle = title.split('\n');
+ return (
+
+ {seperatedTitle.map((titleItem, index) => (
+ {titleItem}
+ ))}
+
+ );
+};
+
+export default TipTitle;
+
+const Title = styled.span`
+ padding: 20px 0px 10px 16px;
+ line-height: 1.2rem;
+ font-size: 1.2rem;
+ font-weight: bold;
+`;
diff --git a/src/components/Card/TipCard/domain/getTipCardSubElement.ts b/src/components/Card/TipCard/domain/getTipCardSubElement.ts
new file mode 100644
index 00000000..083e0174
--- /dev/null
+++ b/src/components/Card/TipCard/domain/getTipCardSubElement.ts
@@ -0,0 +1,21 @@
+import { Children, isValidElement } from 'react';
+
+import TipImage from '../TipImage';
+import TipSubTitle from '../TipSubTitle';
+import TipTitle from '../TipTitle';
+
+type TipCardChildType = typeof TipTitle | typeof TipSubTitle | typeof TipImage;
+
+const getTipCardSubElement = (
+ children: React.ReactNode,
+ childType: TipCardChildType,
+) => {
+ const chidrenArray = Children.toArray(children);
+ const targetChild = chidrenArray
+ .filter((child) => isValidElement(child) && child.type === childType)
+ .slice(0, 2);
+
+ return targetChild;
+};
+
+export default getTipCardSubElement;
diff --git a/src/components/Card/TipCard/index.tsx b/src/components/Card/TipCard/index.tsx
new file mode 100644
index 00000000..6cc301b3
--- /dev/null
+++ b/src/components/Card/TipCard/index.tsx
@@ -0,0 +1,47 @@
+import styled from '@emotion/styled';
+import { THEME } from '@styles/ThemeProvider/theme';
+import React from 'react';
+
+import getTipCardSubElement from './domain/getTipCardSubElement';
+import TipImage from './TipImage';
+import TipSubTitle from './TipSubTitle';
+import TipTitle from './TipTitle';
+
+type StrictPropsWithChildren = T & {
+ children: React.ReactNode;
+ onClick: () => void;
+};
+
+const TipCard = ({ children, onClick }: StrictPropsWithChildren) => {
+ const tipTitle = getTipCardSubElement(children, TipTitle);
+ const tipSubTitle = getTipCardSubElement(children, TipSubTitle);
+ const tipImage = getTipCardSubElement(children, TipImage);
+
+ return (
+
+ {tipTitle}
+ {tipSubTitle}
+ {tipImage}
+
+ );
+};
+
+export default TipCard;
+
+TipCard.TipTitle = TipTitle;
+TipCard.TipSubTitle = TipSubTitle;
+TipCard.TipImage = TipImage;
+
+const Container = styled.div`
+ position: relative;
+ height: 10rem;
+ width: 10rem;
+ display: flex;
+ flex-direction: column;
+ background-color: ${THEME.PRIMARY}20;
+ border: 1px solid ${THEME.PRIMARY}30;
+ border-radius: 10px;
+ box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
+ gap: 5px;
+ z-index: 1;
+`;
diff --git a/src/components/Common/Image/index.tsx b/src/components/Common/Image/index.tsx
index 519e1231..c4572406 100644
--- a/src/components/Common/Image/index.tsx
+++ b/src/components/Common/Image/index.tsx
@@ -7,7 +7,7 @@ const imageSize: ImageSize = {
large: setSize(200),
medium: setSize(150),
small: setSize(100),
- tiny: setSize(45),
+ tiny: setSize(80),
};
const Image = ({
diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx
index 91cccaf4..20f5140e 100644
--- a/src/components/Header/index.tsx
+++ b/src/components/Header/index.tsx
@@ -1,37 +1,33 @@
import Icon from '@components/Common/Icon';
-import SideBar from '@components/SideBar';
-import SideBarContent from '@components/SideBar/Content';
import styled from '@emotion/styled';
import useRoter from '@hooks/useRouter';
import { THEME } from '@styles/ThemeProvider/theme';
-import { useState } from 'react';
-import { useLocation } from 'react-router-dom';
const Header = () => {
- const { routerTo, goBack } = useRoter();
- const [open, setOpen] = useState(false);
- const location = useLocation();
+ const { routerTo, goBack, currentPath } = useRoter();
+ if (currentPath === '/map') return <>>;
- if (location.pathname === '/map') return <>>;
+ const isNotHomePage = currentPath !== '/';
return (
-
-
-
- routerTo('/')}>부림이
-
-
-
-
-
+
+ {isNotHomePage && (
+
+
+
+ )}
+ routerTo('/')}>부림이
+
);
};
export default Header;
-const HeaderContainer = styled.div`
+const Container = styled.section`
+ position: relative;
display: flex;
justify-content: center;
+ align-items: center;
width: 100%;
max-width: 480px;
@@ -43,12 +39,9 @@ const HeaderContainer = styled.div`
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
`;
-const HeaderWrapper = styled.div`
- width: 90%;
- height: 100%;
- display: flex;
- justify-content: space-between;
- align-items: center;
+const IconContainer = styled.div`
+ position: absolute;
+ left: 1rem;
`;
const Logo = styled.span`
diff --git a/src/components/InformUpperLayout/InformSubTitle.tsx b/src/components/InformUpperLayout/InformSubTitle.tsx
new file mode 100644
index 00000000..01d1110e
--- /dev/null
+++ b/src/components/InformUpperLayout/InformSubTitle.tsx
@@ -0,0 +1,28 @@
+import styled from '@emotion/styled';
+import { THEME } from '@styles/ThemeProvider/theme';
+import React from 'react';
+
+interface InformSubTitleProps {
+ subTitle: string;
+}
+
+const InformSubTitle = ({ subTitle }: InformSubTitleProps) => {
+ const seperatedSubTitle = subTitle.split('\n');
+
+ return (
+
+ {seperatedSubTitle.map((subTitle, index) => (
+ {subTitle}
+ ))}
+
+ );
+};
+
+export default InformSubTitle;
+
+const SubTitle = styled.span`
+ padding: 0 0 1rem 0;
+ color: ${THEME.TEXT.GRAY};
+ line-height: 1.3;
+ font-size: 0.9rem;
+`;
diff --git a/src/components/InformUpperLayout/InformTitle.tsx b/src/components/InformUpperLayout/InformTitle.tsx
new file mode 100644
index 00000000..6de18811
--- /dev/null
+++ b/src/components/InformUpperLayout/InformTitle.tsx
@@ -0,0 +1,20 @@
+import styled from '@emotion/styled';
+import { THEME } from '@styles/ThemeProvider/theme';
+import React from 'react';
+
+interface InformTitleProps {
+ title: string;
+}
+
+const InformTitle = ({ title }: InformTitleProps) => {
+ return {title};
+};
+
+export default InformTitle;
+
+const Title = styled.span`
+ padding: 1.5rem 0 1.5rem 0;
+ color: ${THEME.TEXT.BLACK};
+ font-size: 1.5rem;
+ font-weight: bold;
+`;
diff --git a/src/components/InformUpperLayout/InformTypeButton.tsx b/src/components/InformUpperLayout/InformTypeButton.tsx
new file mode 100644
index 00000000..59cc824d
--- /dev/null
+++ b/src/components/InformUpperLayout/InformTypeButton.tsx
@@ -0,0 +1,35 @@
+import Button from '@components/Common/Button';
+import { css } from '@emotion/react';
+import { THEME } from '@styles/ThemeProvider/theme';
+import React from 'react';
+
+interface InformTypeButtonProps {
+ type: string;
+ isActive: boolean;
+ onClick: () => void;
+}
+
+const InformTypeButton = ({
+ type,
+ isActive,
+ onClick,
+}: InformTypeButtonProps) => {
+ return (
+
+ );
+};
+
+export default InformTypeButton;
diff --git a/src/components/InformUpperLayout/domain/getInformUpperLayoutSubElement.ts b/src/components/InformUpperLayout/domain/getInformUpperLayoutSubElement.ts
new file mode 100644
index 00000000..790baa3f
--- /dev/null
+++ b/src/components/InformUpperLayout/domain/getInformUpperLayoutSubElement.ts
@@ -0,0 +1,24 @@
+import { Children, isValidElement } from 'react';
+
+import InformSubTitle from '../InformSubTitle';
+import InformTitle from '../InformTitle';
+import InformTypeButton from '../InformTypeButton';
+
+type InformUpperLayoutChildType =
+ | typeof InformTitle
+ | typeof InformSubTitle
+ | typeof InformTypeButton;
+
+const getInformUpperLayoutSubElement = (
+ children: React.ReactNode,
+ childType: InformUpperLayoutChildType,
+) => {
+ const childrenArray = Children.toArray(children);
+ const targetChild = childrenArray
+ .filter((child) => isValidElement(child) && child.type === childType)
+ .slice(0, 2);
+
+ return targetChild;
+};
+
+export default getInformUpperLayoutSubElement;
diff --git a/src/components/InformUpperLayout/index.tsx b/src/components/InformUpperLayout/index.tsx
new file mode 100644
index 00000000..838d025e
--- /dev/null
+++ b/src/components/InformUpperLayout/index.tsx
@@ -0,0 +1,49 @@
+import styled from '@emotion/styled';
+import React from 'react';
+
+import getInformUpperLayoutSubElement from './domain/getInformUpperLayoutSubElement';
+import InformSubTitle from './InformSubTitle';
+import InformTitle from './InformTitle';
+import InformTypeButton from './InformTypeButton';
+
+type StrictPropsWithChildren = T & { children: React.ReactNode };
+
+const InformUpperLayout = ({ children }: StrictPropsWithChildren) => {
+ const informTitle = getInformUpperLayoutSubElement(children, InformTitle);
+ const informSubTitle = getInformUpperLayoutSubElement(
+ children,
+ InformSubTitle,
+ );
+ const informTypeButton = getInformUpperLayoutSubElement(
+ children,
+ InformTypeButton,
+ );
+
+ return (
+
+ {informTitle}
+ {informSubTitle}
+ {informTypeButton && (
+ {informTypeButton}
+ )}
+
+ );
+};
+
+export default InformUpperLayout;
+
+InformUpperLayout.InformTitle = InformTitle;
+InformUpperLayout.InformSubTitle = InformSubTitle;
+InformUpperLayout.InformTypeButton = InformTypeButton;
+
+const Container = styled.section`
+ padding: 0px 20px 0px 20px;
+ display: flex;
+ flex-direction: column;
+`;
+
+const TypeButtonContainer = styled.div`
+ padding: 0 0 10px 0;
+ display: flex;
+ column-gap: 10px;
+`;
diff --git a/src/components/List/TipCardList/index.tsx b/src/components/List/TipCardList/index.tsx
new file mode 100644
index 00000000..fa9805c5
--- /dev/null
+++ b/src/components/List/TipCardList/index.tsx
@@ -0,0 +1,21 @@
+import { TipData } from '@constants/tip';
+import styled from '@emotion/styled';
+import React from 'react';
+
+interface TipCardListProps {
+ tipList: TipData[];
+ tipItemRenderer: (tipItem: TipData) => JSX.Element;
+}
+
+const TipCardList = ({ tipList, tipItemRenderer }: TipCardListProps) => {
+ return {tipList.map((tipItem) => tipItemRenderer(tipItem))};
+};
+
+export default TipCardList;
+
+const Grid = styled.section`
+ display: grid;
+ padding: 0 20px 10px 20px;
+ grid-template-columns: 1fr auto;
+ gap: 10px;
+`;
diff --git a/src/components/SideBar/Content/index.tsx b/src/components/SideBar/Content/index.tsx
deleted file mode 100644
index d0f5335f..00000000
--- a/src/components/SideBar/Content/index.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import Icon from '@components/Common/Icon';
-import SIDEBAR_CONTENT from '@constants/sidebar';
-import styled from '@emotion/styled';
-import useRouter from '@hooks/useRouter';
-import { THEME } from '@styles/ThemeProvider/theme';
-import React, { SetStateAction } from 'react';
-
-interface SideBarContentProps {
- setOpen: React.Dispatch>;
-}
-
-const SideBarContent = ({ setOpen }: SideBarContentProps) => {
- const { routerTo } = useRouter();
- const routerToPath = (path: string) => {
- routerTo(path);
- setOpen(false);
- };
-
- return (
-
- {SIDEBAR_CONTENT.map((item) => {
- return (
- routerToPath(item.path)}>
-
- {item.title}
-
- );
- })}
-
- );
-};
-
-export default SideBarContent;
-
-const Container = styled.section`
- display: flex;
- flex-direction: column;
- align-items: flex-start;
-
- line-height: 4;
-`;
-
-const SideBarItem = styled.div`
- width: 100%;
-
- font-size: 16px;
- color: ${THEME.TEXT.BLACK};
-
- display: flex;
- align-items: center;
- border-bottom: 1px solid ${THEME.BUTTON.GRAY};
-`;
-
-const Title = styled.span`
- text-indent: 10px;
-`;
diff --git a/src/components/SideBar/index.tsx b/src/components/SideBar/index.tsx
deleted file mode 100644
index af574ae9..00000000
--- a/src/components/SideBar/index.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import Icon from '@components/Common/Icon';
-import Image from '@components/Common/Image';
-import ASSET_PATH from '@constants/assets-path';
-import { css, keyframes } from '@emotion/react';
-import styled from '@emotion/styled';
-import { THEME } from '@styles/ThemeProvider/theme';
-import React, { CSSProperties, SetStateAction, useRef, useState } from 'react';
-
-interface SideBarProps {
- width?: CSSProperties['width'];
- children: React.ReactNode;
- open: boolean;
- setOpen: React.Dispatch>;
-}
-
-const SideBar = ({ width = '70%', children, open, setOpen }: SideBarProps) => {
- const [mount, setMount] = useState(false);
- const sideBarRef = useRef(null);
-
- const openSideBar = () => {
- setMount(true);
- setOpen(true);
- };
-
- const handleCloseSideBar = (e: React.MouseEvent) => {
- if (e.target === e.currentTarget) {
- setMount(false);
- setTimeout(() => {
- setOpen(false);
- }, 300);
- }
- };
-
- return (
-
-
- {open && (
-
-
-
- 부림이
- {children}
-
-
- )}
-
- );
-};
-
-export default SideBar;
-
-const Container = styled.section`
- max-width: 480px;
- position: relative;
- display: flex;
- justify-content: flex-end;
-`;
-
-const SideBarBackground = styled.div<{ mount: boolean }>`
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: rgba(0, 0, 0, 0.6);
- z-index: 9999;
-
- opacity: ${({ mount }) => (mount ? '1' : '0')};
- transition: opacity 0.3s ease-out;
-`;
-
-interface SideBarContentProps {
- width: CSSProperties['width'];
- mount: boolean;
-}
-
-const SideBarContent = styled.div`
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- height: 100%;
- width: ${({ width }) => width};
- padding: 12px;
- background-color: ${THEME.IVORY};
-
- display: flex;
- flex-direction: column;
-
- animation: ${({ mount }) => (mount ? slideIn : slideOut)} 0.3s ease-out;
-`;
-
-const Title = styled.span`
- text-align: center;
- font-size: 16px;
-`;
-
-const slideIn = keyframes`
- from {
- opacity: 0;
- transform: translateX(100%);
- }
- to {
- opacity: 1;
- transform: translateX(0%);
- }
-`;
-
-const slideOut = keyframes`
- from {
- opacity: 1;
- transform: translateX(0%);
- }
- to {
- opacity: 0;
- transform: translateX(100%);
- }
-`;
diff --git a/src/constants/assets-path.ts b/src/constants/assets-path.ts
deleted file mode 100644
index 469e6e88..00000000
--- a/src/constants/assets-path.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-const ASSET_PATH = {
- WHALEBE: '/assets/baekgyeong-whalebe.png',
- PKNU: 'assets/pknu.png',
- ICON: '/assets/baekgyeong-speaker.png',
-};
-
-export default ASSET_PATH;
diff --git a/src/constants/path.ts b/src/constants/path.ts
index 45e2d1e6..eb5fa20b 100644
--- a/src/constants/path.ts
+++ b/src/constants/path.ts
@@ -9,6 +9,10 @@ const PATH = {
`/announcement/${category}/pinned`,
SEARCH_ANNOUNCEMENT: (category: Category, keyword: string) =>
`/announcement/${category}/search?q=${keyword}`,
+ TIP: {
+ SHORTCUT: '/tip/shortcut',
+ HONEY_TIP: '/tip/honeytip',
+ },
} as const;
export default PATH;
diff --git a/src/constants/tip.ts b/src/constants/tip.ts
index 982e781e..4f29d101 100644
--- a/src/constants/tip.ts
+++ b/src/constants/tip.ts
@@ -1,52 +1,105 @@
-import { IconKind } from '@type/styles/icon';
-
-import ASSET_PATH from './assets-path';
-
-interface SideBarContent {
- readonly id: number;
- readonly title: string;
- readonly path: string;
- readonly iconKind?: IconKind;
- readonly imagePath?: string;
+export interface TipData {
+ title: string;
+ subTitle: string;
+ webpPath: string;
+ pngPath: string;
+ link: string;
}
-const TIP_CONTENT: SideBarContent[] = [
+export const SHORTCUT_DATA: readonly TipData[] = [
{
- id: 1,
title: '부경대학교',
- path: 'https://www.pknu.ac.kr/main',
- imagePath: `${ASSET_PATH.PKNU}`,
+ subTitle: '부경대학교\n홈페이지로 이동',
+ webpPath: '/assets/tipImages/webp/pknu.webp',
+ pngPath: '/assets/tipImages/png/pknu.png',
+ link: 'https://www.pknu.ac.kr/main',
},
{
- id: 2,
title: '웨일비',
- path: 'https://whalebe.pknu.ac.kr/main/1',
- imagePath: `${ASSET_PATH.WHALEBE}`,
+ subTitle: '웨일비 비교과\n홈페이지로 이동',
+ webpPath: '/assets/tipImages/webp/baekgyeong_love.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_love.png',
+ link: 'https://whalebe.pknu.ac.kr/main',
+ },
+ {
+ title: '진로취업\n길라잡이',
+ subTitle: '취업관련\n정보, 검사 하러가기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_teach.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_teach.png',
+ link: 'https://pknujob.pknu.ac.kr/main',
},
{
- id: 3,
- title: '진로취업길라잡이',
- path: 'https://pknujob.pknu.ac.kr/main',
- iconKind: 'handshake',
+ title: '증명서\n발급센터',
+ subTitle: '각종 증명서\n발급하러 가기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_search.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_search.png',
+ link: 'https://pknu.certpia.com/',
},
{
- id: 4,
- title: '증명서발급센터',
- path: 'https://pknu.certpia.com/',
- iconKind: 'print',
+ title: '이루미',
+ subTitle: '부경대 포털 사이트\n바로가기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_teach.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_teach.png',
+ link: 'https://portal.pknu.ac.kr/',
},
{
- id: 5,
- title: '강의계획서 조회',
- path: 'https://irumi.pknu.ac.kr/nxui/launch.html?screenid=Desktop_screen_quick&menuId=U020913',
- iconKind: 'document',
+ title: '도서관',
+ subTitle: '도서관 정보\n확인하기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_camera.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_camera.png',
+ link: 'https://libweb.pknu.ac.kr/',
+ },
+ {
+ title: '해커스',
+ subTitle: '토익, 스피킹 등\n외국어 무료 강좌',
+ webpPath: '/assets/tipImages/webp/baekgyeong_hi.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_hi.png',
+ link: 'https://pknulib.champstudy.com/',
+ },
+] as const;
+
+export const HONEY_TIP_DATA: readonly TipData[] = [
+ {
+ title: '아우란트검사',
+ subTitle: '인성·역량·취업준비도\n·진로적성검사',
+ webpPath: '/assets/tipImages/webp/baekgyeong_hi.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_hi.png',
+ link: 'https://u.educe.co.kr/pknu',
+ },
+ {
+ title: '동아리/스터디',
+ subTitle: '동아리/스터디\n모집 정보 알아보기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_love.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_love.png',
+ link: 'https://www.pknu.ac.kr/main/143',
},
{
- id: 6,
title: '아르바이트',
- path: 'https://www.pknu.ac.kr/main/145',
- iconKind: 'personSearch',
+ subTitle: '알바 정보 보러가기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_camera.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_camera.png',
+ link: 'https://www.pknu.ac.kr/main/145',
},
-];
+ {
+ title: '강의계획서\n조회',
+ subTitle: '강의정보 열람하기',
+ webpPath: '/assets/tipImages/webp/baekgyeong_teach.webp',
+ pngPath: '/assets/tipImages/png/baekgyeong_teach.png',
+ link: 'https://irumi.pknu.ac.kr/nxui/launch.html?screenid=Desktop_screen_quick&menuId=U020913',
+ },
+] as const;
+
+export const TIP_TYPE = {
+ SHORTCUT: 'shortcut',
+ HONEY_TIP: 'honeytip',
+} as const;
-export default TIP_CONTENT;
+export const TIP_PAGE = {
+ TITLE: '꿀팁 사이트',
+ SUB_TITLE:
+ '알아두면 쓸모 있는 학교 관련 정보 페이지들입니다.\n카드를 누르면 바로 사이트로 이동해요.',
+ BUTTON: {
+ SHORTCUT: '바로가기',
+ HONEY_TIP: '꿀팁',
+ },
+} as const;
diff --git a/src/pages/Tip/index.tsx b/src/pages/Tip/index.tsx
index 2e22085f..6b1c9ef1 100644
--- a/src/pages/Tip/index.tsx
+++ b/src/pages/Tip/index.tsx
@@ -1,40 +1,59 @@
-import Icon from '@components/Common/Icon';
-import Image from '@components/Common/Image';
-import TIP_CONTENT from '@constants/tip';
-import { css } from '@emotion/react';
+import TipCard from '@components/Card/TipCard';
+import InformUpperLayout from '@components/InformUpperLayout';
+import TipCardList from '@components/List/TipCardList';
+import PATH from '@constants/path';
+import {
+ HONEY_TIP_DATA,
+ SHORTCUT_DATA,
+ TIP_PAGE,
+ TIP_TYPE,
+ TipData,
+} from '@constants/tip';
import styled from '@emotion/styled';
-import { THEME } from '@styles/ThemeProvider/theme';
+import useRouter from '@hooks/useRouter';
+import openLink from '@utils/router/openLink';
import React from 'react';
+import { useParams } from 'react-router-dom';
const Tip = () => {
- const moveToPath = (path: string) => {
- window.open(path, '_blank');
- };
+ const { type } = useParams();
+ if (!type) return <>>;
+
+ const { routerTo } = useRouter();
+ const routerToShortcut = () => routerTo(PATH.TIP.SHORTCUT);
+ const routerToHoneyTip = () => routerTo(PATH.TIP.HONEY_TIP);
+ const tipList = type === TIP_TYPE.SHORTCUT ? SHORTCUT_DATA : HONEY_TIP_DATA;
return (
- {TIP_CONTENT.map((item) => {
- return (
- moveToPath(item.path)}>
- {item.iconKind && (
-
-
-
- )}
- {item.imagePath && (
-
- )}
- {item.title}
-
- );
- })}
+
+
+
+
+
+
+ (
+ openLink(tipItem.link)}>
+
+
+
+
+ )}
+ />
);
};
@@ -42,34 +61,6 @@ const Tip = () => {
export default Tip;
const Container = styled.section`
- width: 80%;
- height: 100%;
display: flex;
flex-direction: column;
- justify-content: center;
- margin: 0 auto;
-
- line-height: 4;
- gap: 10px;
-`;
-
-const IconContainer = styled.div`
- display: flex;
- border-radius: 50%;
- background-color: ${THEME.PRIMARY};
- height: 45px;
- width: 45px;
- justify-content: center;
- align-items: center;
-`;
-
-const TipItem = styled.div`
- display: flex;
- justify-content: space-between;
- align-items: center;
-
- background-color: ${THEME.IVORY};
- padding: 5px;
- border-radius: 15px;
- box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
`;