Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Card & Text & NavigationHeader 구현 #13

Merged
merged 12 commits into from
Jan 30, 2025
Merged
10 changes: 10 additions & 0 deletions spark-web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions spark-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@types/node": "^22.10.7",
"autoprefixer": "^10.4.20",
"axios": "^1.7.9",
"clsx": "^2.1.1",
"postcss": "^8.5.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
10 changes: 6 additions & 4 deletions spark-web/src/app/router/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import Setting from '@/pages/Setting';
import Strategy from '@/pages/Strategy';
import StrengthWeakness from '@/pages/StrengthWeakness';
import UserInfo from '@/pages/UserInfo';
import BottomNavigationLayout from './BottomNavigationLayout';
import PageLayout from './PageLayout';
import ProtectedRoute from './ProtectedRoute';
import {
BottomNavigationLayout,
PageLayout,
ProtectedLayout,
} from '@/shared/ui';
Comment on lines +13 to +17
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 하니까 가독성이 좋아지네요


export default function RouterApp() {
return (
Expand All @@ -24,7 +26,7 @@ export default function RouterApp() {
</Route>
<Route element={<PageLayout />}>
<Route path="/onboarding" element={<OnBoarding />} />
<Route element={<ProtectedRoute />}>
<Route element={<ProtectedLayout />}>
<Route path="/detail" element={<Detail />} />
<Route path="/user-info" element={<UserInfo />} />
<Route path="/analysis" element={<Analysis />} />
Expand Down
25 changes: 25 additions & 0 deletions spark-web/src/assets/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { SvgProps } from '../nav/SettingIcon';

export const Avatar = ({ className, ...props }: SvgProps) => {
return (
<svg
width="60"
height="60"
viewBox="0 0 60 60"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
{...props}
>
<circle cx="30" cy="30" r="30" fill="#8D9199" />
<path
d="M36.6667 24.6667C36.6667 28.3486 33.6819 31.3333 30 31.3333C26.3181 31.3333 23.3333 28.3486 23.3333 24.6667C23.3333 20.9848 26.3181 18 30 18C33.6819 18 36.6667 20.9848 36.6667 24.6667Z"
fill="white"
/>
<path
d="M19.3333 40.6667C19.3333 36.9848 22.3181 34 26 34H34C37.6819 34 40.6667 36.9848 40.6667 40.6667C40.6667 41.403 40.0697 42 39.3333 42H20.6667C19.9303 42 19.3333 41.403 19.3333 40.6667Z"
fill="white"
/>
</svg>
);
};
279 changes: 279 additions & 0 deletions spark-web/src/assets/logo/Logo.tsx

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions spark-web/src/assets/nav/BackIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { SvgProps } from './SettingIcon';

export const BackIcon = ({ className, ...props }: SvgProps) => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
{...props}
>
<path
d="M8.55439 11.5271L15.1552 17.0659C15.5783 17.4209 15.6335 18.0517 15.2785 18.4747C14.9235 18.8978 14.2927 18.953 13.8696 18.598L6.36322 12.2993C6.30343 12.2492 6.25099 12.1935 6.20601 12.1337C5.88238 11.7115 5.9458 11.1052 6.35736 10.7599L13.8646 4.46054C14.2877 4.10554 14.9184 4.16072 15.2734 4.5838C15.6284 5.00687 15.5732 5.63763 15.1502 5.99263L8.55439 11.5271Z"
fill="#333333"
/>
</svg>
);
};
20 changes: 20 additions & 0 deletions spark-web/src/assets/nav/CloseIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { SvgProps } from './SettingIcon';

export const CloseIcon = ({ className, ...props }: SvgProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
className={className}
{...props}
>
<path
d="M6.12117 4.7072C5.73064 4.31668 5.09748 4.31668 4.70696 4.7072C4.31643 5.09772 4.31643 5.73089 4.70696 6.12141L10.3639 11.7783L4.70706 17.4351C4.31654 17.8256 4.31654 18.4588 4.70706 18.8493C5.09758 19.2399 5.73075 19.2399 6.12127 18.8493L11.7781 13.1925L17.4349 18.8493C17.8254 19.2399 18.4586 19.2399 18.8491 18.8493C19.2396 18.4588 19.2396 17.8256 18.8491 17.4351L13.1923 11.7783L18.8492 6.12141C19.2397 5.73089 19.2397 5.09772 18.8492 4.7072C18.4587 4.31668 17.8255 4.31668 17.435 4.7072L11.7781 10.3641L6.12117 4.7072Z"
fill="#1C1C1E"
/>
</svg>
);
};
2 changes: 1 addition & 1 deletion spark-web/src/assets/svg/LargeClose.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SvgProps } from './SettingIcon';
import { SvgProps } from '../nav/SettingIcon';

export const LargeClose = ({ color, className, ...props }: SvgProps) => {
return (
Expand Down
2 changes: 1 addition & 1 deletion spark-web/src/assets/svg/SparkIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SvgProps } from './SettingIcon';
import { SvgProps } from '../nav/SettingIcon';

export const SparkIcon = ({ className }: SvgProps) => {
return (
Expand Down
1 change: 1 addition & 0 deletions spark-web/src/colors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const COLORS = {
// Gray Scale
black: '#1C1C1E', // Black
gray: '#5E6166', //gray
highEmphasis: '#333333', // High Emphasis Gray
subText: '#616166', // Gray5
midEmphasis: '#B9B9B9', // Mid Emphasis Gray
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react';
import Button from '@/shared/components/Buttons/Button';
import { Button } from '@/shared/components';

interface FulltimeParttime {
onClick: (fulltime: string) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import Button from '@/shared/components/Buttons/Button';
import { Button } from '@/shared/components';

interface SNSGoal {
onClick: (goal: string) => void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { userAnswer } from '@/pages/UserInfo';
import Button from '@/shared/components/Buttons/Button';
import PrimaryChips from '@/shared/components/Chips/PrimaryChips';
import { Button, PrimaryChips } from '@/shared/components';

interface SheetContents {
setOnlyClicked: (onlyClick: string) => void;
Expand Down
2 changes: 1 addition & 1 deletion spark-web/src/pages/UserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import SheetContents from '@/domains/UserInformation/components/SheetContent';
import UserDialogbox from '@/domains/UserInformation/components/UserDialogbox';
import UserInformationProfiles from '@/domains/UserInformation/components/UserInformationProfiles';
import { QUESTIONS } from '@/domains/UserInformation/questions';
import { Button } from '@/shared/components';
import BottomSheetModal from '@/shared/components/BottomSheetModal/BottomSheetModal';
import Button from '@/shared/components/Buttons/Button';

export interface userAnswer {
CONTENTS: string;
Expand Down
39 changes: 39 additions & 0 deletions spark-web/src/shared/components/NavigationHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { ReactNode } from 'react';
import clsx from 'clsx';
import { type RouteInfo } from '@/shared/hooks';
import RouteMove from '../RouteMove';

interface LeftContentProps extends RouteInfo {
className?: string;
children: ReactNode;
}

function Root({ className, children }: Omit<LeftContentProps, 'location'>) {
return (
<header
className={clsx('flex justify-between px-5 py-4 items-center', className)}
>
{children}
</header>
);
}

function LeftContent({ location, className, children }: LeftContentProps) {
return (
<RouteMove location={location} className={clsx(className)}>
{children}
</RouteMove>
);
}

function RightContent({ location, className, children }: LeftContentProps) {
return (
<RouteMove location={location} className={clsx(className)}>
{children}
</RouteMove>
);
}

const NavigationHeader = Object.assign(Root, { LeftContent, RightContent });

export default NavigationHeader;
20 changes: 20 additions & 0 deletions spark-web/src/shared/components/RouteMove/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { ComponentProps, ReactNode } from 'react';
import { type RouteInfo, useMoveLocation } from '@/shared/hooks';

interface RouteMoveProps extends RouteInfo, ComponentProps<'div'> {
children: ReactNode;
}

export default function RouteMove({
location,
children,
...props
}: RouteMoveProps) {
const handleMoveLocation = useMoveLocation(location);

return (
<div onClick={handleMoveLocation} {...props}>
{children}
</div>
);
}
4 changes: 4 additions & 0 deletions spark-web/src/shared/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default as NavigationHeader } from './NavigationHeader';
export { default as PrimaryChips } from './Chips';
export { default as Button } from './Buttons';
export { default as RouteMove } from './RouteMove';
Comment on lines +1 to +4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 index에 한데 모아서 export 하는 이유가 뭘까요?

1 change: 1 addition & 0 deletions spark-web/src/shared/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useMoveLocation';
34 changes: 34 additions & 0 deletions spark-web/src/shared/hooks/useMoveLocation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useCallback } from 'react';
import { useNavigate } from 'react-router';

const routeMap = {
home: '/',
setting: '/setting',
onboarding: '/onboarding',
detail: '/detail',
userInfo: '/user-info',
analysis: '/analysis',
result: '/result',
popular: '/result/popular',
strengthWeakness: '/result/strength-weakness',
growthPrediction: '/result/growth-prediction',
strategy: '/result/strategy',
} as const;

export interface RouteInfo {
location: (typeof routeMap)[keyof typeof routeMap] | 'back';
}

export const useMoveLocation = (location: RouteInfo['location']) => {
const navigate = useNavigate();

const handleMoveLocation = useCallback(() => {
if (location === 'back') {
navigate(-1);
} else {
navigate(location);
}
}, [navigate, location]);
Comment on lines +22 to +31
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

외부 라이브러리로 부터의 결합성을 낮추는 이런 방식이 있군요!


return handleMoveLocation;
};
49 changes: 49 additions & 0 deletions spark-web/src/shared/ui/components/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { ReactNode } from 'react';
import clsx from 'clsx';

interface RootProps {
className?: string;
children: ReactNode;
}

function Root({ className, children }: RootProps) {
return (
<article
className={clsx(
`flex flex-col border rounded-2xl border-midEmphasis gap-y-5 overflow-hidden`,
className,
)}
>
{children}
</article>
);
}

function Header({ className, children }: RootProps) {
return (
<div className={clsx(`flex flex-col px-5 pt-5 flex-1`, className)}>
{children}
</div>
);
}

function Content({ className, children }: RootProps) {
return (
<div
className={clsx(
`p-5 flex justify-between flex-2 gap-x-9 items-center`,
className,
)}
>
{children}
</div>
);
}

function Bottom({ className, children }: RootProps) {
return <div className={clsx(`flex-1`, className)}>{children}</div>;
}

const Card = Object.assign(Root, { Header, Content, Bottom });
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 배워갑니다. 오픈 소스 라이브러리에서만 보던건데 너무 좋은데요?


export default Card;
16 changes: 16 additions & 0 deletions spark-web/src/shared/ui/components/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import clsx from 'clsx';

interface TextProps {
as: keyof typeof style;
title: string;
className?: string;
}

const style = {
title: 'text-black font-extrabold text-[15px] not-italic',
description: 'text-gray font-medium text-[13px] not-italic',
} as const;

export default function Text({ as, title, className }: TextProps) {
return <p className={clsx(style[as], className)}>{title}</p>;
}
Comment on lines +1 to +16
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text 컴포넌트는 용도가 어떻게 될까요? 스크린샷이 있을까요?

8 changes: 7 additions & 1 deletion spark-web/src/shared/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
export { default as GlobalLayout } from './GlobalLayout';
export { default as Card } from './components/Card';
export { default as Text } from './components/Text';

export { default as GlobalLayout } from './layout/GlobalLayout';
export { default as BottomNavigationLayout } from './layout/BottomNavigationLayout';
export { default as PageLayout } from './layout/PageLayout';
export { default as ProtectedLayout } from './layout/ProtectedLayout';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NavLink, Outlet } from 'react-router';
import { HomeIcon } from '@/assets/svg/HomeIcon';
import { SettingIcon } from '@/assets/svg/SettingIcon';
import { HomeIcon } from '@/assets/nav/HomeIcon';
import { SettingIcon } from '@/assets/nav/SettingIcon';

interface NavLinkProps {
path: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Outlet } from 'react-router';
export default function PageLayout() {
return (
<div>
PageLayout
<Outlet />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Outlet } from 'react-router';

export default function ProtectedRoute() {
export default function ProtectedLayout() {
return (
<div>
ProtectedRoute
Expand Down
Loading