Skip to content

Commit

Permalink
[Feature/BAR-255] 메모가 없는 경우, 끄적이는 페이지 안내 메시지 노출 (#83)
Browse files Browse the repository at this point in the history
* feat: 글 수정 및 삭제시 토스트 노출

* fix: 메모 저장 해제인 경우, 툴팁 노출 제거

* refactor: WriteTabContent 컴포넌트 분리

* refactor: DayMessage 컴포넌트 적용 및 중복 코드 제거

* fix: 맞춤법 수정 사항이 없는 경우도 카드 메뉴 보이도록 수정

* feat: 신규 유저인 경우, 끄적이는 페이지 안내 메시지 노출

* style(Layout): min-width 값 적용
  • Loading branch information
dmswl98 authored Feb 23, 2024
1 parent 6433421 commit 7a8034a
Show file tree
Hide file tree
Showing 20 changed files with 284 additions and 182 deletions.
55 changes: 3 additions & 52 deletions pages/main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,81 +1,32 @@
import { useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useRef } from 'react';

import WriteInput from '@components/Input/WriteInput';
import Layout from '@components/Layout';
import MainPageTab from '@components/Layout/MainPageTab';
import { ROUTES } from '@constants/routes';
import WriteGuide from '@domain/끄적이는/components/Guide';
import TemporalMemoHistoryTable from '@domain/끄적이는/components/History';
import TodayTemoralMemos from '@domain/끄적이는/components/Today';
import useCreateTemporalMemo from '@domain/끄적이는/mutations/useCreateTemporalMemo';
import useGetWriteHistory from '@domain/끄적이는/queries/useGetHistory';
import * as styles from '@domain/끄적이는/style.css';
import WriteTabContent from '@domain/끄적이는/components/WriteTabContent';
import 참고하는TabContent from '@domain/참고하는/components';
import { useInput } from '@hooks/useInput';
import useGetMemoFolders from '@queries/useGetMemoFolders';
import useGetMyProfile from '@queries/useGetMyProfile';
import { COLORS } from '@styles/tokens';

const MainPage = () => {
const router = useRouter();
const searchParams = useSearchParams();

useGetMyProfile();

const writeContentRef = useRef<HTMLDivElement>(null);
const writeInput = useInput({ id: 'write-input' });
const { todayMemos, history } = useGetWriteHistory();
const { mutate: submitTemporalMemo } = useCreateTemporalMemo();
const { data: memoFolders } = useGetMemoFolders();

const selectedTab = searchParams.get('tab') || 'write';

useEffect(() => {
handleScroll();
}, [todayMemos]);

const handleScroll = () => {
if (writeContentRef.current) {
writeContentRef.current.scrollTop = writeContentRef.current.scrollHeight;
}
};
useGetMyProfile();

const handleTabSelect = (selectedTab: string) => {
router.push(`${ROUTES.MAIN}?tab=${selectedTab}`);
};

const handleSubmit = () => {
submitTemporalMemo(writeInput.value);
writeInput.reset();

handleScroll();
};

const backgroundColor =
selectedTab === 'refer' ? COLORS['Grey/100'] : undefined;

return (
<Layout backgroundColor={backgroundColor}>
<MainPageTab
write={
<div className={styles.container}>
<div ref={writeContentRef} className={styles.content}>
<WriteGuide />
<TemporalMemoHistoryTable
data={history}
memoFolders={memoFolders}
/>
<TodayTemoralMemos
memos={todayMemos[0]?.temporalMemos}
memoFolders={memoFolders}
/>
<div className={styles.inputWrapper}>
<WriteInput inputProps={writeInput} onSubmit={handleSubmit} />
</div>
</div>
</div>
}
write={<WriteTabContent />}
refer={<참고하는TabContent />}
selectedTab={selectedTab}
handleTabSelect={handleTabSelect}
Expand Down
2 changes: 1 addition & 1 deletion src/assets/icons/smileFace.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/assets/images/message.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/components/DayMessage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { type PropsWithChildren } from 'react';

import Icon from '@components/Icon';
import { type Icons } from '@constants/icon';

import * as styles from './style.css';

interface DayMessageProps {
icon?: Icons;
}

const DayMessage = ({ children, icon }: PropsWithChildren<DayMessageProps>) => {
return (
<div className={styles.wrapper}>
<div className={styles.message}>
{icon && <Icon icon={icon} width={20} height={20} />}
<span className={styles.text}>{children}</span>
</div>
</div>
);
};

export default DayMessage;
29 changes: 29 additions & 0 deletions src/components/DayMessage/style.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { style } from '@vanilla-extract/css';

import { sprinkles } from '@styles/sprinkles.css';
import { COLORS } from '@styles/tokens';
import * as utils from '@styles/utils.css';

export const wrapper = style([
utils.flexCenter,
{
marginTop: '12px',
marginBottom: '24px',
},
]);

export const message = style([
utils.flexCenter,
{
padding: '6px 28px',
border: `1px solid ${COLORS['Grey/200']}`,
borderRadius: '100px',
},
]);

export const text = style([
sprinkles({ typography: '15/Body/Medium' }),
{
marginLeft: '6px',
},
]);
10 changes: 4 additions & 6 deletions src/components/Dropdown/FolderDropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Folder } from '@api/memoFolder/types';
import Button from '@components/Button';
import TooltipButton from '@components/Button/components/TooltipButton';
import Dropdown from '@components/Dropdown';
import Icon from '@components/Icon';
Expand Down Expand Up @@ -29,12 +30,9 @@ const FolderDropdown = ({
return (
<>
{onClickBookmark ? (
<TooltipButton
isActive
icon="bookmark"
content="저장 해제"
onClick={onClickBookmark}
/>
<Button onClick={onClickBookmark}>
<Icon icon="bookmark" color={COLORS['Blue/Default']} />
</Button>
) : (
<Icon icon="bookmark" color={COLORS['Blue/Default']} />
)}
Expand Down
9 changes: 3 additions & 6 deletions src/domain/끄적이는/components/Card/Today/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ const WriteTodayCard = ({

const [spellCheckResult, setSpellCheckResult] =
useState<SpellCheckResponse>();
const {
mutateAsync: spellCheck,
isPending: isPendingSpellCheck,
isSuccess: isSuccessSpellCheck,
} = usePostSpellCheck();
const { mutateAsync: spellCheck, isPending: isPendingSpellCheck } =
usePostSpellCheck();

const handleSpellCheck = async () => {
const spellCheckResult = await spellCheck({
Expand Down Expand Up @@ -97,7 +94,7 @@ const WriteTodayCard = ({

return (
<Card color="blue" defaultIsVisibleMenu>
{!isSuccessSpellCheck && (
{!spellCheckResult?.result.suggestions.length && (
<Card.Menu>
<TooltipButton
icon="spelling"
Expand Down
60 changes: 55 additions & 5 deletions src/domain/끄적이는/components/Guide/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,61 @@
import Message from '@assets/images/message.svg';
import Card from '@components/Card';
import DayMessage from '@components/DayMessage';
import Icon from '@components/Icon';
import Responsive from '@components/Responsive';

import * as styles from './style.css';

const WriteGuide = () => {
const EXAMPLE_CARD = [
{
title: '자료 확인 요청',
description:
'안녕하세요, 바로님. 현재 baro 추천 상품 팝업 프로젝트에 대한 세부 기획 작업 진행 중입니다. 관련하여 첨부된 pdf 파일을 차주 목요일까지 확인 후 피드백 주시면 프로젝트 진행에 큰 도움이 될 것 같습니다. 감사합니다.',
},
{
title: '권한 요청',
description:
'안녕하세요, 바로님. 다름이 아니라 업무 진행을 위해 JIRA 권한을 받고자 하는데 시간 괜찮으실 때 권한 추가해 주실 수 있을까요?',
},
{
title: '일정 참석 요청',
description:
'바로님, 최종으로 업무 산출물 공유 드리기 전에 여쭤보고 싶은 마이너한 부분들이 있습니다. 혹시 시간 괜찮으실 때 논의 가능하실까요?',
},
];

interface GuideProps {
hasMemo: boolean;
}

const Guide = ({ hasMemo }: GuideProps) => {
return (
<p className={styles.guideText}>
끄적인 글은 일주일 후에 사라져요! 오래 간직하고 싶다면 저장해주세요 😊
</p>
<>
{hasMemo ? (
<p className={styles.guide}>
<span className={styles.guideText}>
끄적인 글은 일주일 후에 사라져요! 오래 간직하고 싶다면 저장해주세요
</span>
<Icon icon="smileFace" width={20} height={20} />
</p>
) : (
<div className={styles.newMemberGuide}>
<div className={styles.guideImage}>
<Message />
</div>
<DayMessage>끄적이는 예시</DayMessage>
<Responsive>
{EXAMPLE_CARD.map(({ title, description }) => (
<Card key={title} color="grey">
<Card.Header>{title}</Card.Header>
<Card.Body>{description}</Card.Body>
</Card>
))}
</Responsive>
</div>
)}
</>
);
};

export default WriteGuide;
export default Guide;
34 changes: 27 additions & 7 deletions src/domain/끄적이는/components/Guide/style.css.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
import { style } from '@vanilla-extract/css';

import { sprinkles } from '@styles/sprinkles.css';
import { COLORS } from '@styles/tokens';
import * as utils from '@styles/utils.css';

export const guideText = style({
marginTop: '220px',
marginBottom: '12px',
color: COLORS['Grey/500'],
textAlign: 'center',
fontSize: '15px',
fontWeight: '500',
export const guide = style([
utils.flexCenter,
{
marginTop: '220px',
marginBottom: '12px',
gap: '2px',
},
]);

export const guideText = style([
sprinkles({ typography: '15/Title/Medium' }),
{
color: COLORS['Grey/500'],
},
]);

export const newMemberGuide = style({
marginBottom: '48px',
});

export const guideImage = style({
display: 'flex',
justifyContent: 'center',
marginTop: '240px',
marginBottom: '64px',
});
28 changes: 0 additions & 28 deletions src/domain/끄적이는/components/History/index.css.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,8 @@
import { style } from '@vanilla-extract/css';

import { COLORS } from '@styles/tokens';

export const container = style({
marginBottom: '48px',
display: 'flex',
flexDirection: 'column',
gap: '64px',
});

export const dateLabelWrapper = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
marginTop: '12px',
marginBottom: '24px',
});

export const dateLabel = style({
padding: '6px 28px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: `1px solid ${COLORS['Grey/200']}`,
borderRadius: '100px',
});

export const dateLabelText = style({
marginLeft: '6px',
color: COLORS['Grey/700'],
fontSize: '15px',
fontWeight: 500,
lineHeight: '24px',
letterSpacing: '-0.2px',
});
Loading

0 comments on commit 7a8034a

Please sign in to comment.