From e16606973e687ad533ae136275fa1bd33756ae0c Mon Sep 17 00:00:00 2001 From: yunhwancho Date: Tue, 15 Oct 2024 01:35:55 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=BA=98=EB=A6=B0=EB=8D=94=20=EB=B0=8F?= =?UTF-8?q?=20=ED=8B=B0=EC=BC=93ui?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/post/page.tsx | 1485 +++++++++++--------- src/components/board/CalendarModal2.tsx | 26 +- src/components/board/DateInput2.tsx | 28 +- src/components/profile/UserInformation.tsx | 20 +- src/components/testEditor/textEditor2.tsx | 162 ++- 5 files changed, 940 insertions(+), 781 deletions(-) diff --git a/src/app/post/page.tsx b/src/app/post/page.tsx index 5b67b231..6660e192 100644 --- a/src/app/post/page.tsx +++ b/src/app/post/page.tsx @@ -1,732 +1,859 @@ -"use client" -import Header from '@/components/shared/header/Header' -import React, { ChangeEvent, useEffect, useState } from 'react' -import Image from 'next/image' -import searchicon from '@/dummy/search.svg' -import uploadImages from "@/dummy/uploadfile.svg" -import date from "@/dummy/date.svg" +"use client"; +import Header from "@/components/shared/header/Header"; +import React, { ChangeEvent, useEffect, useState } from "react"; +import Image from "next/image"; +import searchicon from "@/dummy/search.svg"; +import uploadImages from "@/dummy/uploadfile.svg"; +import date from "@/dummy/date.svg"; import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; -import postBoard from '@/services/board/post/postBoard' -import { uploadImage } from '@/services/blog' -import { UploadedImage } from '@/types/ootd' -import { useRouter } from 'next/navigation' -import Swal from 'sweetalert2' -import { colorTicket } from '@/types/board' -import MyTinyMCEEditor from '@/components/testEditor/textEditor2' -import { getCountry, getCountry1 } from '@/services/board/get/getCountry' -import { PostAirSVG, PostBusSVG, PostBycicleSVG, PostCarSVG, PostTrainSVG } from '@/components/transportsvg/post' -import { useQuery } from 'react-query' -import { MemberInfo } from '@/services/auth' -import Cookies from "js-cookie" -import DateInput from '@/components/ootd/DateInput' -import DateInput2 from '@/components/board/DateInput2' -import Editor from '@/components/testEditor/textEditors' -import Write from '@/components/testEditor/textEditors' +import postBoard from "@/services/board/post/postBoard"; +import { uploadImage } from "@/services/blog"; +import { UploadedImage } from "@/types/ootd"; +import { useRouter } from "next/navigation"; +import Swal from "sweetalert2"; +import { colorTicket } from "@/types/board"; +import MyTinyMCEEditor from "@/components/testEditor/textEditor2"; +import { getCountry, getCountry1 } from "@/services/board/get/getCountry"; +import { + PostAirSVG, + PostBusSVG, + PostBycicleSVG, + PostCarSVG, + PostTrainSVG, +} from "@/components/transportsvg/post"; +import { useQuery } from "react-query"; +import { MemberInfo } from "@/services/auth"; +import Cookies from "js-cookie"; +import DateInput from "@/components/ootd/DateInput"; +import DateInput2 from "@/components/board/DateInput2"; +import Editor from "@/components/testEditor/textEditors"; +import Write from "@/components/testEditor/textEditors"; interface CountryResult { - countryIsoAlp2: string; - // 다른 필요한 필드 추가 + countryIsoAlp2: string; + // 다른 필요한 필드 추가 } interface ApiResponse { - result: CountryResult; + result: CountryResult; } interface CountryResult { - // 기존 프로퍼티들... - isoAlp3?: string; // isoAlp3 프로퍼티 추가 (선택적) + // 기존 프로퍼티들... + isoAlp3?: string; // isoAlp3 프로퍼티 추가 (선택적) } function PostWrite() { - const [bgColor, setBgColor] = useState('#55FBAF'); - const [thumbnailPreview, setThumbnailPreview] = useState(null); - const [isTransport, setIsTransport] = useState(false); - const [passengerCount, setPassengerCount] = useState(0); - const [startDate, setStartDate] = useState(null); - const [endDate, setEndDate] = useState(null); - const [dateOpen, setDateOpen] = useState(false); - const [title, setTitle] = useState(''); - const [body, setBody] = useState(''); - const [images, setImages] = useState([]); - const [isImages, setIsImages] = useState([]); - const router = useRouter(); - const [inputValue1, setInputValue1] = useState(''); - const [inputValue2, setInputValue2] = useState(''); - const [suggestions1, setSuggestions1] = useState([]); - const [suggestions2, setSuggestions2] = useState([]); - const [selectedCountryCode, setSelectedCountryCode] = useState(''); - const [selectedCountryCode2, setSelectedCountryCode2] = useState(''); - const [tags, setTags] = useState([]); - const [inputValue, setInputValue] = useState(''); - const [ticketColor, setTicketColor] = useState('Aquamarine') - const [isImageIdx, setIsImageIdx] = useState([]); - const [postRequests, setPostRequests] = useState({ - body: '', - images: [] as string[], // 이미지 URL을 저장할 배열 + const [bgColor, setBgColor] = useState("#55FBAF"); + const [thumbnailPreview, setThumbnailPreview] = useState(null); + const [isTransport, setIsTransport] = useState(false); + const [passengerCount, setPassengerCount] = useState(0); + const [startDate, setStartDate] = useState(null); + const [endDate, setEndDate] = useState(null); + const [dateOpen, setDateOpen] = useState(false); + const [title, setTitle] = useState(""); + const [body, setBody] = useState(""); + const [images, setImages] = useState([]); + const [isImages, setIsImages] = useState([]); + const router = useRouter(); + const [inputValue1, setInputValue1] = useState(""); + const [inputValue2, setInputValue2] = useState(""); + const [suggestions1, setSuggestions1] = useState([]); + const [suggestions2, setSuggestions2] = useState([]); + const [selectedCountryCode, setSelectedCountryCode] = useState(""); + const [selectedCountryCode2, setSelectedCountryCode2] = useState(""); + const [tags, setTags] = useState([]); + const [inputValue, setInputValue] = useState(""); + const [ticketColor, setTicketColor] = useState("Aquamarine"); + const [isImageIdx, setIsImageIdx] = useState([]); + const [postRequests, setPostRequests] = useState({ + body: "", + images: [] as string[], // 이미지 URL을 저장할 배열 + }); + // console.log(postRequests) + const [result, setResult] = useState(null); + const [result1, setResult1] = useState(null); + const [transportStr, setTransportStr] = useState(""); + const accessToken = Cookies.get("accessToken"); + const [isClient, setIsClient] = useState(false); + const [date, setDate] = useState(""); + + useEffect(() => { + setIsClient(true); + }, []); + + useEffect(() => { + setIsImageIdx([ + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + ]); + }, [ticketColor]); + + useEffect(() => { + setIsImageIdx([ + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + { imgsrc: }, + ]); + }, [ticketColor]); + + const handleDateChange = (date: string) => { + setDate(date); + }; + + const formatDate = (date: Date | null) => { + if (!date) return ""; + return date.toLocaleDateString("ko-KR", { + year: "numeric", + month: "2-digit", + day: "2-digit", }); - // console.log(postRequests) - const [result, setResult] = useState(null); - const [result1, setResult1] = useState(null); - const [transportStr, setTransportStr] = useState(''); - const accessToken = Cookies.get("accessToken"); - const [isClient, setIsClient] = useState(false); - const [date, setDate] = useState(''); - - useEffect(() => { - setIsClient(true); - }, []); - - useEffect(() => { - setIsImageIdx([ - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - ]); - }, [ticketColor]); - - useEffect(() => { - setIsImageIdx([ - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - { imgsrc: }, - ]); - }, [ticketColor]); - - const handleDateChange = (date: string) => { - setDate(date); - }; + }; - const formatDate = (date: Date | null) => { - if (!date) return ''; - return date.toLocaleDateString('ko-KR', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - }); - }; + function formatDates(date: Date | null) { + if (!date || !(date instanceof Date) || isNaN(date.getTime())) { + return ""; // 날짜가 null이거나 유효하지 않은 경우 빈 문자열 반환 + } - function formatDates(date: Date | null) { - if (!date || !(date instanceof Date) || isNaN(date.getTime())) { - return ''; // 날짜가 null이거나 유효하지 않은 경우 빈 문자열 반환 + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + + return `${year}-${month}-${day}`; // 원하는 형식으로 반환 + } + + const formatDateRange = () => { + if (!startDate || !endDate) return ""; + return `${formatDate(startDate)} ~ ${formatDate(endDate)}`; + }; + + const { + data: memberData, + error, + isLoading, + } = useQuery({ + queryKey: ["member", accessToken], + queryFn: () => MemberInfo(accessToken), + onError: (error) => { + // 에러 처리 로직 + // console.error(error); + }, + }); + + const handleIncrease = () => { + setPassengerCount(passengerCount + 1); + }; + + const handleDecrease = () => { + if (passengerCount > 1) { + setPassengerCount(passengerCount - 1); + } + }; + + const handleButtonClick = (color: string, index: number) => { + setBgColor(color); + const selectedColor = Object.keys(colorTicket)[index]; // 인덱스를 사용하여 색상 가져오기 + setTicketColor(selectedColor); + }; + + // console.log(memberData) + + const selectTransport = (imgSrc: JSX.Element) => { + setIsImageIdx((prevState) => { + // 클릭한 항목의 인덱스를 찾기 + const selectedIndex = prevState.findIndex( + (item) => + item.imgsrc.type === imgSrc.type && + item.imgsrc.props.fillColor === imgSrc.props.fillColor + ); + + // 새로운 배열 생성 + const updatedState: any = [...prevState]; + + // 클릭한 항목을 맨 앞으로 옮기기 + if (selectedIndex !== -1) { + const selectedItem = updatedState.splice(selectedIndex, 1)[0]; + updatedState.unshift(selectedItem); + + // 첫 번째 항목의 src에 따라 setTransportStr 설정 + if (updatedState.length > 0) { + const transportValue = updatedState[0].imgsrc.type.name; // SVG 컴포넌트의 이름 사용 + + if (transportValue === "PostBicycleSVG") { + setTransportStr("Bicycle"); + } else if (transportValue === "PostAirSVG") { + setTransportStr("Airplane"); + } else if (transportValue === "PostTrainSVG") { + setTransportStr("Train"); + } else if (transportValue === "PostBusSVG") { + setTransportStr("Bus"); + } else if (transportValue === "PostCarSVG") { + setTransportStr("Car"); + } + } else { + // console.warn('No valid src found in updatedState[0]'); // 디버깅: src가 없을 경우 경고 } + } + setIsTransport(false); // transport 상태를 false로 설정 - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); + return updatedState; + }); + }; - return `${year}-${month}-${day}`; // 원하는 형식으로 반환 + const handleImageUpload = async (event: ChangeEvent) => { + const file = event.target.files?.[0]; + if (event.target.files && event.target.files.length > 0) { + const file = event.target.files[0]; + setThumbnailPreview(URL.createObjectURL(file)); + } + if (!file) return; + + try { + const uploadedImage = await uploadImage(file); + // console.log(uploadedImage.result); + setImages([...images, uploadedImage.result]); + // console.log(images); + setIsImages([...images, uploadedImage.result]); + } catch (error) { + // console.error('Error uploading image:', error); + } + }; + + const displayImages = images.map((image) => image.accessUri); + + // console.log(thumbnailPreview) + const addPost = async () => { + if (inputValue1 === "" || inputValue2 === "") { + Swal.fire({ + icon: "error", + title: "입력 오류", + text: "출발지 또는 도착지를 작성해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; } - const formatDateRange = () => { - if (!startDate || !endDate) return ''; - return `${formatDate(startDate)} ~ ${formatDate(endDate)}`; - }; - - const { - data: memberData, - error, - isLoading, - } = useQuery({ - queryKey: ["member", accessToken], - queryFn: () => MemberInfo(accessToken), - onError: (error) => { - // 에러 처리 로직 - // console.error(error); - }, - }); - + if (!images[0]) { + Swal.fire({ + icon: "error", + title: "이미지 오류", + text: "티켓 이미지를 업로드해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + // console.log(postRequests) + return; + } + if (title.trim() === "") { + Swal.fire({ + icon: "error", + title: "문구 작성 오류", + text: "POST 제목을 작성해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; + } - const handleIncrease = () => { - setPassengerCount(passengerCount + 1); - }; + if (postRequests.body.trim() === "") { + Swal.fire({ + icon: "error", + title: "문구 작성 오류", + text: "POST 문구를 작성해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; + } - const handleDecrease = () => { - if (passengerCount > 1) { - setPassengerCount(passengerCount - 1); - } - }; + if (tags.length < 3) { + Swal.fire({ + icon: "error", + title: "태그 오류", + text: "태그를 3개 이상 등록해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; + } + if (!startDate || !endDate) { + Swal.fire({ + icon: "error", + title: "날짜 오류", + text: "날짜 정보를 입력해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; + } - const handleButtonClick = (color: string, index: number) => { - setBgColor(color); - const selectedColor = Object.keys(colorTicket)[index]; // 인덱스를 사용하여 색상 가져오기 - setTicketColor(selectedColor); - }; + if (Number(passengerCount) < 1) { + Swal.fire({ + icon: "error", + title: "인원 오류", + text: "인원 수를 입력해주세요.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + return; + } - // console.log(memberData) - - - const selectTransport = (imgSrc: JSX.Element) => { - setIsImageIdx((prevState) => { - // 클릭한 항목의 인덱스를 찾기 - const selectedIndex = prevState.findIndex((item) => item.imgsrc.type === imgSrc.type && item.imgsrc.props.fillColor === imgSrc.props.fillColor); - - // 새로운 배열 생성 - const updatedState: any = [...prevState]; - - // 클릭한 항목을 맨 앞으로 옮기기 - if (selectedIndex !== -1) { - const selectedItem = updatedState.splice(selectedIndex, 1)[0]; - updatedState.unshift(selectedItem); - - // 첫 번째 항목의 src에 따라 setTransportStr 설정 - if (updatedState.length > 0) { - const transportValue = updatedState[0].imgsrc.type.name; // SVG 컴포넌트의 이름 사용 - - if (transportValue === 'PostBicycleSVG') { - setTransportStr('Bicycle'); - } else if (transportValue === 'PostAirSVG') { - setTransportStr('Airplane'); - } else if (transportValue === 'PostTrainSVG') { - setTransportStr('Train'); - } else if (transportValue === 'PostBusSVG') { - setTransportStr('Bus'); - } else if (transportValue === 'PostCarSVG') { - setTransportStr('Car'); - } - } else { - // console.warn('No valid src found in updatedState[0]'); // 디버깅: src가 없을 경우 경고 - } - } - setIsTransport(false); // transport 상태를 false로 설정 - - return updatedState; - }); + const postRequest = { + title: title, + body: postRequests.body, + postType: "POST", + location: "24.12342,12.12344", + images: postRequests.images, + tags: tags, }; - - - const handleImageUpload = async (event: ChangeEvent) => { - const file = event.target.files?.[0]; - if (event.target.files && event.target.files.length > 0) { - const file = event.target.files[0]; - setThumbnailPreview(URL.createObjectURL(file)); - } - if (!file) return; - - try { - const uploadedImage = await uploadImage(file); - // console.log(uploadedImage.result); - setImages([...images, uploadedImage.result]); - // console.log(images); - setIsImages([...images, uploadedImage.result]); - } catch (error) { - // console.error('Error uploading image:', error); - } + const ticketRequest = { + departure: inputValue1, + departureCode: result?.result.isoAlp3, + destination: inputValue2, + destinationCode: result1?.result.isoAlp3, + image: images[0], + memberNum: Number(passengerCount), + startDate: formatDates(startDate), + endDate: formatDates(endDate), + ticketColor: ticketColor || "Aquamarine", + transport: transportStr || "Airplane", }; - - const displayImages = images.map(image => image.accessUri); - - // console.log(thumbnailPreview) - const addPost = async () => { - - if (inputValue1 === '' || inputValue2 === '') { - Swal.fire({ - icon: 'error', - title: '입력 오류', - text: '출발지 또는 도착지를 작성해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - if (!images[0]) { - Swal.fire({ - icon: 'error', - title: '이미지 오류', - text: '티켓 이미지를 업로드해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - // console.log(postRequests) - return; - } - - if (title.trim() === '') { - Swal.fire({ - icon: 'error', - title: '문구 작성 오류', - text: 'POST 제목을 작성해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - if (postRequests.body.trim() === '') { - Swal.fire({ - icon: 'error', - title: '문구 작성 오류', - text: 'POST 문구를 작성해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - if (tags.length < 3) { - Swal.fire({ - icon: 'error', - title: '태그 오류', - text: '태그를 3개 이상 등록해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - if (!startDate || !endDate) { - Swal.fire({ - icon: 'error', - title: '날짜 오류', - text: '날짜 정보를 입력해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - if (Number(passengerCount) < 1) { - Swal.fire({ - icon: 'error', - title: '인원 오류', - text: '인원 수를 입력해주세요.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); - return; - } - - const postRequest = { - title: title, - body: postRequests.body, - postType: 'POST', - location: '24.12342,12.12344', - images: postRequests.images, - tags: tags, - }; - - const ticketRequest = { - departure: inputValue1, - departureCode: result?.result.isoAlp3, - destination: inputValue2, - destinationCode: result1?.result.isoAlp3, - image: images[0], - memberNum: Number(passengerCount), - startDate: formatDates(startDate), - endDate: formatDates(endDate), - ticketColor: ticketColor || 'Aquamarine', - transport: transportStr || "Airplane" - }; - - try { - // 로딩 시작 - Swal.fire({ - title: '로딩 중...', - html: '게시글을 올리는 중입니다.', - allowOutsideClick: false, - didOpen: () => { - Swal.showLoading(); - } - }); - - // console.log(postRequest, ticketRequest); - await postBoard(postRequest, ticketRequest); - - // 로딩 완료 후 성공 메시지 - Swal.fire({ - icon: 'success', - title: 'TICKET 게시글을 올렸습니다.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - customClass: { - popup: 'swal-custom-popup', - icon: 'swal-custom-icon' - } - }).then((result) => { - if (result.isConfirmed) { - router.push('/'); - } - }); - } catch (e: any) { - // 에러 처리 (예: 에러 메시지 표시) - Swal.fire({ - icon: 'error', - title: '게시글 업로드에 실패했습니다.', - text: e.message || '알 수 없는 오류가 발생했습니다.', - confirmButtonText: '확인', - confirmButtonColor: '#FB3463', - }); + try { + // 로딩 시작 + Swal.fire({ + title: "로딩 중...", + html: "게시글을 올리는 중입니다.", + allowOutsideClick: false, + didOpen: () => { + Swal.showLoading(); + }, + }); + + // console.log(postRequest, ticketRequest); + await postBoard(postRequest, ticketRequest); + + // 로딩 완료 후 성공 메시지 + Swal.fire({ + icon: "success", + title: "TICKET 게시글을 올렸습니다.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + customClass: { + popup: "swal-custom-popup", + icon: "swal-custom-icon", + }, + }).then((result) => { + if (result.isConfirmed) { + router.push("/"); } - }; - - - // console.log(images) - - // URL 객체 해제 - useEffect(() => { - return () => { - if (thumbnailPreview) { - URL.revokeObjectURL(thumbnailPreview); - } - }; - }, [thumbnailPreview]); - // console.log(formatDates(startDate), formatDates(endDate)) - - - const handleInputChange = (e: React.ChangeEvent) => { - setInputValue(e.target.value); - }; - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && inputValue.trim() !== "") { - const trimmedInput = inputValue.trim(); + }); + } catch (e: any) { + // 에러 처리 (예: 에러 메시지 표시) + Swal.fire({ + icon: "error", + title: "게시글 업로드에 실패했습니다.", + text: e.message || "알 수 없는 오류가 발생했습니다.", + confirmButtonText: "확인", + confirmButtonColor: "#FB3463", + }); + } + }; - // 중복 태그 체크 (부분 포함 검사 추가) - const isDuplicate = tags.some(tag => tag.toLowerCase() === trimmedInput.toLowerCase() || trimmedInput.toLowerCase().includes(tag.toLowerCase())); + // console.log(images) - if (!isDuplicate) { - setTags([...tags, trimmedInput]); - setInputValue(''); // 입력 필드 초기화 - } - } + // URL 객체 해제 + useEffect(() => { + return () => { + if (thumbnailPreview) { + URL.revokeObjectURL(thumbnailPreview); + } }; - - const handleTagRemove = (index: number) => { - setTags((prevTags) => prevTags.filter((_, i) => i !== index)); // 해당 인덱스의 태그를 삭제 - }; - - const { getLocationData } = getCountry({ setResult }); - const { getLocationData1 } = getCountry1({ setResult1 }); - - const searchCountry = async (locations: string) => { - await getLocationData(locations); - } - - const searchCountry1 = async (locationss: string) => { - await getLocationData1(locationss); + }, [thumbnailPreview]); + // console.log(formatDates(startDate), formatDates(endDate)) + + const handleInputChange = (e: React.ChangeEvent) => { + setInputValue(e.target.value); + }; + + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter" && inputValue.trim() !== "") { + const trimmedInput = inputValue.trim(); + + // 중복 태그 체크 (부분 포함 검사 추가) + const isDuplicate = tags.some( + (tag) => + tag.toLowerCase() === trimmedInput.toLowerCase() || + trimmedInput.toLowerCase().includes(tag.toLowerCase()) + ); + + if (!isDuplicate) { + setTags([...tags, trimmedInput]); + setInputValue(""); // 입력 필드 초기화 + } } - - - // console.log(transportStr) - return ( -
- {/*
*/} -
-
- - - - - + }; + + const handleTagRemove = (index: number) => { + setTags((prevTags) => prevTags.filter((_, i) => i !== index)); // 해당 인덱스의 태그를 삭제 + }; + + const { getLocationData } = getCountry({ setResult }); + const { getLocationData1 } = getCountry1({ setResult1 }); + + const searchCountry = async (locations: string) => { + await getLocationData(locations); + }; + + const searchCountry1 = async (locationss: string) => { + await getLocationData1(locationss); + }; + + // console.log(transportStr) + return ( +
+ {/*
*/} +
+
+ + + + + + + +
+ {typeof window !== "undefined" && window.innerWidth > 600 ? ( +
+
+
+
+
+

+ {result?.result.isoAlp3} +

+
+ setInputValue1(e.target.value)} // 입력 값 변경 시 핸들러 + onKeyDown={(e) => { + if (e.key === "Enter") { + searchCountry(inputValue1); // 엔터 키가 눌리면 함수 호출 + } + }} + /> - + className="ml-auto" + onClick={() => searchCountry(inputValue1)} + > + + +
- {typeof window !== 'undefined' && window.innerWidth > 600 ? ( -
-
-
-
-
-

{result?.result.isoAlp3}

-
- setInputValue1(e.target.value)} // 입력 값 변경 시 핸들러 - onKeyDown={(e) => { - if (e.key === 'Enter') { - searchCountry(inputValue1); // 엔터 키가 눌리면 함수 호출 - } - }} - /> - -
-
-
- { - isTransport ? ( -
- {isImageIdx.slice(0, 5).map((item: any, index) => ( -
selectTransport(item.imgsrc)}> - {item.imgsrc} -
- ))} -
- ) : ( -
setIsTransport(true)} - > - {isImageIdx[0]?.imgsrc} -
- ) - } -
-
-

{result1?.result.isoAlp3}

-
- setInputValue2(e.target.value)} // 입력 값 변경 시 핸들러 - onKeyDown={(e) => { - if (e.key === 'Enter') { - searchCountry1(inputValue2); // 엔터 키가 눌리면 함수 호출 - } - }} - /> - -
-
-
-
-
- PASSENGER - DATE - GROUP -
-
- {memberData?.result.nickName} - -
- - {passengerCount} - -
-
-
-
-
-
-
-
- - +
+ {isTransport ? ( +
+ {isImageIdx.slice(0, 5).map((item: any, index) => ( +
selectTransport(item.imgsrc)} + > + {item.imgsrc}
+ ))}
+ ) : ( +
setIsTransport(true)} + > + {isImageIdx[0]?.imgsrc} +
+ )} +
+
+

+ {result1?.result.isoAlp3} +

+
+ setInputValue2(e.target.value)} // 입력 값 변경 시 핸들러 + onKeyDown={(e) => { + if (e.key === "Enter") { + searchCountry1(inputValue2); // 엔터 키가 눌리면 함수 호출 + } + }} + /> + +
+
+
+
+
+ + PASSENGER + + DATE + GROUP +
+
+ + {memberData?.result.nickName} + + +
+ + + {passengerCount} + + +
+
+
+
+
+
+
+
+
+ ); } export default PostWrite; diff --git a/src/components/board/CalendarModal2.tsx b/src/components/board/CalendarModal2.tsx index e5c64243..fc1d879d 100644 --- a/src/components/board/CalendarModal2.tsx +++ b/src/components/board/CalendarModal2.tsx @@ -1,7 +1,7 @@ -import React from 'react'; -import DatePicker from 'react-datepicker'; -import 'react-datepicker/dist/react-datepicker.css'; -import { ko } from 'date-fns/locale'; +import React from "react"; +import DatePicker from "react-datepicker"; +import "react-datepicker/dist/react-datepicker.css"; +import { ko } from "date-fns/locale"; interface CalendarModalProps { isOpen: boolean; @@ -18,7 +18,7 @@ const CalendarModal2: React.FC = ({ selectedDates, onDateChange, startDate, - endDate + endDate, }) => { if (!isOpen) return null; @@ -39,6 +39,22 @@ const CalendarModal2: React.FC = ({ inline dateFormat="yyyy. MM. dd" maxDate={today} // 오늘 날짜 이후 선택 불가 + renderCustomHeader={({ date, decreaseMonth, increaseMonth }) => ( +
+ + + {date.toLocaleString("default", { + month: "long", + year: "numeric", + })} + + +
+ )} /> {/* 선택 및 취소 버튼 */} diff --git a/src/components/board/DateInput2.tsx b/src/components/board/DateInput2.tsx index a1b14a74..e01e4991 100644 --- a/src/components/board/DateInput2.tsx +++ b/src/components/board/DateInput2.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect } from 'react'; -import { format, parse, isValid } from 'date-fns'; -import Image from 'next/image'; -import CalendarIcon from '../../../public/icon_calendar.svg'; -import CalendarModal2 from './CalendarModal2'; +import React, { useState, useEffect } from "react"; +import { format, parse, isValid } from "date-fns"; +import Image from "next/image"; +import CalendarIcon from "../../../public/icon_calendar.svg"; +import CalendarModal2 from "./CalendarModal2"; interface DateInputProps { onDateChange: any; // 날짜 배열 전달 @@ -21,18 +21,20 @@ const DateInput2: React.FC = ({ setStartDate, setEndDate, }) => { - const [selectedDates, setSelectedDates] = useState<[Date | null, Date | null]>([null, null]); + const [selectedDates, setSelectedDates] = useState< + [Date | null, Date | null] + >([null, null]); const [isModalOpen, setIsModalOpen] = useState(false); // 모달 상태 관리 - const [inputValue, setInputValue] = useState(''); // 입력된 값 관리 + const [inputValue, setInputValue] = useState(""); // 입력된 값 관리 useEffect(() => { if (initialDate) { - const parsedDate = parse(initialDate, 'yyyyMMdd', new Date()); + const parsedDate = parse(initialDate, "yyyyMMdd", new Date()); if (isValid(parsedDate)) { setSelectedDates([parsedDate, null]); // 시작일만 설정 setInputValue(initialDate); // 초기 날짜 값 설정 } else { - console.error('Invalid date format:', initialDate); + console.error("Invalid date format:", initialDate); } } }, [initialDate]); @@ -44,8 +46,8 @@ const DateInput2: React.FC = ({ setSelectedDates([start, end]); // 시작 날짜와 종료 날짜 설정 - const formattedStart = start ? format(start, 'yyyyMMdd') : null; - const formattedEnd = end ? format(end, 'yyyyMMdd') : null; + const formattedStart = start ? format(start, "yyyyMMdd") : null; + const formattedEnd = end ? format(end, "yyyyMMdd") : null; setStartDate(start); setEndDate(end); @@ -58,7 +60,7 @@ const DateInput2: React.FC = ({ } else if (end) { setInputValue(String(formattedEnd)); } else { - setInputValue(''); + setInputValue(""); } // 날짜 변경 콜백 호출 @@ -73,7 +75,7 @@ const DateInput2: React.FC = ({ }; return ( -
+
void }> = ({ useEffect(() => { if (!accessToken) { - router.push('/login'); + router.push("/login"); } }, [accessToken, router]); @@ -76,23 +76,31 @@ const UserInformation: React.FC<{ setActiveTab: (tab: string) => void }> = ({ }} />
-

{userData?.nickName}

+

+ {userData?.nickName} +

{userData?.email}
- setActiveTab(TABS.FOLLOWER)}> + setActiveTab(TABS.FOLLOWER)} + > 팔로워 {userData?.followerCnt}  |  - setActiveTab(TABS.FOLLOWING)}> + setActiveTab(TABS.FOLLOWING)} + > 팔로잉 {userData?.followingCnt} diff --git a/src/components/testEditor/textEditor2.tsx b/src/components/testEditor/textEditor2.tsx index eca5f66e..32c33d49 100644 --- a/src/components/testEditor/textEditor2.tsx +++ b/src/components/testEditor/textEditor2.tsx @@ -1,95 +1,101 @@ -import React, { useState, useRef } from 'react'; -import { Editor } from '@tinymce/tinymce-react'; -import { uploadImage } from '@/services/blog'; +import React, { useState, useRef } from "react"; +import { Editor } from "@tinymce/tinymce-react"; +import { uploadImage } from "@/services/blog"; interface editorProps { - postRequest: any; - setPostRequest: any; + postRequest: any; + setPostRequest: any; } const inputAPI = process.env.NEXT_PUBLIC_INPUT_TEXT_API_KEY; const MyTinyMCEEditor = ({ postRequest, setPostRequest }: editorProps) => { - const editorRef = useRef(null); // 에디터 참조 생성 + const editorRef = useRef(null); // 에디터 참조 생성 - const handleEditorChange = (content: string) => { - // 에디터 내용 업데이트 - setPostRequest((prev: any) => ({ ...prev, body: content })); - }; + const handleEditorChange = (content: string) => { + // 에디터 내용 업데이트 + setPostRequest((prev: any) => ({ ...prev, body: content })); + }; - const handleImageUpload = async (blobInfo: any) => { - const file = blobInfo.blob(); // Blob 객체 가져오기 - try { - const uploadedImage = await uploadImage(file); // 이미지 업로드 함수 호출 - const imageUrl = uploadedImage.result; // 업로드된 이미지 URL 가져오기 + const handleImageUpload = async (blobInfo: any) => { + const file = blobInfo.blob(); // Blob 객체 가져오기 + try { + const uploadedImage = await uploadImage(file); // 이미지 업로드 함수 호출 + const imageUrl = uploadedImage.result; // 업로드된 이미지 URL 가져오기 - // 이미지 URL을 postRequest.images에 추가 - setPostRequest((prev: any) => ({ - ...prev, - images: [...prev.images, imageUrl], // 이미지 URL 추가 - })); + // 이미지 URL을 postRequest.images에 추가 + setPostRequest((prev: any) => ({ + ...prev, + images: [...prev.images, imageUrl], // 이미지 URL 추가 + })); - // TinyMCE에 이미지 URL 반환 - return imageUrl; - } catch (error) { - console.error('Error uploading image:', error); - return ''; // 실패 시 빈 문자열 반환 - } - }; + // TinyMCE에 이미지 URL 반환 + return imageUrl; + } catch (error) { + console.error("Error uploading image:", error); + return ""; // 실패 시 빈 문자열 반환 + } + }; - const renderBodyWithImages = (body: string, images: { accessUri: string }[]) => { - return body.replace(/imageData(\d+)/g, (match, index) => { - const imgIndex = parseInt(index) - 1; // imageData1 -> 0, imageData2 -> 1 등 - const image = images[imgIndex]; // 해당 이미지 객체 가져오기 - return image ? `Uploaded Image` : match; // 이미지가 있으면 img 태그 반환, 없으면 원래 문자열 반환 - }); - }; + const renderBodyWithImages = ( + body: string, + images: { accessUri: string }[] + ) => { + return body.replace(/imageData(\d+)/g, (match, index) => { + const imgIndex = parseInt(index) - 1; // imageData1 -> 0, imageData2 -> 1 등 + const image = images[imgIndex]; // 해당 이미지 객체 가져오기 + return image + ? `Uploaded Image` + : match; // 이미지가 있으면 img 태그 반환, 없으면 원래 문자열 반환 + }); + }; - const handleSaveEditorContent = () => { - if (editorRef.current) { - const content = editorRef.current.getContent(); // 에디터 내용 가져오기 - handleEditorChange(content); // 내용 업데이트 - } - }; + const handleSaveEditorContent = () => { + if (editorRef.current) { + const content = editorRef.current.getContent(); // 에디터 내용 가져오기 + handleEditorChange(content); // 내용 업데이트 + } + }; - return ( -
- -
- ); + return ( +
+ +
+ ); }; export default MyTinyMCEEditor;