Skip to content

Commit

Permalink
Merge pull request #106 from DDD-Community/97-feature-폴라로이드-디자인-개선
Browse files Browse the repository at this point in the history
[FEATURE/97] 폴라로이드 디자인 개선, 닉네임 추가
  • Loading branch information
junseublim authored Sep 3, 2024
2 parents 52a806a + d142e27 commit 0110906
Show file tree
Hide file tree
Showing 27 changed files with 594 additions and 389 deletions.
2 changes: 2 additions & 0 deletions src/app/(board)/board/[boardId]/_actions/uploadAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const uploadAction = async (id: string, formData: FormData) => {
try {
const fileInput = formData.get('fileInput')
const oneLineMessage = formData.get('oneLineMessage')
const nickname = formData.get('nickname')

if (!fileInput || !(fileInput instanceof File)) {
throw new Error('Invalid file input')
Expand All @@ -18,6 +19,7 @@ export const uploadAction = async (id: string, formData: FormData) => {
const res = await postPolaroid(id, {
imageKey,
oneLineMessage: oneLineMessage as string,
nickname: nickname as string,
})
return res
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import Button from '@/components/Button'
import { useState } from 'react'
import { useFormStatus } from 'react-dom'
import FinalModal from '../modals/FinalModal'

interface UploadBtnProps {
formRef: React.RefObject<HTMLFormElement>
btnDisabled: boolean
submitForm: () => Promise<void>
}

const UploadBtn = ({ formRef, btnDisabled }: UploadBtnProps) => {
const UploadBtn = ({ submitForm, btnDisabled }: UploadBtnProps) => {
const [showFinalModal, setShowFinalModal] = useState<boolean>(false)
const { pending } = useFormStatus()
const [isPending, setIsPending] = useState<boolean>(false)

const onSubmit = () => {
if (formRef.current) {
formRef.current.requestSubmit()
}
const onSubmit = async () => {
setIsPending(true)
await submitForm()
setIsPending(false)
}

return (
Expand All @@ -25,7 +24,7 @@ const UploadBtn = ({ formRef, btnDisabled }: UploadBtnProps) => {
onClick={() => setShowFinalModal(true)}
size="lg"
className="w-full"
disabled={pending || btnDisabled}
disabled={isPending || btnDisabled}
>
업로드하기
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
'use client'

import { useEffect, useState } from 'react'
import { useSession } from 'next-auth/react'
import { getPolaroidNickname } from '@/lib/utils/polaroid'
import PolaroidMaker from '@/components/Polaroid/PolaroidMaker'
import { useRef, useState } from 'react'
import { uploadAction } from '../../_actions/uploadAction'
import ArrowBack from './ArrowBack'
import { useModal } from './ModalContext'
Expand All @@ -12,35 +14,49 @@ interface CreatePolaroidProps {
}

const CreatePolaroid = ({ id }: CreatePolaroidProps) => {
const formRef = useRef<HTMLFormElement>(null)
const [btnDisabled, setBtnDisabled] = useState<boolean>(true)
const [isValid, setIsValid] = useState<boolean>(false)
const [image, setImage] = useState<File | null>(null)
const [nickname, setNickname] = useState<string>('')
const [message, setMessage] = useState<string>('')
const { closeModal } = useModal()
const [compressedFile, setCompressedFile] = useState<File | null>(null)

useEffect(() => {
setIsValid(!!image)
}, [image])

const { data: session } = useSession()

const submit = async () => {
if (!isValid) {
return
}

const formData = new FormData()
formData.append('fileInput', image!)
formData.append('oneLineMessage', message)
formData.append('nickname', getPolaroidNickname(nickname, session))

const res = await uploadAction(id, formData)

if (res) {
closeModal()
}
}

return (
<div className="mx-auto flex h-dvh max-w-md flex-1 flex-col justify-between px-5 py-10">
<div className="w-md mx-auto flex h-dvh max-w-md flex-1 flex-col justify-between px-5 py-10">
<ArrowBack />
<form
action={async (formData) => {
if (compressedFile) {
formData.set('fileInput', compressedFile)
}

const res = await uploadAction(id, formData)
if (res) {
closeModal()
}
}}
ref={formRef}
>
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform">
<PolaroidMaker
setBtnDisabled={setBtnDisabled}
setCompressedFile={setCompressedFile}
/>
</div>
<UploadBtn formRef={formRef} btnDisabled={btnDisabled} />
</form>
<div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform">
<PolaroidMaker
image={image}
message={message}
nickname={nickname}
setImage={setImage}
setMessage={setMessage}
setNickname={setNickname}
/>
</div>
<UploadBtn submitForm={submit} btnDisabled={!isValid} />
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useEffect, useState } from 'react'
import { Polaroid } from '@/types'
import PolaroidCard from '@/components/Polaroid/PolaroidCard'

interface PolaroidListItemProps {
item: Polaroid
onClick: () => void
}

const PolaroidListItem = ({ item, onClick }: PolaroidListItemProps) => {
const [rotate, setRotate] = useState<number>(0)
useEffect(() => {
const randomRotate =
Math.random() > 0.5 ? Math.random() + 1 : Math.random() * -1 - 1
setRotate(randomRotate)
}, [])

return (
<div
className="flex flex-col justify-center"
onClick={onClick}
style={{ rotate: `${rotate}deg` }}
>
<PolaroidCard polaroid={item} />
</div>
)
}

export default PolaroidListItem
43 changes: 43 additions & 0 deletions src/app/(board)/board/[boardId]/_components/PolaroidList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use client'

import { Polaroid } from '@/types'
import { useState } from 'react'
import PolaroidDetailModal from '@/components/Polaroid/PolaroidDetail'
import PolaroidListItem from './PolaroidListItem'

interface PolaroidListProps {
polaroids: Polaroid[]
}

const PolaroidList = ({ polaroids }: PolaroidListProps) => {
const [isModalOpen, setIsModalOpen] = useState(false)
const [selectedPolaroid, setSelectedPolaroid] = useState<Polaroid | null>(
null,
)

const openDetailModal = (polaroid: Polaroid) => {
setSelectedPolaroid(polaroid)
setIsModalOpen(true)
}

return (
<div className="mx-auto w-full flex-1 overflow-x-hidden overflow-y-scroll scrollbar-hide">
<div className="grid grid-cols-2 gap-6 px-[20px] py-[10px]">
{polaroids.map((item) => (
<PolaroidListItem
key={item.id}
item={item}
onClick={() => openDetailModal(item)}
/>
))}
</div>
<PolaroidDetailModal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
polaroid={selectedPolaroid}
/>
</div>
)
}

export default PolaroidList
14 changes: 2 additions & 12 deletions src/app/(board)/board/[boardId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { auth } from '@/auth'
import Hamburger from '@/components/HamburgerMenu'
import Header from '@/components/Header'
import PolaroidCard from '@/components/Polaroid/PolaroidCard'
import { getBoard } from '@/lib'
import { Metadata } from 'next'
import PinIcon from 'public/icons/pinFilled.svg'
import PolaroidList from '@/app/(board)/board/[boardId]/_components/PolaroidList'
import CreatePolaroid from './_components/CreatePolaroidModal'
import { ModalProvider } from './_components/CreatePolaroidModal/ModalContext'
import Empty from './_components/Empty'
Expand Down Expand Up @@ -80,17 +80,7 @@ const BoardPage = async ({ params }: BoardPageProps) => {
{board.items.length === 0 ? (
<Empty />
) : (
<div className="mx-auto flex-1 overflow-x-hidden overflow-y-scroll scrollbar-hide">
<div className="grid grid-cols-2 gap-3 p-[10px]">
{board.items.map((item) => (
<PolaroidCard
key={item.id}
imageUrl={item.imageUrl}
oneLineMessage={item.oneLineMessage}
/>
))}
</div>
</div>
<PolaroidList polaroids={board.items} />
)}

<ModalProvider>
Expand Down
113 changes: 0 additions & 113 deletions src/components/Polaroid/Base.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions src/components/Polaroid/Base/PolaroidDescription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { HTMLAttributes } from 'react'
import { twMerge } from 'tailwind-merge'

const PolaroidDescription = ({
children,
className,
...props
}: HTMLAttributes<HTMLDivElement>) => {
return (
<div
className={`${twMerge('flex flex-col gap-0.5 px-4 pb-2', className)}`}
style={{
background:
'linear-gradient(180deg, rgba(255, 255, 255, 0.20) 10.71%, rgba(255, 255, 255, 0.50) 57.96%, rgba(255, 255, 255, 0.00) 100%), #EAEAEA',
}}
{...props}
>
{children}
</div>
)
}

export default PolaroidDescription
Loading

0 comments on commit 0110906

Please sign in to comment.