Merge branch 'fe/feat/62-Footer' into 'fe/develop'
Feat : Footer컴포넌트 ui 구현 - S11P21S002-62 See merge request s11-s-project/S11P21S002!7
This commit is contained in:
commit
41af5db907
12
frontend/src/components/Footer/index.stories.tsx
Normal file
12
frontend/src/components/Footer/index.stories.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import Footer from './index';
|
||||||
|
|
||||||
|
const meta: Meta<typeof Footer> = {
|
||||||
|
title: 'Components/Footer',
|
||||||
|
component: Footer,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof Footer>;
|
||||||
|
|
||||||
|
export const Default: Story = {};
|
27
frontend/src/components/Footer/index.tsx
Normal file
27
frontend/src/components/Footer/index.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
export interface FooterProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||||
|
|
||||||
|
export default function Footer({ className, ...props }: FooterProps) {
|
||||||
|
return (
|
||||||
|
<footer
|
||||||
|
className={cn('mt-[100px] border-t border-gray-200 bg-gray-100', className)}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className="container py-10">
|
||||||
|
<div className="flex flex-col items-start gap-5">
|
||||||
|
<div className="relative">
|
||||||
|
<div className="font-heading text-lg text-gray-600 md:text-xl">WorLabel</div>
|
||||||
|
<p className="font-body-small mt-2 text-gray-500">Copyright © 2024 WorLabel All rights reserved</p>
|
||||||
|
</div>
|
||||||
|
<div className="inline-flex items-center gap-4">
|
||||||
|
<div className="font-body-small text-gray-500">서비스 이용약관</div>
|
||||||
|
<div className="h-4 w-px bg-gray-400" />
|
||||||
|
<div className="font-body-small text-gray-500">개인정보 처리방침</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
@ -22,7 +22,7 @@ export default function Header({ className, ...props }: HeaderProps) {
|
|||||||
>
|
>
|
||||||
WorLabel
|
WorLabel
|
||||||
</div>
|
</div>
|
||||||
<nav className="items-center hidden gap-5 md:flex">
|
<nav className="hidden items-center gap-5 md:flex">
|
||||||
<div className={cn('text-color-text-default-default', 'font-body-strong', 'text-sm sm:text-base md:text-lg')}>
|
<div className={cn('text-color-text-default-default', 'font-body-strong', 'text-sm sm:text-base md:text-lg')}>
|
||||||
workspace
|
workspace
|
||||||
</div>
|
</div>
|
||||||
@ -33,12 +33,12 @@ export default function Header({ className, ...props }: HeaderProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4 md:gap-5">
|
<div className="flex items-center gap-4 md:gap-5">
|
||||||
<img
|
<img
|
||||||
className="w-4 h-4 sm:h-5 sm:w-5"
|
className="h-4 w-4 sm:h-5 sm:w-5"
|
||||||
src={bellIcon}
|
src={bellIcon}
|
||||||
alt="Bell Icon"
|
alt="Bell Icon"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
className="w-4 h-4 sm:h-5 sm:w-5"
|
className="h-4 w-4 sm:h-5 sm:w-5"
|
||||||
src={userIcon}
|
src={userIcon}
|
||||||
alt="User Icon"
|
alt="User Icon"
|
||||||
/>
|
/>
|
||||||
|
@ -25,7 +25,7 @@ export default function Button({ isActive, text, onClick, progress = 0 }: Button
|
|||||||
>
|
>
|
||||||
<span className="relative z-10 font-sans text-base font-bold leading-6">{buttonText}</span>
|
<span className="relative z-10 font-sans text-base font-bold leading-6">{buttonText}</span>
|
||||||
<div
|
<div
|
||||||
className="absolute top-0 left-0 z-0 h-full duration-300 bg-white transition-width bg-opacity-20"
|
className="transition-width absolute left-0 top-0 z-0 h-full bg-white bg-opacity-20 duration-300"
|
||||||
style={{ width: `var(--progress-width, 0%)` }}
|
style={{ width: `var(--progress-width, 0%)` }}
|
||||||
></div>
|
></div>
|
||||||
</button>
|
</button>
|
||||||
|
@ -8,8 +8,8 @@ interface FileListProps {
|
|||||||
|
|
||||||
export default function FileList({ files, onRemoveFile }: FileListProps): JSX.Element {
|
export default function FileList({ files, onRemoveFile }: FileListProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full overflow-x-hidden overflow-y-auto max-h-52">
|
<div className="max-h-52 max-w-full overflow-y-auto overflow-x-hidden">
|
||||||
<ul className="p-0 m-0 list-none">
|
<ul className="m-0 list-none p-0">
|
||||||
{files.map((file, index) => (
|
{files.map((file, index) => (
|
||||||
<li
|
<li
|
||||||
key={index}
|
key={index}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { cn } from '@/lib/utils';
|
|
||||||
import CloseButton from './CloseButton';
|
import CloseButton from './CloseButton';
|
||||||
import Button from './Button';
|
import Button from './Button';
|
||||||
import FileList from './FileList';
|
import FileList from './FileList';
|
||||||
@ -65,51 +63,52 @@ export default function ImageUploadModal({ title, buttonText, onClose }: ImageUp
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-[610px]">
|
<div className="flex w-[610px] flex-col gap-10 rounded-3xl border px-10 py-5 shadow-lg">
|
||||||
<div className={cn('relative flex flex-col gap-5 rounded-2xl border border-gray-200 bg-white p-5 shadow-md')}>
|
<header className="flex items-center justify-between">
|
||||||
<div className="flex items-center justify-between">
|
<h1 className="small-title">{title}</h1>
|
||||||
<span className="font-sans text-2xl font-bold leading-tight text-gray-1000">{title}</span>
|
<button
|
||||||
<CloseButton onClick={handleClose} />
|
className="flex h-8 w-8 items-center justify-center"
|
||||||
</div>
|
onClick={handleClose}
|
||||||
<div className="flex flex-col gap-5">
|
>
|
||||||
<div className="flex justify-center">
|
<CloseButton />
|
||||||
<div
|
</button>
|
||||||
className={cn(
|
</header>
|
||||||
'relative flex h-44 w-full max-w-[570px] cursor-pointer items-center justify-center rounded-lg border-2 border-dashed border-primary bg-gray-100 p-5 text-center'
|
<div className="flex flex-col gap-5">
|
||||||
)}
|
|
||||||
onDrop={handleDrop}
|
|
||||||
onDragOver={handleDragOver}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="file"
|
|
||||||
multiple
|
|
||||||
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
|
|
||||||
onChange={handleFilesUpload}
|
|
||||||
/>
|
|
||||||
<p className="font-sans text-base font-normal leading-relaxed text-gray-500">
|
|
||||||
파일을 업로드하려면 클릭하거나
|
|
||||||
<br />
|
|
||||||
드래그하여 파일을 여기에 놓으세요
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{files.length > 0 && (
|
|
||||||
<div>
|
|
||||||
<FileList
|
|
||||||
files={files}
|
|
||||||
onRemoveFile={(index) => setFiles(files.filter((_, i) => i !== index))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-center">
|
<div className="flex justify-center">
|
||||||
<Button
|
<div
|
||||||
isActive={files.length > 0 && !isUploading}
|
className="relative flex h-44 w-full max-w-[570px] cursor-pointer items-center justify-center rounded-lg border-2 border-dashed border-primary bg-gray-100 p-5 text-center"
|
||||||
text={isUploading ? `업로드 중... (${uploadProgress}%)` : buttonText}
|
onDrop={handleDrop}
|
||||||
onClick={handleUpload}
|
onDragOver={handleDragOver}
|
||||||
progress={uploadProgress}
|
>
|
||||||
/>
|
<input
|
||||||
|
type="file"
|
||||||
|
multiple
|
||||||
|
className="absolute inset-0 h-full w-full cursor-pointer opacity-0"
|
||||||
|
onChange={handleFilesUpload}
|
||||||
|
/>
|
||||||
|
<p className="font-sans text-base font-normal leading-relaxed text-gray-500">
|
||||||
|
파일을 업로드하려면 클릭하거나
|
||||||
|
<br />
|
||||||
|
드래그하여 파일을 여기에 놓으세요
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{files.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<FileList
|
||||||
|
files={files}
|
||||||
|
onRemoveFile={(index) => setFiles(files.filter((_, i) => i !== index))}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<Button
|
||||||
|
isActive={files.length > 0 && !isUploading}
|
||||||
|
text={isUploading ? `업로드 중... (${uploadProgress}%)` : buttonText}
|
||||||
|
onClick={handleUpload}
|
||||||
|
progress={uploadProgress}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user