Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//wines/page.tsx 와인목록페이지
"use client";

import { useState, useCallback, useEffect } from "react";
Expand All @@ -16,7 +17,7 @@ import Search from "@/components/wines/search";
import RecommendCard from "@/components/wines/recommend-card";
import EntireCard from "@/components/wines/entire-card";
import FilterModal from "@/components/wines/modal/filter-modal";
import arrowRight from "../../../public/icons/right.svg";
import arrowRight from "../../../../public/icons/right.svg";
import "swiper/css";
import "swiper/css/navigation";
import { useAddWineModal } from "./AddWineModalProvider";
Expand Down
4 changes: 3 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//app/layout.tsx

import type { Metadata } from "next";
import "@/styles/globals.css";
import { AuthProvider } from "@/context/auth-provider";
import ClientWrapper from "@/components/common/nav-wrapper";
import { AddWineModalProvider } from "@/app/wines/AddWineModalProvider";
import { AddWineModalProvider } from "@/app/(user-wine)/wines/AddWineModalProvider";
import ReviewProvider from "@/provider/usereviewmodals";
import DarkThemeProvider from "@/components/common/theme-provider";
import DarkMode from "@/components/common/dark-mode-button";
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions src/components/modal-review/modal-review-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { useReviewModalStore } from "@/provider/usereviewmodals";
import { FormEvent, useEffect } from "react";
import Button from "@/components/common/Button";
import Modalv from "@/components/common/modal-container-review";
import ReviewInput from "@/components/modal-review/ReviewInput";
import TagSelector from "@/components/modal-review/TagSelector";
import TasteSlider from "@/components/modal-review/TasteSlider";
import ReviewInput from "@/components/modal-review/review-input";
import TagSelector from "@/components/modal-review/tag-selector";
import TasteSlider from "@/components/modal-review/taste-slider";
import { convertToAroma } from "@/utils/translate-aroma";
import {
useAddReview,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"use client";

import StarRating from "@/components/common/StarRating";
import TextArea from "@/components/common/TextArea";
import StarRating from "@/components/common/star-rating";
import TextArea from "@/components/common/text-area";
import { useReviewModalStore } from "@/provider/usereviewmodals";
import Image from "next/image";
import wine from "../../../public/icons/wine.svg";
import { useEffect, useState } from "react";
import { useEffect, useState, useCallback } from "react";
import instance from "@/api/api";

interface WineDetails {
Expand All @@ -17,10 +17,33 @@ interface WineIdProps {
content?: string;
}

const MAX_CHARS = 200;
const DEBOUNCE_DELAY = 300;

function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);

useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => {
clearTimeout(timer);
};
}, [value, delay]);

return debouncedValue;
}

export default function ReviewInput({ id, content }: WineIdProps) {
const { setContent, setRating } = useReviewModalStore();
const [wineName, setWineName] = useState<WineDetails | null>(null);
const [error, setError] = useState<string>("");
const [localContent, setLocalContent] = useState(content || "");
const [charCount, setCharCount] = useState(content?.length || 0);

const debouncedContent = useDebounce(localContent, DEBOUNCE_DELAY);

useEffect(() => {
if (id) {
Expand All @@ -36,16 +59,26 @@ export default function ReviewInput({ id, content }: WineIdProps) {
}
}, [id]);

const handleContentChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const newContent = e.target.value;
setContent(newContent);

if (newContent.length < 10) {
useEffect(() => {
setContent(debouncedContent);

if (debouncedContent.length < 10) {
setError("10자 이상 작성해주세요");
} else {
setError("");
}
};
}, [debouncedContent, setContent]);

const handleContentChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
const newContent = e.target.value;

if (newContent.length > MAX_CHARS) {
return;
}

setLocalContent(newContent);
setCharCount(newContent.length);
}, []);

const wineNameText = wineName ? wineName.name : "와인 이름 로딩 중...";

Expand All @@ -62,7 +95,7 @@ export default function ReviewInput({ id, content }: WineIdProps) {
/>
</div>
<div className="flex flex-col min-w-0 gap-[0.8rem]">
<p className="ml-[0.5rem] mt-[1rem] dark:text-dark-black break-words whitespace-normal text-lg tablet:text-2lg font-semiBold">
<p className="ml-[0.5rem] mt-[1rem] dark:text-dark-black break-words whitespace-normal text-lg tablet:text-2lg font-semiBold">
{wineNameText}
</p>

Expand All @@ -76,11 +109,15 @@ export default function ReviewInput({ id, content }: WineIdProps) {
<TextArea
id="content"
name="content"
value={content}
value={localContent}
placeholder="후기를 작성해주세요"
className="mb-[4rem] mt-[2.4rem] tablet:mb-[3.2rem] w-full h-[10rem] tablet:h-[12rem] p-[1.6rem] tablet:p-[2rem] text-[1.4rem] tablet:text-[1.6rem]"
onChange={handleContentChange}
maxLength={MAX_CHARS}
/>
<div className="absolute bottom-[1rem] right-[1.6rem] text-gray-500 text-sm">
{charCount}/{MAX_CHARS}
</div>
{error && (
<p className="absolute bottom-[1rem] left-[1.6rem] text-primary text-sm">
{error}
Expand All @@ -89,4 +126,4 @@ export default function ReviewInput({ id, content }: WineIdProps) {
</div>
</>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { useReviewModalStore } from "@/provider/usereviewmodals";
import { FormEvent, useEffect } from "react";
import Button from "@/components/common/Button";
import Modalv from "@/components/common/modal-container-review";
import ReviewInput from "@/components/modal-review/ReviewInput";
import TagSelector from "@/components/modal-review/TagSelector";
import TasteSlider from "@/components/modal-review/TasteSlider";
import ReviewInput from "@/components/modal-review/review-input";
import TagSelector from "@/components/modal-review/tag-selector";
import TasteSlider from "@/components/modal-review/taste-slider";
import instance from "@/api/api";
import { AxiosError, AxiosResponse } from "axios";
import { Aroma, mapTagToAroma } from "../wines/detail/detail-wine-tag";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { useReviewModalStore } from "@/provider/usereviewmodals";
import Chips from "@/components/common/Chips";
import Chips from "@/components/common/chips";
import { useEffect } from "react";

interface TagSelctorProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { useReviewModalStore } from "@/provider/usereviewmodals";
import Slider from "../common/Slider";
import Slider from "../common/slider";

// interface sliderDataType {
// label: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/myprofile/my-review-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MenuIcon from "@/../public/icons/menu.svg";
import DeleteModal from "../common/modal-delete";
import { useEffect, useState } from "react";
import instance from "@/api/api";
import AddReviewModal from "../modal-review/AddReviewModal";
import AddReviewModal from "../modal-review/review-modal";
import { Aroma, AromaMapping } from "../wines/detail/detail-wine-tag";
// import ReviewModal from "../modal-review/modal-review-edit";

Expand Down
2 changes: 1 addition & 1 deletion src/components/wines/detail/detail-no-review.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Image from "next/image";
import NoRievew from "@/../public/icons/no_review.svg";
import Button from "@/components/common/Button";
import { useState } from "react";
import AddReviewModal from "@/components/modal-review/AddReviewModal";
import AddReviewModal from "@/components/modal-review/review-modal";

interface DetailReviewCardProps {
wineid: string;
Expand Down
2 changes: 1 addition & 1 deletion src/components/wines/detail/detail-review-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import DetailWineTag, { Aroma, AromaMapping } from "./detail-wine-tag";
import StarFill from "@/../public/icons/star_fill.svg";
import { useEffect, useState } from "react";
import axios from "axios";
import AddReviewModal from "@/components/modal-review/AddReviewModal";
import AddReviewModal from "@/components/modal-review/review-modal";
import instance from "@/api/api";
import RatingDetails from "./rating-details";
import DetailNoReview from "./detail-no-review";
Expand Down
2 changes: 1 addition & 1 deletion src/components/wines/detail/rating-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import purpleStar from "../../../../public/icons/star_fill.svg";
import instance from "@/api/api";
import { AxiosError } from "axios";
import { useEffect, useState } from "react";
import AddReviewModal from "@/components/modal-review/AddReviewModal";
import AddReviewModal from "@/components/modal-review/review-modal";
import ReviewProvider from "@/provider/usereviewmodals";

interface RatingDetailsProps {
Expand Down