Merge branch 'fe/feat/65-project-card' into 'fe/develop'
Feat: ProjectCard 컴포넌트 추가 - S11P21S002-65 See merge request s11-s-project/S11P21S002!10
This commit is contained in:
commit
525051f498
1
frontend/package-lock.json
generated
1
frontend/package-lock.json
generated
@ -8858,7 +8858,6 @@
|
|||||||
"version": "0.436.0",
|
"version": "0.436.0",
|
||||||
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.436.0.tgz",
|
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.436.0.tgz",
|
||||||
"integrity": "sha512-N292bIxoqm1aObAg0MzFtvhYwgQE6qnIOWx/GLj5ONgcTPH6N0fD9bVq/GfdeC9ZORBXozt/XeEKDpiB3x3vlQ==",
|
"integrity": "sha512-N292bIxoqm1aObAg0MzFtvhYwgQE6qnIOWx/GLj5ONgcTPH6N0fD9bVq/GfdeC9ZORBXozt/XeEKDpiB3x3vlQ==",
|
||||||
"license": "ISC",
|
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
|
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc"
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M10 2C7.79 2 6 3.79 6 6V8C6 10.34 4.34 12 2 12H18C15.66 12 14 10.34 14 8V6C14 3.79 12.21 2 10 2ZM2 14H18V16H2V14ZM12 18H8V16H12V18Z" fill="currentColor"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 269 B |
@ -1,3 +0,0 @@
|
|||||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M10 2C8.34 2 7 3.34 7 5C7 6.66 8.34 8 10 8C11.66 8 13 6.66 13 5C13 3.34 11.66 2 10 2ZM10 10C7.79 10 5.67 10.79 4 12.07V14H16V12.07C14.33 10.79 12.21 10 10 10Z" fill="currentColor"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 296 B |
@ -1,7 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import bellIcon from '@/assets/icons/bell.svg';
|
import { Bell, User } from 'lucide-react';
|
||||||
import userIcon from '@/assets/icons/user.svg';
|
|
||||||
|
|
||||||
export interface HeaderProps extends React.HTMLAttributes<HTMLDivElement> {}
|
export interface HeaderProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
|
|
||||||
@ -32,16 +31,8 @@ export default function Header({ className, ...props }: HeaderProps) {
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4 md:gap-5">
|
<div className="flex items-center gap-4 md:gap-5">
|
||||||
<img
|
<Bell className="h-4 w-4 text-black sm:h-5 sm:w-5" />
|
||||||
className="h-4 w-4 sm:h-5 sm:w-5"
|
<User className="h-4 w-4 text-black sm:h-5 sm:w-5" />
|
||||||
src={bellIcon}
|
|
||||||
alt="Bell Icon"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
className="h-4 w-4 sm:h-5 sm:w-5"
|
|
||||||
src={userIcon}
|
|
||||||
alt="User Icon"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { X } from 'lucide-react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
interface CloseButtonProps {
|
interface CloseButtonProps {
|
||||||
@ -8,7 +9,7 @@ interface CloseButtonProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function CloseButton({
|
export default function CloseButton({
|
||||||
color = 'currentColor',
|
color = '#1e1e1e',
|
||||||
onClick,
|
onClick,
|
||||||
className,
|
className,
|
||||||
size = 32,
|
size = 32,
|
||||||
@ -18,30 +19,11 @@ export default function CloseButton({
|
|||||||
className={cn('cursor-pointer border-none bg-none p-1', className)}
|
className={cn('cursor-pointer border-none bg-none p-1', className)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<svg
|
<X
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
color={color}
|
||||||
width={size}
|
size={size}
|
||||||
height={size}
|
|
||||||
viewBox={`0 0 ${size} ${size}`}
|
|
||||||
fill="none"
|
|
||||||
stroke={color}
|
|
||||||
strokeWidth="2"
|
strokeWidth="2"
|
||||||
strokeLinecap="round"
|
/>
|
||||||
strokeLinejoin="round"
|
|
||||||
>
|
|
||||||
<line
|
|
||||||
x1={size * 0.75}
|
|
||||||
y1={size * 0.25}
|
|
||||||
x2={size * 0.25}
|
|
||||||
y2={size * 0.75}
|
|
||||||
></line>
|
|
||||||
<line
|
|
||||||
x1={size * 0.25}
|
|
||||||
y1={size * 0.25}
|
|
||||||
x2={size * 0.75}
|
|
||||||
y2={size * 0.75}
|
|
||||||
></line>
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ export default function ImageUploadModal({ title, buttonText, onClose }: ImageUp
|
|||||||
className="flex h-8 w-8 items-center justify-center"
|
className="flex h-8 w-8 items-center justify-center"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
<CloseButton />
|
<CloseButton className="self-end" />
|
||||||
</button>
|
</button>
|
||||||
</header>
|
</header>
|
||||||
<div className="flex flex-col gap-5">
|
<div className="flex flex-col gap-5">
|
||||||
|
20
frontend/src/components/ProjectCard/index.stories.tsx
Normal file
20
frontend/src/components/ProjectCard/index.stories.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import ProjectCard from '.';
|
||||||
|
|
||||||
|
const meta: Meta<typeof ProjectCard> = {
|
||||||
|
title: 'Components/ProjectCard',
|
||||||
|
component: ProjectCard,
|
||||||
|
argTypes: {
|
||||||
|
title: { control: 'text' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
type Story = StoryObj<typeof ProjectCard>;
|
||||||
|
|
||||||
|
export const Default: Story = {
|
||||||
|
args: {
|
||||||
|
title: '프로젝트 제목',
|
||||||
|
},
|
||||||
|
};
|
43
frontend/src/components/ProjectCard/index.tsx
Normal file
43
frontend/src/components/ProjectCard/index.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { Compass } from 'lucide-react';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
interface ProjectCardProps {
|
||||||
|
title: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProjectCard({ title, imageUrl, onClick }: ProjectCardProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onClick={onClick}
|
||||||
|
className={cn('relative flex h-60 w-[295px] cursor-pointer flex-col items-center gap-3 bg-white')}
|
||||||
|
>
|
||||||
|
<div className={cn('flex w-full flex-1 items-center justify-center bg-gray-100')}>
|
||||||
|
{imageUrl ? (
|
||||||
|
<img
|
||||||
|
src={imageUrl}
|
||||||
|
alt={title}
|
||||||
|
className={cn('h-36 w-full object-cover')}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className={cn('flex h-full w-full items-center justify-center')}>
|
||||||
|
<Compass
|
||||||
|
className="h-12 w-12"
|
||||||
|
color="#757575"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={cn('flex w-full items-end px-4 pb-4')}>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'font-body mt-[-1px] w-fit whitespace-nowrap text-center text-[length:var(--body-font-size)] font-[number:var(--body-font-weight)] leading-[var(--body-line-height)] tracking-[var(--body-letter-spacing)] text-black'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user