Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { NextConfig } from "next";
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
/* config options here */
images: {
domains: ['sprint-fe-project.s3.ap-northeast-2.amazonaws.com'],
},
};

export default nextConfig;
3 changes: 3 additions & 0 deletions src/app/(with-header-sidebar)/dashboard/[id]/page.tsx
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@21ow ์ง€์œค๋‹˜ ์ด๊ฑฐ ์ œ๊ฐ€ ์ถ”๊ฐ€ํ•ด๋†“์„๊ฒŒ์š” ์•„์ง ๋Œ€์‹œ๋ณด๋“œ์ชฝ์ž‘์—… ์•ˆํ•˜์‹ ๊ฒƒ๊ฐ™์•„์„œ
์™ผ์ชฝ ์•„์ด์ฝ˜ ๋ˆ„๋ฅด๋ฉด ๋Œ€์‹œ๋ณด๋“œ ํ™”๋ฉด ์ž˜๋œจ๋‚˜ ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ ๋กœ์ปฌ์—์„œ๋งŒ ์ผ์—ˆ๋Š”๋ฐ ์š”๊ฑฐ ๊ฐ€์ ธ๋‹ค ์“ฐ์‹œ๋ฉด ๋ ๊ฒƒ๊ฐ™์Šต๋‹ˆ๋‹ค!

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <div>dashboard page</div>;
}
17 changes: 10 additions & 7 deletions src/app/(with-header-sidebar)/mydashboard/hooks/useApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,26 @@ export default function useApi<
const [error, setError] = useState<AxiosError | null>(null);

const fetchData = useCallback(async () => {
// TODO if (loading) return; add?
setLoading(true);
setError(null);

const config = {
method: options.method,
url,
params: options.params,
data: options.body,
};

try {
const config = {
method: options.method,
url,
params: options.params,
data: options.body,
};
const response: AxiosResponse<T> = await axiosInstance.request(config);
setData(response.data);
} catch (err) {
setError(err as AxiosError);
} finally {
setLoading(false);
}
}, [url, options]);
}, [url, options.method, options.params, options.body]);

useEffect(() => {
fetchData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function useWindowSize(): WindowSize {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
isMobile: window.innerWidth <= 768,
isMobile: window.innerWidth < 768,
});
}

Expand Down
Binary file modified src/app/favicon.ico
Binary file not shown.
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const pretendard = localFont({
});

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
title: 'Taskify',
description: 'Task management application',
};

export default function RootLayout({
Expand Down
1 change: 1 addition & 0 deletions src/components/Button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
font-size: 14px;
font-weight: 600;
color: var(--white);
white-space: nowrap;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

์ด๊ฑฐ ๋ฒ„ํŠผ ๊ธ€์ž ๋งŽ์•„์ง€๋ฉด(?) ์ค„๋ฐ”๊ฟˆ ๋˜๋”๋ผ๊ตฌ์š”
๊ธฐ๋ณธ์œผ๋กœ ์•ˆ์ค„๋ฐ”๊ฟˆํ•˜๋ฉด ์ข‹์„๊ฒƒ๊ฐ™์•„ ์ถ”๊ฐ€ํ–ˆ์–ด์š”!

}

.button:disabled {
Expand Down
88 changes: 88 additions & 0 deletions src/components/Header.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,91 @@
.header {
padding: 16px;
border-bottom: 1px solid var(--gray-300);
display: flex;
justify-content: space-around;
align-items: center;
gap: 16px;
}

.title {
flex: 1;
color: var(--black-100);
font-size: 16px;
font-weight: 700;
}

.buttonContainer {
display: flex;
justify-content: space-between;
align-items: center;
gap: 6px;
}

.button {
padding: 6px 12px;
display: flex;
align-items: center;
gap: 8px;
background-color: transparent;
border-radius: 6px;
border: 1px solid var(--gray-300);
color: var(--gray-500);
font-size: 14px;
font-weight: 500;
}

.icon {
display: none;
}

.userInfoContainer {
display: flex;
align-items: center;
}

.userInfoContainer::before {
content: '';
border: 0.5px solid var(--gray-300);
height: 34px;
}

.userInfoWrapper {
margin-left: 16px;
display: flex;
align-items: center;
}

@media screen and (min-width: 768px) {
.header {
padding-left: 40px;
padding-right: 30px;
gap: 36px;
}

.title {
font-size: 20px;
}

.buttonContainer {
gap: 16px;
}

.button {
padding: 10px 16px;
font-size: 16px;
}

.userInfoWrapper {
margin-left: 36px;
}
}

@media screen and (min-width: 1199px) {
.header {
padding-right: 80px;
}

.icon {
display: block;
}
}
56 changes: 44 additions & 12 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
'use client';
import { usePathname } from 'next/navigation';
import Image from 'next/image';
import Button from './Button';
import UserInfo from './UserInfo';
import styles from './Header.module.css';
import type { User } from '@/app/(with-header-sidebar)/mydashboard/types/user';

const user: User = {
id: 1,
email: '[email protected]',
nickname: 'heejin',
profileImageUrl: null,
createdAt: '2024-11-15T14:29:07.482Z',
};
interface HeaderProps {
component: React.ComponentType;
}

export default function Header() {
export default function Header({ component: Component }: HeaderProps) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ํ—ค๋”์— ๋ณด๋ฉด ๋Œ€์‹œ๋ณด๋“œ์ชฝ์—๋งŒ ์‚ฌ๋žŒ๋“ค์•„์ด์ฝ˜..? ์žˆ๋Š”๊ฒŒ ์žˆ์–ด์„œ
์ด๋ถ€๋ถ„์€ ๋จธ๊ฐ€์˜ฌ์ง„ ๋ชจ๋ฅด์ง€๋งŒ~ ์ปดํฌ๋„ŒํŠธ๋ฅผ props๋กœ ๋ฐ›๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ
์ปดํฌ๋„ŒํŠธ ์ฑ„์šฐ๋Š” ํ˜•์‹์ด ์ข‹์„๊ฒƒ๊ฐ™์•„ ์ถ”ํ›„์ž‘์—…์šฉ์œผ๋กœ ์ƒ๊ฐํ•ด์ฃผ์‹œ๋ฉด ๋ ๊ฒƒ๊ฐ™์Šต๋‹ˆ๋‹ค

const pathname = usePathname();

const { nickname, profileImageUrl } = user;

return <header className={styles.header}>๋‚ด ๋Œ€์‹œ๋ณด๋“œ</header>;
return (
<header className={styles.header}>
<span className={styles.title}>๋‚ด ๋Œ€์‹œ๋ณด๋“œ</span>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

h2 ์“ฐ๋Š”๊ฒŒ ์ข‹์•„๋ณด์ด๋„ค์š” ์ถ”ํ›„ ์ˆ˜์ • ใ„ฑใ„ฑ (์…€ํ”„ ์ฝ”๋“œ๋ฆฌ๋ทฐ..ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹)

<div className={styles.buttonContainer}>
<Button className={styles.button}>
<Image
src="/icons/settings.svg"
alt="๊ด€๋ฆฌ"
width={20}
height={20}
className={styles.icon}
/>
๊ด€๋ฆฌ
</Button>
<Button className={styles.button}>
<Image
src="/icons/add_box.svg"
alt="์ดˆ๋Œ€ํ•˜๊ธฐ"
width={20}
height={20}
className={styles.icon}
/>
์ดˆ๋Œ€ํ•˜๊ธฐ
</Button>
</div>
{Component && (
<div>
<Component />
</div>
)}
<div className={styles.userInfoContainer}>
<div className={styles.userInfoWrapper}>
<UserInfo />
</div>
Copy link
Owner

Choose a reason for hiding this comment

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

userInfoContainer, userInfoWrapper ๋‘˜๋‹ค

display: flex;
align-items: center;

์ด ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ์ด๋ ‡๊ฒŒ ํ•˜์‹  ์ด์œ ๊ฐ€ ๋ญ”๊ฐ€์š”?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@najitwo ์ด๊ฒŒ.. ์ œ๊ฐ€ ํŒŒ์ดํ”„๋ผ์ธ ์ €๊ฑฐ๋ฅผ ๋”ฐ๋กœ ํƒœ๊ทธ์š”์†Œ ์ถ”๊ฐ€์•ˆํ•˜๊ณ  before ๊ฐ€์ƒํด๋ž˜์Šค ์‚ฌ์šฉํ•ด์„œ ํ‘œ์‹œ๋ฅผ ํ•˜๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ
๊ทธ๋ ‡๊ฒŒ ํ•˜๋‹ค๊ฐ€.. ๊ทธ ํŒŒ์ดํ”„๋ž‘ ์ด๋ฏธ์ง€ ์‚ฌ์ด์˜ ๊ฐญ์„ margin์„ ์ค˜์„œ ์ฒ˜๋ฆฌํ–ˆ๋Š”๋ฐ ๊ทธ๋ž˜์„œ div๊ฐ€ ์ถ”๊ฐ€๋˜๋‹ˆ๊นŒ ์ •๋ ฌ์ด ๋˜ ์•ˆ๋งž์•„์„œ..
container๊บผ๋ฅผ ์ง€์šฐ๋ฉด before๊ฐ€์ƒ์š”์†Œ ์“ด๊ฒŒ ํ‹€์–ด์ง€๊ณ 
wrapper๊บผ ์ง€์šฐ๋ฉด userInfo์ชฝ์ด ํ‹€์–ด์ง€๊ณ  ๐Ÿค—
๊ทธ๋ž˜์„œ ๊ฒฐ๋ก ์ด ์ด๋ ‡๊ฒŒ ๋‚˜๋ฒ„๋ ธ์Šต๋‹ˆ๋‹ค
ํ˜น์‹€ ๋” ์Œˆ๋ฐ•ํ•œ ๋ฐฉ๋ฒ•์ž‡์œผ๋ฉด ํ•œ์ˆ˜...๋ฐฐ์›Œ๋ณด๊ฒŸ์Šต๋‹ˆ๋‹ค ๐Ÿซก

Copy link
Owner

Choose a reason for hiding this comment

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

์˜ค... ์ง์ ‘ ํ•˜๋Š”๊ฑฐ ์•„๋‹ˆ๋ฉด ๊ฐ์ด ์•ˆ์žกํžˆ๋„ค์š” ใ…‹ใ…‹ใ…‹ใ…‹
๋‚˜์ค‘์— ํ•œ๋ฒˆ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ๐Ÿ˜Ž

</div>
</header>
);
}
8 changes: 7 additions & 1 deletion src/components/SideBar.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
}

.button {
background-color: transparent !important;
background-color: transparent;
}

.active {
color: salmon;
}

@media screen and (min-width: 768px) {
.sideBar {
min-width: 155px;
}
}
2 changes: 1 addition & 1 deletion src/components/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import Link from 'next/link';
import { usePathname } from 'next/navigation';
import styles from './SideBar.module.css';
import Image from 'next/image';
import Button from './Button';
import useWindowSize from '@/app/(with-header-sidebar)/mydashboard/hooks/useWindowSize';
import styles from './SideBar.module.css';

export default function SideBar() {
const pathname = usePathname();
Expand Down
25 changes: 25 additions & 0 deletions src/components/UserInfo.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.image {
border-radius: 50%;
object-fit: cover;
}

.userInfo {
display: flex;
align-items: center;
gap: 15px;
}

.userIcon {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}

.nickname {
color: var(--black-100);
font-size: 16px;
font-weight: 500;
}
76 changes: 76 additions & 0 deletions src/components/UserInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use client';

import type { User } from '@/app/(with-header-sidebar)/mydashboard/types/user';
import styles from './UserInfo.module.css';
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

์–˜ ๋˜ ์œ„๋กœ๊ฐ“๋„ค.. ๋‹ด์— ๋‚˜์ค‘์— ๋‚ด๋ฆด๊ฒŒ์š”~!

import Image from 'next/image';
import useWindowSize from '@/app/(with-header-sidebar)/mydashboard/hooks/useWindowSize';
import { useState, useEffect } from 'react';
import UserInfoSkeleton from './skeleton/UserInfoSkeleton';

const user: User = {
id: 1,
email: '[email protected]',
nickname: 'heejin',
// profileImageUrl:
// 'https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/taskify/profile_image/10-1_4804_1731757528194.jpeg',
profileImageUrl: null,
createdAt: '2024-11-15T14:29:07.482Z',
};

export default function UserInfo() {
const { email, nickname, profileImageUrl } = user;
const { isMobile } = useWindowSize();

const [colors, setColors] = useState<{
randomColor: string;
invertedColor: string;
} | null>(null);

useEffect(() => {
const { randomColor, invertedColor } = getRandomColor();
setColors({ randomColor, invertedColor });
}, []);

if (!colors) {
return <UserInfoSkeleton />;
}

return (
<>
{profileImageUrl ? (
<Image
src={profileImageUrl}
alt="ํ”„๋กœํ•„ ์ด๋ฏธ์ง€"
width={30}
height={30}
className={styles.image}
/>
) : (
<div className={styles.userInfo}>
<div
style={{
backgroundColor: colors.randomColor,
color: colors.invertedColor,
}}
className={styles.userIcon}
>
<span>{email[0].toUpperCase()}</span>
</div>
{!isMobile && <span className={styles.nickname}>{nickname}</span>}
</div>
)}
</>
);
}

function getRandomColor() {
const randomColor = `#${Math.floor(Math.random() * 16777215).toString(16)}`;

const r = parseInt(randomColor.slice(1, 3), 16);
const g = parseInt(randomColor.slice(3, 5), 16);
const b = parseInt(randomColor.slice(5, 7), 16);

const invertedColor = `rgb(${255 - r}, ${255 - g}, ${255 - b})`;

return { randomColor, invertedColor };
}
23 changes: 23 additions & 0 deletions src/components/skeleton/UserInfoSkeleton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.userIcon {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
background-color: var(--gray-300);
}

@media screen and (min-width: 768px) {
.userInfo {
display: flex;
align-items: center;
gap: 15px;
}

.nickname {
background-color: var(--gray-300);
width: 45px;
height: 20px;
}
}
Loading