Skip to content

Commit

Permalink
๐Ÿšš release sprint 5.0.1 (#113)
Browse files Browse the repository at this point in the history
* ๐ŸŽ‰ ์œ ์ €๋Š” ์ œ์•ˆ ์š”์ฒญ, ์ œ์•ˆ ์ˆ˜๋ฝ/๊ฑฐ์ ˆ, ๊ฑฐ๋ž˜ ์„ฑ์‚ฌ ์š”์ฒญ์— ๋Œ€ํ•œ ์•Œ๋ฆผ์„ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. (#97)

* ๐ŸŽ‰ ์•Œ๋ฆผ ์นด๋“œ ์ œ์ž‘ ๋ฐ ํŽ˜์ด์ง€ ์ด๋™ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์•Œ๋ฆผ ๋ฆฌ์ŠคํŠธ ์ œ์ž‘ ๋ฐ ์•Œ๋ฆผ ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์•Œ๋ฆผ ํƒญ ์ œ์ž‘ ๋ฐ ์•Œ๋ฆผ ์ข…๋ฅ˜๋ณ„ ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์ฝ์Œ ์ฒ˜๋ฆฌ ๋ฒ„ํŠผ ์ œ์ž‘ ๋ฐ ์ฝ์Œ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* โœจ ์ฑ„ํŒ…๋ฐฉ ๋ ˆ์ด์•„์›ƒ ๋ฐ ํƒ€์ž… ์กฐ์ •

* ๐Ÿ› ์ฐœ ๋ชฉ๋ก ์—ฐ๊ฒฐ ์•ˆ๋˜๋˜ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ

* ๐ŸŽ‰ ์ฑ„ํŒ…๋ฐฉ api ์—ฐ๊ฒฐ

* ๐ŸŽ‰ ์œ ์ €๋Š” ์ˆ˜๋ฝ๋œ ์ œ์•ˆ์œผ๋กœ ์ธํ•ด ์ƒ์„ฑ๋œ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก์„ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. (#102)

* ๐ŸŽ‰ ์ฑ„ํŒ…๋ฐฉ ์นด๋“œ ์ œ์ž‘ ๋ฐ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์ฑ„ํŒ…๋ฐฉ ๋ฆฌ์ŠคํŠธ ์ œ์ž‘ ๋ฐ ๋ฌดํ•œ์Šคํฌ๋กค ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์œ ์ €๋Š” ์ˆ˜๋ฝ๋œ ์ œ์•ˆ์œผ๋กœ ์ธํ•ด ์ƒ์„ฑ๋œ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก์„ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. (#104)

* ๐ŸŽ‰ ์ฑ„ํŒ…๋ฐฉ ์นด๋“œ ์ œ์ž‘ ๋ฐ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* ๐ŸŽ‰ ์ฑ„ํŒ…๋ฐฉ ๋ฆฌ์ŠคํŠธ ์ œ์ž‘ ๋ฐ ๋ฌดํ•œ์Šคํฌ๋กค ๊ธฐ๋Šฅ ๊ตฌํ˜„

* Merge branch 'develop' into NABI-301

* ๐ŸŽ‰ ๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์™„๋ฃŒ (#108)

* ๐Ÿšง complete request ์ƒํƒœ ํƒ€์ž… ์ง€์ •

* ๐Ÿšง get api ์ถ”๊ฐ€

* ๐Ÿšง ๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ์นด๋“œ ์ปดํฌ๋„ŒํŠธ

* ๐ŸŽ‰ ๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ์ปดํฌ๋„ŒํŠธ ๊ตฌํ˜„

* ๐Ÿšง ์ œ์•ˆ์š”์ฒญ ์ˆ˜๋ฝ/๊ฑฐ์ ˆ api ์—ฐ๊ฒฐ์ค‘

* ๐Ÿšง chatroom ํ…Œ์ŠคํŠธ์ค‘

* ๐ŸŽ‰ ๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์™„๋ฃŒ

* โœจ ์ฝ”๋“œ๋ฆฌ๋ทฐ ๋ฐ˜์˜

---------

Co-authored-by: Kim Dong Hyun <[email protected]>
Co-authored-by: oaoong <[email protected]>
  • Loading branch information
3 people authored Nov 26, 2023
1 parent c902421 commit 185b491
Show file tree
Hide file tree
Showing 55 changed files with 1,770 additions and 685 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@
"titleBar.inactiveForeground": "#e7e7e799"
},
"peacock.color": "#6C64F8",
"cSpell.words": ["Firestore"]
"cSpell.words": ["chatrooms", "Firestore"]
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
"firebase": "^10.6.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.292.0",
"next": "14.0.1",
"next": "14.0.3",
"next-themes": "^0.2.1",
"react": "^18",
"react-dom": "^18",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.47.0",
"sharp": "^0.32.6",
"swiper": "^11.0.3",
Expand Down
1,162 changes: 581 additions & 581 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions public/images/check-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/images/notification-bell.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/notification-dot.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions public/images/quit-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/images/switch-horizontal.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { cn } from '@/utils'

type ChatListProps = {
messages: Message[]
currentUserNickname?: string
currentUserId?: number
}

type ChatProps = {
Expand All @@ -14,15 +14,15 @@ type ChatProps = {
}

const ChatList = forwardRef<HTMLDivElement, ChatListProps>(
({ messages, currentUserNickname }, ref) => {
({ messages, currentUserId }, ref) => {
return (
<ul className="flex flex-col w-full h-full gap-1">
{messages.map((message: Message) => {
return (
<Chat
key={message.id}
message={message}
isMyMessage={message.sender === currentUserNickname}
isMyMessage={message.sender === currentUserId?.toString()}
/>
)
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@

import React, { useEffect, useRef } from 'react'
import { limit, orderBy, query, addDoc } from 'firebase/firestore'
import PageTitle from '@/components/domain/page-title'
import { CHAT_LIMIT } from '@/config/firebaseConfig'
import { useAuth } from '@/contexts/AuthProvider'
import useFirestoreQuery from '@/hooks/useFirestoreQuery'
import { useToast } from '@/hooks/useToast'
import { getMessageRef } from '@/lib/firebase'
import ChatInput from './components/ChatInput'
import ChatList from './components/ChatList'
import type { User } from '@/types/user'
import ChatInput from './ChatInput'
import ChatList from './ChatList'

const ChatPage = () => {
const { currentUser } = useAuth()
type ChatRoomTemplateProps = {
currentUser: User
fireStoreId: string
}

const ChatRoomTemplate = ({
currentUser,
fireStoreId,
}: ChatRoomTemplateProps) => {
const { toast } = useToast()

const messageRef = getMessageRef('room2') // TODO: room id๋ฅผ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ
const messageRef = getMessageRef(fireStoreId)
const messages = useFirestoreQuery(
query(messageRef, orderBy('createdAt', 'asc'), limit(CHAT_LIMIT)),
)
Expand All @@ -34,7 +40,7 @@ const ChatPage = () => {
try {
await addDoc(messageRef, {
text: message,
sender: currentUser?.nickname ?? '์ต๋ช…',
sender: currentUser?.userId.toString(),
createdAt: new Date(),
})
} catch (e) {
Expand All @@ -47,19 +53,17 @@ const ChatPage = () => {
}

return (
<main className="relative flex flex-col items-center w-full gap-10 h-page pb-chat_input">
<PageTitle title="์ฑ„ํŒ…๋ฐฉ" />
<section className="flex flex-col items-center px-2 overflow-scroll overflow-x-hidden">
<>
<section className="flex flex-col items-center w-full h-full px-2 overflow-scroll overflow-x-hidden">
<ChatList
messages={messages}
currentUserNickname={currentUser?.nickname}
currentUserId={currentUser?.userId}
ref={chatBottomRef}
/>
</section>
<ChatInput onSubmit={onSubmitMessage} />
<div className="w-full h-0 border border-t-background-secondary-color" />
</main>
</>
)
}

export default ChatPage
export default ChatRoomTemplate
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use client'

import Image from 'next/image'
import Button from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import Assets from '@/config/assets'
import { toast } from '@/hooks/useToast'
import { postCompleteRequest } from '@/services/complete-request/completeRequest'

type CompleteRequestButtonProps = {
myCardId: number
otherCardId: number
}

const CompleteRequestButton = ({
myCardId,
otherCardId,
}: CompleteRequestButtonProps) => {
const handleRequestButton = async () => {
try {
await postCompleteRequest(myCardId, otherCardId)
toast({
title: '๊ฑฐ๋ž˜์„ฑ์‚ฌ๋ฅผ ์š”์ฒญํ•˜์˜€์Šต๋‹ˆ๋‹ค',
variant: 'default',
duration: 2000,
})
} catch (error) {
toast({
title: '๊ฑฐ๋ž˜์„ฑ์‚ฌ ์š”์ฒญ์ด ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
variant: 'destructive',
duration: 2000,
})
}
}

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="ml-auto" size="icon_sm" variant={null}>
<Image src={Assets.vMoreIcon} alt="more" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="min-w-[8rem]">
<DropdownMenuGroup>
<DropdownMenuItem onClick={handleRequestButton}>
๊ฑฐ๋ž˜์„ฑ์‚ฌ ์š”์ฒญ
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}
export default CompleteRequestButton
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Image from 'next/image'
import Button from '@/components/ui/button'
import { Card, CardFlex, CardImage, CardText } from '@/components/ui/card/Card'
import Assets from '@/config/assets'
import { toast } from '@/hooks/useToast'
import { putCompleteRequest } from '@/services/complete-request/completeRequest'
import { Card as CardType } from '@/types/card'

const CardItem = ({
thumbnail,
itemName,
}: Pick<CardType, 'thumbnail' | 'itemName'>) => (
<CardFlex direction={'col'} justify={'center'} align={'center'} gap={'space'}>
<div className="h-11 w-20 relative">
<CardImage
alt="card-thumbnail"
src={thumbnail}
layout="fill"
objectFit="cover"
className="rounded"
/>
</div>
<CardText className="font-bold text-[12px] whitespace-nowrap overflow-hidden overflow-ellipsis">
{itemName}
</CardText>
</CardFlex>
)

type CompleteRequestCardProps = {
myCardData: CardType
otherCardData: CardType
}

const CompleteRequestCard = ({
myCardData,
otherCardData,
}: CompleteRequestCardProps) => {
const handleCompleteRequestUpdate = async (isAccepted: boolean) => {
try {
await putCompleteRequest(
otherCardData.cardId,
myCardData.cardId,
isAccepted,
)
window.location.reload()
toast({
title: `๊ฑฐ๋ž˜์„ฑ์‚ฌ ์š”์ฒญ์„ ${isAccepted ? '์ˆ˜๋ฝ' : '๊ฑฐ์ ˆ'}ํ•˜์˜€์Šต๋‹ˆ๋‹ค.`,
variant: 'default',
duration: 2000,
})
} catch (error) {
toast({
title: '๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ์ˆ˜๋ฝ ๋˜๋Š” ๊ฑฐ์ ˆ์ด ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.',
variant: 'destructive',
duration: 2000,
})
}
}
return (
<div>
<Card className="p-2 flex items-center border-0" size={'sm'}>
<CardFlex justify={'between'} className="gap-4">
<CardItem
thumbnail={myCardData.thumbnail}
itemName={myCardData.itemName}
/>
<CardFlex direction={'col'} align={'center'} justify={'center'}>
<CardText
type={'description'}
className="text-[12px] max-w-[125px] text-center"
>
๊ฑฐ๋ž˜์„ฑ์‚ฌ ์š”์ฒญ์ด ์™”์Šต๋‹ˆ๋‹ค. ๊ฑฐ๋ž˜๋ฅผ ํ•˜์…จ๋‚˜์š”?
</CardText>
<CardFlex direction={'row'} gap={'space'}>
<Button
className="ml-auto"
size="icon_sm"
variant={null}
onClick={() => handleCompleteRequestUpdate(true)}
>
<Image src={Assets.checkCircle} alt="accept" />
</Button>
<Button
className="ml-auto"
size="icon_sm"
variant={null}
onClick={() => handleCompleteRequestUpdate(false)}
>
<Image src={Assets.quitCircle} alt="refuse" />
</Button>
</CardFlex>
</CardFlex>
<CardItem
thumbnail={otherCardData.thumbnail}
itemName={otherCardData.itemName}
/>
</CardFlex>
</Card>
</div>
)
}

export default CompleteRequestCard
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Badge from '@/components/ui/badge'
import { COMPLETE_REQUEST_TYPE_OBJS } from '@/constants/card'
import { Card, CompleteRequestTypeObjs } from '@/types/card'
import { User } from '@/types/user'
import { getValueByKey } from '@/utils/getValueByKey'
import CompleteRequestCard from './CompleteRequestCard'

type CompleteReqeustTemplateProps = {
currentUser: User
completeRequestData: {
fromCard: { cardInfo: Card; userInfo: User }
toCard: { cardInfo: Card; userInfo: User }
status: CompleteRequestTypeObjs['key']
}
}

const CompleteReqeustTemplate = ({
currentUser,
completeRequestData: { fromCard, toCard, status },
}: CompleteReqeustTemplateProps) => {
//NOTE - ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ์ด ๊ฑฐ๋ž˜์„ฑ์‚ฌ ์š”์ฒญ ๋ฐ›์€ ์‚ฌ๋žŒ์ธ๊ฒฝ์šฐ + ์š”์ฒญ ์ƒํƒœ๊ฐ€ waiting์ธ ๊ฒฝ์šฐ - ๊ฑฐ๋ž˜์„ฑ์‚ฌ์š”์ฒญ ์นด๋“œ๊ฐ€ ๋ณด์ธ๋‹ค.
const isRequestedUser =
toCard.userInfo.userId === currentUser.userId && status === 'WAITING'
return isRequestedUser ? (
<CompleteRequestCard
myCardData={fromCard.cardInfo}
otherCardData={toCard.cardInfo}
/>
) : (
<Badge variant={'gradation'} size={'lg'} className="self-end mr-4">
{getValueByKey(COMPLETE_REQUEST_TYPE_OBJS, status)}
</Badge>
)
}

export default CompleteReqeustTemplate
Loading

0 comments on commit 185b491

Please sign in to comment.