Skip to content

Commit

Permalink
정보 상세 페이지 Skeleton 컴포넌트 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
HyunJinNo committed Jun 30, 2024
1 parent 85e6b1b commit 465d26c
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 117 deletions.
9 changes: 7 additions & 2 deletions src/app/informations/(detail)/[category]/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import InformationViewer from "@/components/informations/InformationViewer";
import PagePath from "@/components/informations/PagePath";
import RecommendationList from "@/components/informations/RecommendationList";
import InformationViewerSkeleton from "@/components/skeleton/informations/InformationViewerSkeleton";
import RecommendationListSkeleton from "@/components/skeleton/informations/RecommendationListSkeleton";
import { CATEGORY_TEXT } from "@/constants/informations/category";
import InformationViewerContainer from "@/containers/informations/InformationViewerContainer";
import { Suspense } from "react";

type MyProps = {
Expand Down Expand Up @@ -36,7 +38,10 @@ export default function page({ params: { category, id } }: MyProps) {

return (
<div className="flex flex-col items-center">
<InformationViewerContainer category={category} id={postId} />
<PagePath category={`${CATEGORY_TEXT[category]} 상세`} />
<Suspense fallback={<InformationViewerSkeleton />}>
<InformationViewer />
</Suspense>
<Suspense fallback={<RecommendationListSkeleton />}>
<RecommendationList />
</Suspense>
Expand Down
65 changes: 65 additions & 0 deletions src/components/informations/ImageViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useDragScrollType } from "@/hooks/useDragScroll";
import Image from "next/image";

type MyProps = {
images: string[];
mainImageIndex: number;
scrollHook: useDragScrollType;
setMainImageIndex: (index: number) => void;
};

const ImageViewer = ({
images,
mainImageIndex,
scrollHook,
setMainImageIndex,
}: MyProps) => {
return (
<div>
<div className="relative h-[26.0625rem] w-full max-[744px]:h-[19.125rem]">
<Image
className="rounded-2xl"
src={images[mainImageIndex]}
alt={"/background"}
fill={true}
style={{
objectFit: "cover",
}}
/>
</div>
<div
className="flex flex-row items-center gap-[0.875rem] overflow-x-auto pt-[0.875rem]"
ref={scrollHook.listRef}
onMouseDown={(e) => {
e.preventDefault();
scrollHook.onDragStart(e);
}}
onMouseMove={scrollHook.onDragMove}
onMouseUp={scrollHook.onDragEnd}
onMouseLeave={scrollHook.onDragEnd}
onTouchStart={scrollHook.onTouchStart}
onTouchMove={scrollHook.onTouchMove}
onTouchEnd={scrollHook.onTouchEnd}
>
{images.map((image, index) => (
<Image
key={index}
className="cursor-pointer rounded-lg"
src={image}
alt={"/background"}
width={107}
height={107}
onClick={(e) => {
setMainImageIndex(index);
}}
onTouchEnd={(e) => {
setMainImageIndex(index);
}}
/>
))}
</div>
</div>
);
};

export default ImageViewer;
79 changes: 5 additions & 74 deletions src/components/informations/InformationViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
import ItemTag from "./ItemTag";
import Image from "next/image";
import PagePath from "./PagePath";
import { MouseEvent, RefObject, TouchEvent } from "react";
import { FaRegHeart } from "react-icons/fa";
import { TiLocation } from "react-icons/ti";
import KakaoMapLinkContainer from "@/containers/common/KakaoMapLinkContainer";
import { CATEGORY_TEXT } from "@/constants/informations/category";

type MyProps = {
category: string;
id: number;
mainImageIndex: number;
listRef: RefObject<HTMLDivElement>;
onDragStart: (e: MouseEvent<HTMLDivElement>) => void;
onDragMove: (e: MouseEvent<HTMLDivElement>) => void;
onDragEnd: (e: MouseEvent<HTMLDivElement>) => void;
onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;
onTouchMove: (e: TouchEvent<HTMLDivElement>) => void;
onTouchEnd: (e: TouchEvent<HTMLDivElement>) => void;
setMainImageIndex: (index: number) => void;
};
import ImageViewerContainer from "@/containers/informations/ImageViewerContainer";

// TODO
const InformationViewer = ({
category,
id,
mainImageIndex,
listRef,
onDragStart,
onDragMove,
onDragEnd,
onTouchStart,
onTouchMove,
onTouchEnd,
setMainImageIndex,
}: MyProps) => {
//const info = await fetch("")
const InformationViewer = async () => {
await new Promise((resolve) => setTimeout(resolve, 3000));

const info = {
title: "책과 공간이 매력적인 선릉역 테라로사",
username: "하몽",
Expand Down Expand Up @@ -66,7 +39,6 @@ const InformationViewer = ({

return (
<div className="w-[60rem] max-[1024px]:w-[39.75rem] max-[744px]:w-[calc(100%_-_48px)]">
<PagePath category={`${CATEGORY_TEXT[category]} 상세`} />
<div className="flex flex-row items-center justify-between overflow-x-hidden max-[1024px]:flex-col">
<div className="w-full pb-4 lg:hidden">
<h1 className="text-2xl font-bold">{info.title}</h1>
Expand Down Expand Up @@ -104,48 +76,7 @@ const InformationViewer = ({
</div>
</div>
<div className="h-[34.5rem] w-[29.375rem] max-[1024px]:w-full max-[744px]:h-[27.5625rem]">
<div className="relative h-[26.0625rem] w-full max-[744px]:h-[19.125rem]">
<Image
className="rounded-2xl"
src={info.images[mainImageIndex]}
alt={"/background"}
fill={true}
style={{
objectFit: "cover",
}}
/>
</div>
<div
className="flex flex-row items-center gap-[0.875rem] overflow-x-auto pt-[0.875rem]"
ref={listRef}
onMouseDown={(e) => {
e.preventDefault();
onDragStart(e);
}}
onMouseMove={onDragMove}
onMouseUp={onDragEnd}
onMouseLeave={onDragEnd}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onTouchEnd={onTouchEnd}
>
{info.images.map((image, index) => (
<Image
key={index}
className="cursor-pointer rounded-lg"
src={image}
alt={"/background"}
width={107}
height={107}
onClick={(e) => {
setMainImageIndex(index);
}}
onTouchEnd={(e) => {
setMainImageIndex(index);
}}
/>
))}
</div>
<ImageViewerContainer images={info.images} />
</div>
<div className="flex h-[34.5rem] w-[29.375rem] flex-col overflow-y-auto px-[1.25rem] max-[1024px]:h-fit max-[1024px]:w-full max-[1024px]:px-0 max-[1024px]:pt-8">
<div className="max-[1024px]:hidden">
Expand Down
112 changes: 112 additions & 0 deletions src/components/skeleton/informations/InformationViewerSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const InformationViewerSkeleton = () => {
return (
<div className="w-[60rem] animate-pulse max-[1024px]:w-[39.75rem] max-[744px]:w-[calc(100%_-_48px)]">
<div className="flex flex-row items-center justify-between overflow-x-hidden max-[1024px]:flex-col">
<div className="w-full pb-4 lg:hidden">
<div className="h-10 w-96 bg-gray-100" />
<div className="flex flex-row items-end justify-between py-4">
<div className="flex flex-row items-center gap-2">
<div className="h-12 w-12 rounded-full bg-gray-100 shadow" />
<div className="space-y-1">
<p className="h-4 w-8 bg-gray-100" />
<p className="h-4 w-20 bg-gray-100" />
</div>
</div>
<div className="flex flex-row items-center gap-3">
<div className="flex flex-row items-center gap-1 text-gray2">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
<div className="flex flex-row items-center gap-1 text-gray2">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
</div>
</div>
</div>
<div className="h-[34.5rem] w-[29.375rem] max-[1024px]:w-full max-[744px]:h-[27.5625rem]">
<div className="h-[26.0625rem] w-full rounded-2xl bg-gray-100 max-[744px]:h-[19.125rem]" />
<div className="flex w-fit flex-row items-center gap-[0.875rem] overflow-x-hidden pt-[0.875rem]">
{[1, 2, 3, 4].map((value) => (
<div
key={value}
className="h-[6.6875rem] w-[6.6875rem] rounded-lg bg-gray-100"
/>
))}
</div>
</div>
<div className="flex h-[34.5rem] w-[29.375rem] flex-col overflow-y-auto px-[1.25rem] max-[1024px]:h-fit max-[1024px]:w-full max-[1024px]:px-0 max-[1024px]:pt-8">
<div className="max-[1024px]:hidden">
<div className="h-10 w-96 bg-gray-100" />
<div className="flex flex-row items-end justify-between py-4">
<div className="flex flex-row items-center gap-2">
<div className="h-12 w-12 rounded-full bg-gray-100 shadow" />
<div className="space-y-1">
<p className="h-4 w-8 bg-gray-100" />
<p className="h-4 w-20 bg-gray-100" />
</div>
</div>
<div className="flex flex-row items-center gap-3">
<div className="flex flex-row items-center gap-1 text-gray2">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
<div className="flex flex-row items-center gap-1 text-gray2">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
</div>
</div>
</div>
<div className="flex flex-row items-center gap-1 py-3">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-60 bg-gray-100" />
</div>
<div className="flex flex-col gap-2 py-4">
<div className="h-5 w-full bg-gray-100" />
<div className="h-5 w-full bg-gray-100" />
<div className="h-5 w-full bg-gray-100" />
<div className="h-5 w-full bg-gray-100" />
<div className="h-5 w-20 bg-gray-100" />
</div>
<div className="flex flex-row items-center gap-1 pb-8">
<div className="h-6 w-16 rounded-full bg-gray-100" />
<div className="h-6 w-16 rounded-full bg-gray-100" />
<div className="h-6 w-16 rounded-full bg-gray-100" />
</div>
<div className="flex flex-col gap-3 border-y-2 border-gray3 px-6 py-4">
<div className="h-6 w-32 bg-gray-100" />
{[1, 2, 3].map((value) => (
<div
key={value}
className="ml-6 h-5 w-80 bg-gray-100 align-baseline"
/>
))}
</div>
</div>
</div>
<div className="mt-20 flex h-48 flex-col">
<div className="h-48 w-full rounded-2xl border-[0.0625rem] bg-gray-100" />
</div>
<div className="-mt-4 flex h-fit w-full flex-col justify-center gap-2 rounded-b-2xl border-x-[0.0625rem] border-b-[0.0625rem] px-6 pb-10 pt-12">
<div className="h-8 w-40 bg-gray-100" />
<div className="flex flex-row items-start gap-1">
<div className="h-5 w-5 bg-gray-100" />
<div className="h-5 w-80 bg-gray-100" />
</div>
</div>
<div className="mt-6 flex flex-row items-center justify-end gap-3">
<div className="flex flex-row items-center gap-1">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
<div className="flex flex-row items-center gap-1">
<div className="h-4 w-4 bg-gray-100" />
<div className="h-4 w-7 bg-gray-100" />
</div>
</div>
</div>
);
};

export default InformationViewerSkeleton;
25 changes: 25 additions & 0 deletions src/containers/informations/ImageViewerContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";

import ImageViewer from "@/components/informations/ImageViewer";
import useDragScroll from "@/hooks/useDragScroll";
import { useState } from "react";

type MyProps = {
images: string[];
};

const ImageViewerContainer = ({ images }: MyProps) => {
const [mainImageIndex, setMainImageIndex] = useState<number>(0);
const scrollHook = useDragScroll();

return (
<ImageViewer
images={images}
mainImageIndex={mainImageIndex}
scrollHook={scrollHook}
setMainImageIndex={setMainImageIndex}
/>
);
};

export default ImageViewerContainer;
41 changes: 0 additions & 41 deletions src/containers/informations/InformationViewerContainer.tsx

This file was deleted.

0 comments on commit 465d26c

Please sign in to comment.