diff --git a/src/components/features/shop/BuyModal.tsx b/src/components/features/shop/BuyModal.tsx index 7397821..7c3440b 100644 --- a/src/components/features/shop/BuyModal.tsx +++ b/src/components/features/shop/BuyModal.tsx @@ -5,7 +5,7 @@ import { getCookie } from "~/utils/cookie"; export const BuyModal = component$(({ showBuyModal, item, mydotory, itemdotory}: {showBuyModal: Signal, item: any, mydotory: number, itemdotory: number}) => { const handleBuy = $(async() => { try { - const res = await axios.post(`http://localhost:8000/api/store/${item.id}?product_name=${item.name}`, { + const res = await axios.post(`http://localhost:8000/api/store/0?product_name=${item.name}`, { }, { headers: { Authorization: `Bearer ${getCookie("access_token")}`, diff --git a/src/components/room/DragRommGrid.tsx b/src/components/room/DragRommGrid.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/room/RoomGrid.tsx b/src/components/room/RoomGrid.tsx index 6870bd5..05dfd5e 100644 --- a/src/components/room/RoomGrid.tsx +++ b/src/components/room/RoomGrid.tsx @@ -16,7 +16,7 @@ export default component$(({ furniture, avatar, roomType }: { furniture: Signal< top_clothe_type: "", bottom_clothe_type: "" }); - + const furnitureItems = useSignal([]); useVisibleTask$(({ track }) => { track(() => avatar.value); console.log(avatar.value); @@ -25,43 +25,44 @@ export default component$(({ furniture, avatar, roomType }: { furniture: Signal< avatar_type: typechecker(avatar.value.avatar_type), top_clothe_type: typechecker(avatar.value.top_clothe_type), bottom_clothe_type: typechecker(avatar.value.bottom_clothe_type), - }; + }; + furnitureItems.value = [furniture.value]; console.log(checkedAvatar.value); }) - const furnitureItems = useSignal([ - { - name: '큰 식물1', - image_path: 'public/funiture/큰 식물.png', - x: 1, - y: 1 - }, - { - name: '녹색 침대1', - image_path: 'public/funiture/녹색 침대-90.png', - x: 3, - y: 3 - }, - { - name: '쓰레기통열림1', - image_path: 'public/funiture/쓰레기통열림.png', - x: 5, - y: 5 - }, - { - name: '어항1', - image_path: 'public/funiture/어항-0.png', - x: 7, - y: 7 - } - ]); + // const furnitureItems = useSignal([ + // { + // name: '큰 식물1', + // image_path: 'public/funiture/큰 식물.png', + // x: 1, + // y: 1 + // }, + // { + // name: '녹색 침대1', + // image_path: 'public/funiture/녹색 침대-90.png', + // x: 3, + // y: 3 + // }, + // { + // name: '쓰레기통열림1', + // image_path: 'public/funiture/쓰레기통열림.png', + // x: 5, + // y: 5 + // }, + // { + // name: '어항2', + // image_path: 'public/funiture/어항-0.png', + // x: 7, + // y: 7 + // } + // ]); // 현재 드래그 중인 가구 - const draggedItem = useSignal(null); - // 드래그 시작 시 호출 - const handleDragStart = $((item: FurnitureItem, e: Event) => { - e.preventDefault(); - draggedItem.value = item; - }); + // const draggedItem = useSignal(null); + // // 드래그 시작 시 호출 + // const handleDragStart = $((item: FurnitureItem, e: Event) => { + // e.preventDefault(); + // draggedItem.value = item; + // }); // 드래그 오버 시 기본 동작 방지 const handleDragOver = $((e: Event) => { @@ -72,29 +73,35 @@ export default component$(({ furniture, avatar, roomType }: { furniture: Signal< const handleCellClick = $((x: number, y: number, e: Event) => { e.preventDefault(); console.log(`Cell clicked: (${x}, ${y})`); + furnitureItems.value = furnitureItems.value.map(item => + item.name === furniture.value?.name + ? { ...item, x: x, y: y } + : item + ); + // draggedItem.value = null; }); // 드롭 시 호출 - const handleDrop = $((cellX: number, cellY: number, e: Event) => { - e.preventDefault(); - if (!draggedItem.value) return; + // const handleDrop = $((cellX: number, cellY: number, e: Event) => { + // e.preventDefault(); + // if (!draggedItem.value) return; - // 이미 해당 위치에 다른 가구가 있는지 확인 - const isOccupied = furnitureItems.value.some( - item => item.x === cellX && item.y === cellY - ); + // // 이미 해당 위치에 다른 가구가 있는지 확인 + // const isOccupied = furnitureItems.value.some( + // item => item.x === cellX && item.y === cellY + // ); - if (!isOccupied) { - // 가구 위치 업데이트 - furnitureItems.value = furnitureItems.value.map(item => - item.name === draggedItem.value?.name - ? { ...item, x: cellX, y: cellY } - : item - ); - } + // if (!isOccupied) { + // // 가구 위치 업데이트 + // furnitureItems.value = furnitureItems.value.map(item => + // item.name === draggedItem.value?.name + // ? { ...item, x: cellX, y: cellY } + // : item + // ); + // } - draggedItem.value = null; - }); + // draggedItem.value = null; + // }); // 10x10 그리드 셀 생성 @@ -125,40 +132,21 @@ export default component$(({ furniture, avatar, roomType }: { furniture: Signal< /> {/* Grid overlay */} -
+
{gridCells.map((cell) => (
handleDrop(cell.x, cell.y, e)} + // onDragOver$={handleDragOver} + // onDrop$={ e => handleDrop(cell.x, cell.y, e)} onClick$={ e => handleCellClick(cell.x, cell.y, e)} > {cell.furniture && ( {cell.furniture.name} handleDragStart(furnitureItems.value.find(f => f.name === cell.furniture?.name)!, e)} - style={{ - position: 'absolute', - width: '100%', - height: '100%', - objectFit: 'contain', - imageRendering: 'pixelated', - cursor: 'move', - zIndex: 10 - }} + // draggable + // onDragStart$={ e => handleDragStart(furnitureItems.value.find(f => f.name === cell.furniture?.name)!, e)} /> )}
@@ -198,17 +186,6 @@ const STYLES = ` object-fit: cover; } -.grid-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: grid; - grid-template-columns: repeat(10, 1fr); - grid-template-rows: repeat(10, 1fr); - pointer-events: auto; -} .avatar-wrapper { position: absolute; @@ -257,7 +234,7 @@ const STYLES = ` grid-template-columns: repeat(10, 1fr); grid-template-rows: repeat(10, 1fr); z-index: 2; - pointer-events: none; + } .grid-overlay div { @@ -287,7 +264,18 @@ const STYLES = ` transform: translate(-50%, -50%); z-index: 99; } - +.grid-overlay div#oneone>img { + width: 70px; + image-rendering: pixelated; + position: absolute; + bottom: 0; + } +.grid-overlay div#twoone>img { + width: 140px; + image-rendering: pixelated; + position: absolute; + transform: translate(-50%, -50%); +} .avatar-wrapper img { position: absolute; top: 0; diff --git a/src/components/room/ShowRoomGrid.tsx b/src/components/room/ShowRoomGrid.tsx new file mode 100644 index 0000000..545aa4a --- /dev/null +++ b/src/components/room/ShowRoomGrid.tsx @@ -0,0 +1,140 @@ + import { component$, useStylesScoped$ , useVisibleTask$ } from "@builder.io/qwik"; + + interface FurnitureItem { + image_path: string; + x: number; + y: number; + size?: "one" | "two"; // 크기 구분 (one = 70px, two = 140px) + } + + interface AvatarItem { + avatar_type: {name: string, path: string}; + top_clothe_type: {name: string, path: string}; + bottom_clothe_type: {name: string, path: string}; + } + + interface ShowRoomGridProps { + roomSrc: string; // 방 배경 + furnitures: FurnitureItem[]; // 가구 리스트 + avatars: AvatarItem; // 아바타 이미지 리스트 + } + + export default component$((props: ShowRoomGridProps) => { + console.log(props.roomSrc); + console.log(props.furnitures + " furnitures"); + console.log(props.avatars + " avatars"); + useStylesScoped$(STYLES); + useVisibleTask$(() => { + }); + return ( +
+ {/* 배경 */} + + + {/* 10x10 격자 */} +
+ {Array.from({ length: 100 }).map((_, idx) => { + const item = props.furnitures.find((f) => f.x*10 + f.y === idx); + console.log(item); + return ( +
+ {item && } +
+ ); + })} +
+ + {/* 아바타 */} +
+ + + + +
+
+ ); + }); + + const STYLES = ` + .room-wrapper { + display: flex; + align-items: center; + justify-content: center; + width: 700px; + height: 700px; + position: relative; + } + .room { + position: absolute; + z-index: 1 !important; + width: 100%; + height: 100%; + image-rendering: pixelated; + } + + .grid-overlay { + position: absolute; + top: 0; + left: 0; + width: 700px; + height: 700px; + display: grid; + grid-template-columns: repeat(10, 1fr); + grid-template-rows: repeat(10, 1fr); + z-index: 2; + pointer-events: none; + } + .grid-overlay div { + /* border: 1px solid rgba(0,0,0,0.2); */ + box-sizing: border-box; + position: relative; + + width: 70px; + height: 70px; + position: relative; + } + + // .grid-overlay div.oneone > img { + // width: 140px; + // image-rendering: pixelated; + // position: absolute; + // bottom: 0; + // } + // .grid-overlay div.twoone > img { + // width: 140px; + // image-rendering: pixelated; + // position: absolute; + // transform: translate(-50%, -50%); + // } + .avatar-wrapper { + width: 100px; + height: 100px; + position: absolute; + top: 70%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 99; + } + .avatar-wrapper img { + position: absolute; + top: 0; + left: 0; + width: 100%; + image-rendering: pixelated; + z-index: 99; + } + `; \ No newline at end of file diff --git a/src/routes/[username]/(store)/layout.tsx b/src/routes/[username]/(store)/layout.tsx index ceda5ab..f05f5dd 100644 --- a/src/routes/[username]/(store)/layout.tsx +++ b/src/routes/[username]/(store)/layout.tsx @@ -5,7 +5,7 @@ import { DocumentHead } from "@builder.io/qwik-city"; import { useLocation } from "@builder.io/qwik-city"; import axios from "axios"; import { routeLoader$ } from "@builder.io/qwik-city"; -export const onRequest: RequestHandler = async ({ cookie, params, sharedMap}) => { +export const onGet: RequestHandler = async ({ cookie, params, sharedMap}) => { console.log(params.username + "의 상점 페이지로 들어옴"); @@ -15,7 +15,7 @@ export const onRequest: RequestHandler = async ({ cookie, params, sharedMap}) => Authorization: `Bearer ${cookie.get("access_token")?.value}`, }, }); - sharedMap.set("dotory", res.data ?? 0); + sharedMap.set("dotory", res.data.dotory ?? 0); console.log(res.data ?? "no data"); } catch (error) { console.log(error); @@ -29,8 +29,8 @@ export default component$(() => { const location = useLocation(); const dotory = useDotory(); - console.log(location.url.pathname); - console.log("/"+location.params.username+"/store"); + // console.log(location.url.pathname); + // console.log(location.params.username+"/store"); return (
@@ -40,8 +40,6 @@ export default component$(() => {
- {/*
-
*/}
도토리: {dotory.value}
diff --git a/src/routes/[username]/(store)/room/index.tsx b/src/routes/[username]/(store)/room/index.tsx index 880930b..7f9f5cd 100644 --- a/src/routes/[username]/(store)/room/index.tsx +++ b/src/routes/[username]/(store)/room/index.tsx @@ -45,39 +45,18 @@ interface Room { room_image_path: string; } export const useRoomLoader = routeLoader$(async ({cookie}) => { + const headers = { + Authorization: `Bearer ${cookie.get("access_token")?.value}`, + } try { - const myRoom = await axios.get("http://localhost:8000/api/room/layout", { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }) - const myAvatar = await axios.get("http://localhost:8000/api/avatar", { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }) - const roomType = await axios.get("http://localhost:8000/api/room/types", { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }) - const furniture = await axios.get("http://localhost:8000/api/room/my", { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }) - const avatarType = await axios.get("http://localhost:8000/api/avatar/options", { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }) - const roomTypeData = roomType.data; - const avatar : Avatar = myAvatar.data; - const room : Room = myRoom.data; - const furnitureData = furniture.data; - const avatarTypeData = avatarType.data; - console.log(myRoom.data); - return {myData : {room: room, avatar: avatar}, selectionData: {roomType: roomTypeData, furniture: furnitureData, avatarType: avatarTypeData}}; + const [myRoom, myAvatar, roomType, furniture, avatarType] = await Promise.all([ + axios.get("http://localhost:8000/api/room/layout", { headers }), + axios.get("http://localhost:8000/api/avatar", { headers }), + axios.get("http://localhost:8000/api/room/types", { headers }), + axios.get("http://localhost:8000/api/room/my", { headers }), + axios.get("http://localhost:8000/api/avatar/options", { headers }), + ]); + return {myData : {room: myRoom.data, avatar: myAvatar.data}, selectionData: {roomType: roomType.data, furniture: furniture.data, avatarType: avatarType.data}}; } catch (error : any) { console.error(error); return error.response?.data?.detail || 'Room not found'; @@ -85,8 +64,10 @@ export const useRoomLoader = routeLoader$(async ({cookie}) => { }) export default component$(() => { const data = useRoomLoader(); - const selectedFurniture = useSignal([]); // 유저 선택 가구 - const selectedType = useSignal("furniture"); // 헤더에서 가구, 아바타, 배경 구분 + const selectedFurnitures = useSignal>([]); + + const selectedType = useSignal<"furniture" | "avatar" | "background">("furniture"); + const editingPosition = useSignal(null); const selectedRoomType = useSignal("room_1"); const selectedAvatar = useSignal({ avatar_type: "", @@ -100,99 +81,31 @@ export default component$(() => { selectedAvatar.value.bottom_clothe_type = data.value.myData.avatar.bottom_clothe_type.name; }) - const deleteFurniture = $((selectedFurniture : Furniture) => { - const furnitureRes = axios.delete("http://localhost:8000/api/room/furniture", { - data: { - furniture_name: selectedFurniture.furniture_name, - x: selectedFurniture.x, - y: selectedFurniture.y, - }, - headers: { - Authorization: `Bearer ${getCookie("access_token")}`, - }, - }) - }) - // const getNewState = async () => { - // const myRoom = await axios.get("http://localhost:8000/api/room/layout", { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // const myAvatar = await axios.get("http://localhost:8000/api/avatar", { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // const roomType = await axios.get("http://localhost:8000/api/room/types", { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // const furniture = await axios.get("http://localhost:8000/api/room/my", { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // const avatarType = await axios.get("http://localhost:8000/api/avatar/options", { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // const roomTypeData = roomType.data; - // const avatar : Avatar = myAvatar.data.avatar; - // const room : Room = myRoom.data; - // const furnitureData = furniture.data; - // const avatarTypeData = avatarType.data; - // console.log(myRoom.data); - // } - const handleChange = $( async () => { - console.log("handleChange"); + const deleteFurniture = $(async (selectedFurniture : Furniture) => { try { - // 배경 설정 - console.log(selectedRoomType.value); - const roomRes = await axios.patch("http://localhost:8000/api/room/", - { - type: selectedRoomType.value - }, - { - headers: { - Authorization: `Bearer ${getCookie("access_token")}`, - }, - } - ); - const avatarRes = await axios.put("http://localhost:8000/api/avatar", { - - avatar_type: selectedAvatar.value.avatar_type, - top_clothe_type: selectedAvatar.value.top_clothe_type, - bottom_clothe_type: selectedAvatar.value.bottom_clothe_type, - }, - { - headers: { - Authorization: `Bearer ${getCookie("access_token")}`, - }, - } - ); - // for (let i = 0; i < selectedFurniture.value.length; i++) { - // const furnitureRes = await axios.post("http://localhost:8000/api/room/furniture", { - // furniture_name: selectedFurniture.value[i].furniture_name, - // x: selectedFurniture.value[i].x, - // y: selectedFurniture.value[i].y, - // }, - // { - // headers: { - // Authorization: `Bearer ${getCookie("access_token")}`, - // }, - // }) - // } - // getNewState(); - console.log(roomRes.data); - console.log(avatarRes.data); - } catch (error) { - console.log(error); - } + await axios.delete(`http://localhost:8000/api/room/furniture?x=${selectedFurniture.x}&y=${selectedFurniture.y}&furniture_name=${selectedFurniture.furniture_name}`, {headers: {Authorization: `Bearer ${getCookie("access_token")}`}}); + selectedFurnitures.value = selectedFurnitures.value.filter((f : Furniture) => f.furniture_name !== selectedFurniture.furniture_name); + } catch (error : any) {console.error(error);} }) - const handleCancel = $(() => { - console.log("handleCancel"); + const addFurniture = $(async (selectedFurniture : Furniture) => { + try { await axios.post("http://localhost:8000/api/room/furniture", {furniture_name: selectedFurniture.furniture_name,x: selectedFurniture.x,y: selectedFurniture.y,}, { headers: { Authorization: `Bearer ${getCookie("access_token")}`,},},) + } catch (error : any) {console.error(error);} + }) + useTask$(({track}) => { + track(() => selectedFurnitures.value); + try { + for (let i = 0; i < selectedFurnitures.value.length; i++) { + if(data.value.myData.room.room.furniture.some((f : Furniture) => f.furniture_name === selectedFurnitures.value[i].furniture_name)) {deleteFurniture(selectedFurnitures.value[i]);} + else { addFurniture(selectedFurnitures.value[i]);} + } + } catch (error : any) {console.error(error);} + }) + + const handleChange = $( async () => { + try { + await axios.patch("http://localhost:8000/api/room/", {type: selectedRoomType.value}, {headers: {Authorization: `Bearer ${getCookie("access_token")}`}}); + await axios.put("http://localhost:8000/api/avatar", {avatar_type: selectedAvatar.value.avatar_type,top_clothe_type: selectedAvatar.value.top_clothe_type,bottom_clothe_type: selectedAvatar.value.bottom_clothe_type,}, {headers: {Authorization: `Bearer ${getCookie("access_token")}`}}); + } catch (error) {console.log(error);} }) return (
@@ -201,7 +114,7 @@ export default component$(() => { {/* Room Preview */}
- +
@@ -251,12 +164,81 @@ export default component$(() => {
{selectedType.value === "furniture" ? ( - data.value.selectionData.furniture.map((furniture: Furniture) => ( -
{if(selectedFurniture.value.includes(furniture)) selectedFurniture.value = selectedFurniture.value.filter((item: Furniture) => item !== furniture); else selectedFurniture.value.push(furniture);}}> - {furniture.furniture_name} - {furniture.furniture_name} -
- ))) + data.value.selectionData.furniture.map((furniture: Furniture) => { + const isSelected = selectedFurnitures.value.some(f => f.furniture_name === furniture.furniture_name); + const selectedItem = selectedFurnitures.value.find(f => f.furniture_name === furniture.furniture_name); + + return ( +
+
{ + if (isSelected) { + selectedFurnitures.value = selectedFurnitures.value.filter( + item => item.furniture_name !== furniture.furniture_name + ); + } else { + selectedFurnitures.value = [...selectedFurnitures.value, { + ...furniture, + x: 0, + y: 0 + }]; + } + }} + > + {furniture.furniture_name} + + {furniture.furniture_name} + +
+ + {isSelected && ( +
+ { + const value = (e.target as HTMLInputElement).value; + const index = selectedFurnitures.value.findIndex(f => f.furniture_name === furniture.furniture_name); + if (index !== -1) { + const updated = [...selectedFurnitures.value]; + updated[index] = { ...updated[index], x: parseInt(value) || 0 }; + selectedFurnitures.value = updated; + } + }} + class="w-12 px-1 text-center border rounded" + placeholder="X" + /> + { + const value = (e.target as HTMLInputElement).value; + const index = selectedFurnitures.value.findIndex(f => f.furniture_name === furniture.furniture_name); + if (index !== -1) { + const updated = [...selectedFurnitures.value]; + updated[index] = { ...updated[index], y: parseInt(value) || 0 }; + selectedFurnitures.value = updated; + } + }} + class="w-12 px-1 text-center border rounded" + placeholder="Y" + /> +
+ )} +
+ ); + } + )) : selectedType.value === "avatar" ? (
diff --git a/src/routes/[username]/(store)/store/index.tsx b/src/routes/[username]/(store)/store/index.tsx index 5d67e34..dd6624e 100644 --- a/src/routes/[username]/(store)/store/index.tsx +++ b/src/routes/[username]/(store)/store/index.tsx @@ -34,6 +34,16 @@ interface ShopResponse { export const useShopLoader = routeLoader$(async ({cookie}) => { try { + // const getDotory = await axios.put(`http://localhost:8000/api/store?dotory_num=100`, { + // headers: { + // Authorization: `Bearer ${cookie.get("access_token")?.value}`, + // }, + // // }); + // const dotory = await axios.get(`http://localhost:8000/api/store`, { + // headers: { + // Authorization: `Bearer ${cookie.get("access_token")?.value}`, + // }, + // }); const res = await axios.get(`http://localhost:8000/api/room/catalog`, { headers: { Authorization: `Bearer ${cookie.get("access_token")?.value}`, @@ -51,14 +61,15 @@ export const useShopLoader = routeLoader$(async ({cookie}) => { // }); console.log(res.data); console.log(avatar.data); - return {storeData: res.data, avatarData: avatar.data, dotory: 0}; + + return {storeData: res.data, avatarData: avatar.data, dotory: 80}; } catch (error : any) { console.error(error); return { storeData: [], avatarData: null, dotory: 0}; } }); export default component$(() => { - const data = useShopLoader() as { value: ShopResponse }; + const data = useShopLoader(); const selectedItem = useSignal(null); const showBuyModal = useSignal(false); return ( @@ -84,7 +95,7 @@ export default component$(() => { class="bg-diary-color hover:bg-diary-icon-hover md:w-full text-black px-4 py-2 rounded-3xl font-bold transition-all duration-200 flex items-center gap-2 z-10 relative" onClick$={() => {showBuyModal.value = true}}> 구매하기 - +
} diff --git a/src/routes/[username]/diary/[diary_id]/edit/index.tsx b/src/routes/[username]/diary/[diary_id]/edit/index.tsx index 907845d..ae3f9e9 100644 --- a/src/routes/[username]/diary/[diary_id]/edit/index.tsx +++ b/src/routes/[username]/diary/[diary_id]/edit/index.tsx @@ -1,44 +1,272 @@ -import { component$, useSignal } from "@builder.io/qwik"; -import { DocumentHead , RequestHandler, routeLoader$} from "@builder.io/qwik-city"; -import { useNavigate } from "@builder.io/qwik-city"; +import { $, component$, useSignal, useVisibleTask$, NoSerialize, useTask$ } from "@builder.io/qwik"; +import { routeLoader$, useLocation, useNavigate } from "@builder.io/qwik-city"; import axios from "axios"; -const diaryLoader = routeLoader$<{ message: string }>(async ({params, cookie, redirect}) => { - - try { - console.log(params.username + "의 방명록 가져오기"); - const myInfo = await axios.get(`http://localhost:8000/api/user/me`, { - headers: { - Authorization: `Bearer ${cookie.get("access_token")?.value}`, - }, - }); - if(myInfo.data.username !== params.username) { - return redirect(302, `/diary/${params.diary_id}`); - } - const res = await axios.get(`http://localhost:8000/api/diary/${params.diary_id}`); - console.log(res.data); - return res.data; - } catch (error : any) { - console.error(error); - return error.response?.data?.detail || 'Diary not found'; +import { noSerialize } from "@builder.io/qwik"; +// import { PhotoUploadModal } from "~/components/features/diary/UploadImages"; +import { getCookie } from "~/utils/cookie"; +interface FileInfo { + name: string; + size: number; + type: string; + lastModified: number; + url: string; +} +interface DiaryData { + content: string; + title: string; + category: string; + images: File[]; +} +export const diaryDataLoader = routeLoader$(async ({params, cookie}) => { + const access_token = cookie.get("access_token"); + const diary_id = params.diary_id; + const diaryData = await axios.get(`http://localhost:8000/api/diary/${diary_id}`, { + headers: { + Authorization: `Bearer ${access_token?.value}`, + }, + }); + return diaryData.data; +}) +export default component$(() => { + const diaryData = diaryDataLoader(); + const content = useSignal(''); + const title = useSignal(''); + const category = useSignal(''); + const selectedImages = useSignal([] ); + const textareaRef = useSignal(); + const nav = useNavigate(); + const location = useLocation(); + const showPhotoUploadModal = useSignal(false); + const fileInfo = useSignal(null); + const fileRef = useSignal | null>(null); + const error = useSignal(''); + // const fileInputRef = useSignal(); + useTask$(() => { + content.value = diaryData.value.content; + title.value = diaryData.value.title; + category.value = diaryData.value.category; + selectedImages.value = diaryData.value.images; + }) + const handleFileSelect = $(async (selectedFile: File) => { + if (selectedFile && selectedFile.type.startsWith('image/')) { + fileInfo.value = { + name: selectedFile.name, + size: selectedFile.size, + type: selectedFile.type, + lastModified: selectedFile.lastModified, + url: URL.createObjectURL(selectedFile) + }; + fileRef.value = noSerialize(selectedFile); + error.value = ''; + console.log(fileInfo.value); + } else { + error.value = '이미지 파일만 업로드 가능합니다.'; + fileInfo.value = null; + fileRef.value = null; } }); -export default component$(() => { - const navigate = useNavigate(); - const diaryData = diaryLoader(); - - return ( -
-

일기 수정

-
- ); -}); -export const head: DocumentHead = { - title: "일기수정하기", - meta: [ - { - name: "description", - content: "유저가 쓴 일기의 상세정보", + const handleRemoveImage = $((index: number) => { + selectedImages.value = selectedImages.value.filter((_, i) => i !== index); + }); + + const handleSend = $(async () => { + try { + const formData = new FormData(); + formData.append('title', title.value); + formData.append('content', content.value); + formData.append('category', category.value); + + // Append each image file + selectedImages.value.forEach((file) => { + formData.append('file', file); + }); + + await axios.put(`http://localhost:8000/api/diary/${location.params.diary_id}`, formData, { + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: `Bearer ${getCookie("access_token")}`, }, - ], -}; \ No newline at end of file + }); + + nav(`/${location.params.username}/diary`); + } catch (error: any) { + console.error('Error creating diary:', error); + } + }); + useVisibleTask$(({ track }) => { + track(() => content.value); + if (textareaRef.value) { + textareaRef.value.style.height = 'auto'; + textareaRef.value.style.height = `${textareaRef.value.scrollHeight}px`; + } + }); + + return ( +
+
+

일기 쓰기

+
+
+ +
+ + +
+
+ + {/* Image upload and preview section */} +
+
+ {selectedImages.value.map((image, index) => ( +
+ {`Preview + +
+ ))} + +
+ +
+
+