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: 6 additions & 0 deletions src/constants/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ export const BOTTOM_SHEET_CONTENT = {
cancelText: null,
},
}

export const SEARCH_EXAMPLE =
'검색하고 싶은 근무지가 구의119안전센터일 경우\n1. 근무지 이름로 검색\nex) 구의\n\n2. 주소지로 검색(광진구 광나루로 480 (구의동))\nex) 광진구, 구의동, 광나루로'

export const SECRET_EXPLANATION =
'공개 시, 더 많은 사람들이 당신의 따뜻한 마음을 보고 공감할 수 있으며,\n특별한 메시지는 다양한 채널을 통해 소개될 수도 있습니다.\n비공개로 설정하면, 나만의 소중한 기록으로 남길 수 있어요.'
43 changes: 36 additions & 7 deletions src/containers/Share/Onboarding.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
import Header from '@/components/Header'
import useEmblaCarousel from 'embla-carousel-react'
import { twMerge } from 'tailwind-merge'
import FirstSlide from './FirstSlide'
import SecondSlide from './SecondSlide'
import ThirdSlide from './ThirdSlide'
import useAuthStore from '@/stores/authStore'
import { useDotButton } from '@/hooks/useDotButton'
import SolidButton from '@/components/SolidButton'
import { shareLink } from '@/utils/shareLink'
import { useEffect } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import Slide from './Slide'

export default function Onboarding() {
const nickname = useAuthStore((state) => state.user)?.nickname ?? ''
const [emblaRef, emblaApi] = useEmblaCarousel()
const { selectedIndex, scrollSnaps, onDotButtonClick } = useDotButton(emblaApi)
const queryClient = useQueryClient()

const SLIDE_DATA = [
{
title: `${nickname}님, 어두웠던 아파트를\n밝혀주셨어요`,
subtitle: '이제 가족, 친구들과 함께 더 많은 불빛을 켜볼까요?',
windowObj: { 0: nickname },
},
{
title: `공유하기 버튼을 눌러\n링크를 보내주세요`,
windowObj: { 0: nickname, 7: '내 친구', 9: '내 친구' },
},
{
title: `링크를 통해 감사메시지를 남기면\n불빛이 켜져요`,
subtitle: '함께하는 사람마다 불빛이 하나씩 늘어날거에요',
windowObj: { 0: nickname, 7: '내 친구', 9: '내 친구', 2: '' },
},
{
title: `${nickname}님의 공유 한 번이\n이 도시를 밝게 빛나게 할 수 있어요!`,
subtitle: `익숙하지 않은 이름이 보여도 놀라지 마세요\n${nickname}님의 선한 영향력을 받은 분이에요`,
windowObj: {
0: nickname,
7: '내 친구',
9: '내 친구',
2: '',
5: '',
8: '',
},
},
]

useEffect(() => {
document.body.style.overflowY = 'hidden'
return () => {
Expand All @@ -40,17 +67,19 @@ export default function Onboarding() {
<section className="flex w-full grow flex-col">
<div className="flex grow flex-col overflow-hidden" ref={emblaRef}>
<div className="flex grow touch-pan-y touch-pinch-zoom">
<FirstSlide nickname={nickname} />
<SecondSlide nickname={nickname} />
<ThirdSlide nickname={nickname} />
{SLIDE_DATA.map(({ title, subtitle, windowObj }) => (
<Slide title={title} subtitle={subtitle} windowObj={windowObj} />
))}
</div>
</div>
<SolidButton
variant="primary"
size="large"
className={twMerge(
'fixed bottom-[5%] left-1/2 z-20 w-[175px] -translate-x-1/2 rounded-full px-[30px] py-4 drop-shadow-[0_15px_25px_rgba(0,0,0,0.35)] transition-opacity duration-300',
selectedIndex === 2 ? 'opacity-100' : 'pointer-events-none opacity-0'
selectedIndex === SLIDE_DATA.length - 1
? 'opacity-100'
: 'pointer-events-none opacity-0'
)}
onClick={() => {
shareLink(nickname)
Expand Down
47 changes: 0 additions & 47 deletions src/containers/Share/SecondSlide.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,27 @@ import { BUILDING_WINDOW } from '@/constants/window'
import BuildingWindow from '@/containers/Share/BuildingWindow'
import { chunkWindow } from '@/utils/chunkWindow'

interface FirstSlideProps {
nickname: string
interface SlideProps {
title: string
subtitle?: string
windowObj: Record<number, string | undefined>
}

export default function FirstSlide({ nickname }: FirstSlideProps) {
export default function Slide({ title, subtitle, windowObj }: SlideProps) {
return (
<div className="relative flex w-full shrink-0 flex-col items-center">
<div className="h-[144px]">
<h1 className="headline-small w-sm:text-[20px] mb-5 text-center text-white">
{nickname}님, 어두웠던 아파트를
<br />
밝혀주셨어요.
</h1>
<p className="title-small text-neutral-30">하지만 아직 많이 어두운 것 같아요.</p>
<div className="mb-[50px] flex h-[110px] flex-col justify-between whitespace-pre-wrap">
<h1 className="headline-small text-center text-white w-sm:text-[20px]">{title}</h1>
<p className="title-small text-neutral-30">{subtitle}</p>
</div>
<div className="absolute top-[160px] z-[-10] h-[151px] w-[150px] rounded-full bg-[#C4EF66] blur-[77px]" />
<div className="absolute top-[170px] z-[-10] h-[151px] w-[150px] rounded-full bg-[#C4EF66] blur-[77px]" />
<section className="w-full max-w-[375px] grow overflow-hidden bg-[#262831] pb-24">
<div className="roof-background mt-[-7px] h-[29px]" />
<div className="h-3 w-full bg-[#3E3E42]" />
<div className="flex flex-col gap-3 px-10 pt-7">
{chunkWindow(
BUILDING_WINDOW.slice(0, 12).map((window, index) => (
<BuildingWindow key={index} imgSrc={window} name={index === 0 ? nickname : null} />
<BuildingWindow key={index} imgSrc={window} name={windowObj[index] ?? null} />
))
).map((row, index) => (
<div key={index} className="flex justify-between">
Expand Down
46 changes: 0 additions & 46 deletions src/containers/Share/ThirdSlide.tsx

This file was deleted.

2 changes: 2 additions & 0 deletions src/containers/Write/BottomSheet/CheckAlarm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export default function CheckAlarm() {

if (result) {
await queryClient.invalidateQueries({ queryKey: ['messages'] })
await queryClient.invalidateQueries({ queryKey: ['my-messages'] })
await queryClient.invalidateQueries({ queryKey: ['main-data'] })
toggleShareLink()
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/containers/Write/Funnel/MessagesCollection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function MessagesCollection() {
)}
<div className="grow">
<h2 className="body-large my-5 text-neutral-30">
다른 사람이 작성한 감사 메시지를
다른 사람들이 작성한 감사 메시지를
<br />
참고해 작성해보세요!
</h2>
Expand Down
4 changes: 2 additions & 2 deletions src/containers/Write/Funnel/NewsCollection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export default function NewsCollection() {
return (
<div className="grow">
<h2 className="body-large my-5 text-neutral-30">
다른 사람이 작성한 감사 메시지를
경찰·소방관님의 이야기를 읽고,
<br />
참고해 작성해보세요!
감사의 마음을 전해보세요.
</h2>
<section className="flex flex-col gap-5">
{news.map((item) => (
Expand Down
3 changes: 2 additions & 1 deletion src/containers/Write/Funnel/SearchOffice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SearchResultItem from './SearchResultItem'
import { useState } from 'react'
import useWriteMessageStore from '@/stores/writeMessageStore'
import { getSearchResult } from '@/apis/message'
import { SEARCH_EXAMPLE } from '@/constants/write'

interface SearchOfficeProps {
onCompleteSelect: () => void
Expand Down Expand Up @@ -70,7 +71,7 @@ export default function SearchOffice({ onCompleteSelect }: SearchOfficeProps) {
) : (
<>
<h3 className="label-large text-white">이렇게 검색해보세요!</h3>
<p className="body-medium text-neutral-50">ex) 강동구</p>
<p className="body-medium whitespace-pre-wrap text-neutral-50">{SEARCH_EXAMPLE}</p>
</>
)}
</section>
Expand Down
7 changes: 5 additions & 2 deletions src/containers/Write/Funnel/WriteMessage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { postMessage } from '@/apis/message'
import Checkbox from '@/components/Checkbox'
import SolidButton from '@/components/SolidButton'
import { MESSAGE_MAX_LENGTH } from '@/constants/write'
import { MESSAGE_MAX_LENGTH, SECRET_EXPLANATION } from '@/constants/write'
import useAuthStore from '@/stores/authStore'
import useWriteBottomStore from '@/stores/writeBottomStore'
import useWriteMessageStore from '@/stores/writeMessageStore'
Expand Down Expand Up @@ -47,6 +47,7 @@ export default function WriteMessage() {

if (result) {
await queryClient.invalidateQueries({ queryKey: ['my-messages'] })
await queryClient.invalidateQueries({ queryKey: ['main-data'] })
navigate('/', { state: { from: 'write' } })
}
}
Expand Down Expand Up @@ -81,7 +82,6 @@ export default function WriteMessage() {
disabled={showCollectionIntro || showCheckAlarm || showShareLink}
onChange={handleMessageChange}
/>
{/* TODO: 닉네임 받아서 넣기 */}
<div className="flex justify-between text-neutral-50">
<p className="title-small">From. {nickname}</p>
<p className="label-medium">
Expand All @@ -100,6 +100,9 @@ export default function WriteMessage() {
/>
<span>비공개로 작성하기</span>
</label>
<p className="body-small mt-2 whitespace-pre-wrap text-neutral-40">
{SECRET_EXPLANATION}
</p>
</div>
</section>
<SolidButton variant="primary" size="large" type="submit" disabled={content.trim() === ''}>
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useNews.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getNews } from '@/apis/news'
import { useInfiniteQuery } from '@tanstack/react-query'

const NEWS_SIZE = 5
const NEWS_SIZE = 10

export const useGetNews = () => {
return useInfiniteQuery({
Expand Down
33 changes: 18 additions & 15 deletions src/pages/MyMessageDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Header from '@/components/Header'
import Loading from '@/components/Loading'
import OutlinedButton from '@/components/OutlinedButton'
import SolidButton from '@/components/SolidButton'
import { SECRET_EXPLANATION } from '@/constants/write'
import MyMessageCard from '@/containers/Message/MyMessageCard'
import useBodyBackgroundColor from '@/hooks/useBodyBackgroundColor'
import { useGetMyMessageDetail } from '@/hooks/useMessage'
Expand Down Expand Up @@ -83,21 +84,23 @@ export default function MyMessageDetail() {
<>
<section className="flex grow flex-col">
{data && <MyMessageCard message={data.letterInfo} isShort={false} />}
<p className="label-large-prominent mb-1 mt-6 text-white">공개 여부 설정</p>
<p className="body-medium mb-5 text-neutral-40">
비공개로 설정 시, 다른 유저들이 메시지를 확인할 수 없어요.
</p>
<label
htmlFor="isPrivate"
className="label-medium flex cursor-pointer items-center gap-2 text-white"
>
<Checkbox
id="isPrivate"
checked={isPrivate}
onChange={() => setIsPrivate((prev) => !prev)}
/>
<span>비공개</span>
</label>
<p className="label-large-prominent mb-2 mt-6 text-white">공개 여부 설정</p>
<div>
<label
htmlFor="isPrivate"
className="label-medium flex cursor-pointer items-center gap-2 text-white"
>
<Checkbox
id="isPrivate"
checked={isPrivate}
onChange={() => setIsPrivate((prev) => !prev)}
/>
<span>비공개</span>
</label>
<p className="body-small mt-2 whitespace-pre-wrap text-neutral-40">
{SECRET_EXPLANATION}
</p>
</div>
</section>
<section className="flex gap-[15px]">
<OutlinedButton
Expand Down