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
3 changes: 2 additions & 1 deletion src/app/(with-header)/myprofile/_components/MyProfile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ export function MyProfile({ profileData, upLoadImgFile, upLoadUserData }: MuProf
<Button
text='적용하기'
onClick={onClickUploadButton}
className='rounded-[12px] px-[20px] py-[8px] text-lg tablet:px-[30px] tablet:py-[11px] mobile:px-[20px] mobile:py-[9px] mobile:text-md'
disabled={nickNameValue === ''}
className={`rounded-[12px] px-[20px] py-[8px] text-lg tablet:px-[30px] tablet:py-[11px] mobile:px-[20px] mobile:py-[9px] mobile:text-md ${nickNameValue === '' ? 'bg-gray-400' : ''}`}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import { useEffect, useState } from 'react';
import { fetchWithAuth } from '@/lib/auth';
import { MyProfile, MyProfileData } from './MyProfile';
import LoadingSpinner from '@/components/LoadingSpinner';

export default function MyProfileContainer() {
const [profileData, setProfileData] = useState<MyProfileData>();
const [isLoading, setIsLoading] = useState(true);

const getUserData = async () => {
try {
setIsLoading(true);
const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/users/me`);

if (!response?.ok || response === null) {
Expand All @@ -19,6 +22,8 @@ export default function MyProfileContainer() {
setProfileData(data);
} catch (error) {
console.error('유저 정보를 불러오는 중 문제가 발생했습니다:', error);
} finally {
setIsLoading(false);
}
};

Expand Down Expand Up @@ -71,6 +76,8 @@ export default function MyProfileContainer() {
getUserData();
}, []);

if (isLoading) return <LoadingSpinner className='h-[530px] w-[280px] rounded-[16px] border border-gray-300 shadow-drop tablet:h-[247px] tablet:w-full mobile:h-[241px]' />;

if (!profileData) return <div></div>;

return <MyProfile profileData={profileData} upLoadImgFile={upLoadImgFile} upLoadUserData={upLoadUserData} />;
Expand Down
33 changes: 17 additions & 16 deletions src/app/(with-header)/myprofile/_components/MyReviewItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,27 @@ import like from '@/assets/icons/star_hover.svg';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import MyReviewKebabDropDown from './MyReviewKebabDropDown';
import { MyReview } from '@/types/review-data';
import { EditReviewData } from './MyReviewListContainer';

interface MyReviewProps {
wineId: number;
id: number;
rating: number;
createdAt: string;
wineName: string;
content: string;
}

export function MyReviewItem({ wineId, id, rating, createdAt, wineName, content }: MyReviewProps) {
export function MyReviewItem({
reviewInitialData,
editMyReview,
deleteMyReview,
}: {
reviewInitialData: MyReview;
editMyReview: (id: number, editReviewData: EditReviewData, updatedAt: string) => void;
deleteMyReview: (id: number) => void;
}) {
const router = useRouter();
const reviewElapsedTime = elapsedTime(createdAt);
const reviewElapsedTime = elapsedTime(reviewInitialData.updatedAt);

const onClickReviewItem = (event: React.MouseEvent<HTMLElement>) => {
if ((event.target as HTMLElement).closest('.ignore-click')) {
event.stopPropagation();
return;
}
router.push(`/wines/${wineId}`);
router.push(`/wines/${reviewInitialData.wine.id}`);
};

return (
Expand All @@ -33,14 +34,14 @@ export function MyReviewItem({ wineId, id, rating, createdAt, wineName, content
<div className='relative flex gap-[15px]'>
<div className='flex h-[42px] w-[80px] items-center justify-center gap-[4px] rounded-[12px] bg-purple-10 tablet:h-[38px] mobile:h-[32px] mobile:w-[60px]'>
<Image className='w-[20px] mobile:w-[16px]' src={like} alt='별점 아이콘' />
<span className='text-2lg font-bold text-purple-100 mobile:text-md'>{rating.toFixed(1)}</span>
<span className='text-2lg font-bold text-purple-100 mobile:text-md'>{reviewInitialData.rating.toFixed(1)}</span>
</div>
<MyReviewKebabDropDown id={id} wineName={wineName} />
<MyReviewKebabDropDown id={reviewInitialData.id} reviewInitialData={reviewInitialData} editMyReview={editMyReview} deleteMyReview={deleteMyReview} />
<span className='flex items-center justify-center text-lg text-gray-500 mobile:text-md'>{reviewElapsedTime}</span>
</div>
<div className='flex flex-col gap-[10px]'>
<h3 className='text-lg font-medium text-gray-500 mobile:text-md'>{wineName}</h3>
<p className='text-lg font-normal text-gray-800 mobile:text-md'>{content}</p>
<h3 className='text-lg font-medium text-gray-500 mobile:text-md'>{reviewInitialData.wine.name}</h3>
<p className='text-lg font-normal text-gray-800 mobile:text-md'>{reviewInitialData.content}</p>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,20 @@ import Modal from '@/components/modal/Modal';
import DeleteWineForm from '@/components/modal/DeleteWineModal';
import { fetchWithAuth } from '@/lib/auth';
import PatchReviewForm from '@/components/modal/PatchReviewForm';
import { MyReview } from '@/types/review-data';
import { EditReviewData } from './MyReviewListContainer';

export default function MyReviewKebabDropDown({ wineName, id }: { wineName: string; id: number }) {
export default function MyReviewKebabDropDown({
reviewInitialData,
id,
editMyReview,
deleteMyReview,
}: {
reviewInitialData: MyReview;
id: number;
editMyReview: (id: number, editReviewData: EditReviewData, updatedAt: string) => void;
deleteMyReview: (id: number) => void;
}) {
const [isEditModalOpen, setIsEditModalOpen] = useState<boolean>(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(false);

Expand Down Expand Up @@ -38,9 +50,6 @@ export default function MyReviewKebabDropDown({ wineName, id }: { wineName: stri
try {
const response = await fetchWithAuth(`${process.env.NEXT_PUBLIC_BASE_URL}/reviews/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
});

if (!response?.ok || response === null) {
Expand All @@ -49,6 +58,9 @@ export default function MyReviewKebabDropDown({ wineName, id }: { wineName: stri

const body = await response.json();
if (body) {
if (deleteMyReview) {
deleteMyReview(id);
}
closeDeleteModal();
}
} catch (error) {
Expand All @@ -73,7 +85,7 @@ export default function MyReviewKebabDropDown({ wineName, id }: { wineName: stri
isEditModalOpen ? 'mobile:translate-y-0 mobile:animate-slide-up' : 'mobile:animate-slide-down mobile:translate-y-full'
}`}
>
<PatchReviewForm name={wineName} id={id} onClose={closeEditModal} />
<PatchReviewForm name={reviewInitialData.wine.name} id={id} onClose={closeEditModal} reviewInitialData={reviewInitialData} editMyReview={editMyReview} />
</Modal>
<Modal isOpen={isDeleteModalOpen} setIsOpen={setIsDeleteModalOpen} className='rounded-2xl mobile:mx-auto mobile:h-[172px] mobile:max-w-[353px]'>
<DeleteWineForm onClose={closeDeleteModal} onDelete={handleDeleteWine} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ import { fetchWithAuth } from '@/lib/auth';
import emptyData from '@/assets/icons/empty_review.svg';
import { MyReview, MyReviewResponse } from '@/types/review-data';
import { MyReviewItem } from './MyReviewItem';
import LoadingSpinner from '@/components/LoadingSpinner';

export interface EditReviewData {
rating: number;
lightBold: number;
smoothTannic: number;
drySweet: number;
softAcidic: number;
aroma: string[];
content: string;
wineId: number;
}

export default function MyReviewListContainer({ setDataCount }: { setDataCount: (value: number) => void }) {
const [myReviewData, setMyReviewData] = useState<MyReview[]>([]);
Expand All @@ -30,11 +42,26 @@ export default function MyReviewListContainer({ setDataCount }: { setDataCount:
}
}, [setDataCount]);

const deleteMyReview = (id: number) => {
const updatedReviewList = myReviewData.filter((value) => value.id !== id);
setMyReviewData(updatedReviewList);
};

const editMyReview = (id: number, editReviewData: EditReviewData, updatedAt: string) => {
const updatedReviewList = myReviewData.map((value) => {
if (value.id === id) {
return { ...value, ...editReviewData, updatedAt: updatedAt };
}
return value;
});
setMyReviewData(updatedReviewList);
};

useEffect(() => {
getMyReview();
}, [getMyReview]);

if (isLoading) return <div></div>;
if (isLoading) return <LoadingSpinner className='flex h-[228px] w-[800px] rounded-[16px] border border-gray-300 tablet:w-full mobile:w-full' />;

if (myReviewData.length === 0)
return (
Expand All @@ -47,7 +74,7 @@ export default function MyReviewListContainer({ setDataCount }: { setDataCount:
return (
<div className='flex flex-col gap-[8px] tablet:gap-[16px] mobile:gap-[16px]'>
{myReviewData.map((value) => (
<MyReviewItem key={value.id} rating={value.rating} createdAt={value.createdAt} wineName={value.wine.name} content={value.content} id={value.id} wineId={value.wine.id} />
<MyReviewItem key={value.id} reviewInitialData={value} editMyReview={editMyReview} deleteMyReview={deleteMyReview} />
))}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MyWineListResponse, WineDetails } from '@/types/wine';
import emptyData from '@/assets/icons/empty_review.svg';
import WineCard from '@/components/WineCard';
import { WineDataProps } from './MyWIneKebabDropDown ';
import LoadingSpinner from '@/components/LoadingSpinner';

export default function MyWineListContainer({ setDataCount }: { setDataCount: (value: number) => void }) {
const [myWineData, setMyWineData] = useState<WineDetails[]>([]);
Expand All @@ -32,8 +33,8 @@ export default function MyWineListContainer({ setDataCount }: { setDataCount: (v
}, [setDataCount]);

const deleteMyWine = (id: number) => {
const updatedReviewList = myWineData.filter((value) => value.id !== id);
setMyWineData(updatedReviewList);
const updatedWineList = myWineData.filter((value) => value.id !== id);
setMyWineData(updatedWineList);
};

const editMyWine = (id: number, editWineData: WineDataProps) => {
Expand All @@ -50,7 +51,7 @@ export default function MyWineListContainer({ setDataCount }: { setDataCount: (v
getMyWine();
}, [getMyWine]);

if (isLoading) return <div></div>;
if (isLoading) return <LoadingSpinner className='flex h-[228px] w-[800px] rounded-[16px] border border-gray-300 tablet:w-full mobile:w-full' />;

if (myWineData.length === 0)
return (
Expand Down
2 changes: 1 addition & 1 deletion src/app/(with-header)/myprofile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function Page() {
else if (category === '내가 등록한 와인') return <MyWineListContainer setDataCount={setDataCount} />;
}

const selectClassName = 'cursor-pointer text-xl font-bold text-gray-800 transition-all duration-300 hover:text-purple-100';
const selectClassName = 'cursor-pointer text-xl font-bold text-purple-100 transition-all duration-300 hover:text-purple-100';

const unSelectClassName = 'duration-300 cursor-pointer text-xl font-bold text-gray-500 transition-all hover:text-purple-100';

Expand Down