๐ dummydata ๊ตฌํ
DummyData.js
export const campgrounds = {
data: [
{
productId: 2,
productName: "์บ ํ์ฅ2",
address: "ํ๊ฐ ์ด๋๊ฐ2",
location: "์์ธ2",
content: "์บ ํ์ฅ ๋น๋ ค๋๋ฆฝ๋๋ค.2",
capacity: 10,
cancellationDeadline: "2023-05-03T10:00:00",
productPrice: 30000,
productPhone: "010-1234-1111",
latitude: null,
longitude: null,
deleted: false,
createdAt: "2023-05-10T09:24:02.995997",
createdBy: "name",
modifiedAt: "2023-05-10T09:24:02.995997",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 1,
productName: "new์บ ํ์ฅ",
address: "newํ๊ฐ ์ด๋๊ฐ",
location: "new์์ธ",
content: "new์บ ํ์ฅ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 3,
productName: "์์ธํน๋ณ์",
address: "์์ธํน๋ณ์",
location: "์์ธํน๋ณ์",
content: "์ฌํ
๋ฉด์๋ผ.",
capacity: 10000,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 4,
productName: "๋๊ตฌ๊ด์ญ์",
address: "๋๊ตฌ๊ด์ญ์",
location: "๋๊ตฌ๊ด์ญ์",
content: "๋๊ตฌ๊ด์ญ์๋ฅผ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 5,
productName: "๋์ ๊ด์ญ์",
address: "๋์ ๊ด์ญ์",
location: "๋์ ๊ด์ญ์",
content: "๋์ ๊ด์ญ์ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 6,
productName: "๊ด์ฃผ๊ด์ญ์",
address: "๊ด์ฃผ๊ด์ญ์",
location: "๊ด์ฃผ๊ด์ญ์",
content: "๊ด์ฃผ๊ด์ญ์ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 7,
productName: "์ธ์ฐ๊ด์ญ์",
address: "์ธ์ฐ๊ด์ญ์",
location: "์ธ์ฐ๊ด์ญ์",
content: "์ธ์ฐ๊ด์ญ์ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 8,
productName: "์ธ์ฒ๊ด์ญ์",
address: "์ธ์ฒ๊ด์ญ์ ์ด๋๊ฐ",
location: "์ธ์ฒ๊ด์ญ์",
content: "์ธ์ฒ๊ด์ญ์ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 9,
productName: "๋ถ์ฐ๊ด์ญ์",
address: "๋ถ์ฐ๊ด์ญ์ ์ด๋๊ฐ",
location: "๋ถ์ฐ๊ด์ญ์",
content: "๋ถ์ฐ๊ด์ญ์ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
{
productId: 10,
productName: "์ ์ฃผํน๋ณ์์น๋ ",
address: "์ ์ฃผํน๋ณ์์น๋ ์ด๋๊ฐ",
location: "์ ์ฃผํน๋ณ์์น๋ ",
content: "์ ์ฃผํน๋ณ์์น๋ ๋น๋ ค๋๋ฆฝ๋๋ค.",
capacity: 10,
cancellationDeadline: "2023-05-05T00:35:17",
productPrice: 30000,
productPhone: "010-1234-5337",
latitude: 37.5,
longitude: 40.5,
deleted: false,
createdAt: "2023-05-10T09:21:24.770742",
createdBy: "name",
modifiedAt: "2023-05-10T09:21:46.344073",
modifiedBy: "name",
imageUrl: "http://~",
memberId: 1,
},
],
pageInfo: {
page: 1,
size: 10,
totalElements: 10,
totalPages: 1,
},
};
export const dummyUsers = [
{
memberId: 1,
name: "๊น์ฝ๋ฉ",
email: "example@gmail.com",
createdAt: "2023-05-10T00:56:10.906617",
modifiedAt: "2023-05-10T00:56:10.906631",
createdBy: "example@gmail.com",
modifiedBy: "example@gmail.com",
phone: "010-1111-2222",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: false,
businessRegistrationNumber: null,
},
{
memberId: 2,
name: "์กฐ์ฝ๋ฉ",
email: "example2@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example2@gmail.com",
modifiedBy: "example2@gmail.com",
phone: "010-2222-3333",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 3,
name: "์ฝ์ฝ๋ฉ",
email: "example3@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example3@gmail.com",
modifiedBy: "example3@gmail.com",
phone: "010-3333-3333",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 4,
name: "์ค์ฝ๋ฉ",
email: "example4@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example4@gmail.com",
modifiedBy: "example4@gmail.com",
phone: "010-0000-0000",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 5,
name: "์ต์ฝ๋ฉ",
email: "example5@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example5@gmail.com",
modifiedBy: "example5@gmail.com",
phone: "010-5555-5555",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 6,
name: "๋ฉ์ฝ๋ฉ",
email: "example6@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example6@gmail.com",
modifiedBy: "example6@gmail.com",
phone: "010-6666-6666",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 7,
name: "๋ฐ์ฝ๋ฉ",
email: "example7@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example7@gmail.com",
modifiedBy: "example7@gmail.com",
phone: "010-7777-7777",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 8,
name: "ํ์ฝ๋ฉ",
email: "example8@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example8@gmail.com",
modifiedBy: "example8@gmail.com",
phone: "010-1234-4321",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 9,
name: "๊ฐ์ฝ๋ฉ",
email: "example9@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example9@gmail.com",
modifiedBy: "example9@gmail.com",
phone: "010-9999-9999",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
{
memberId: 10,
name: "์ ์ฝ๋ฉ",
email: "example10@gmail.com",
createdAt: "2023-05-10T00:56:55.746517",
modifiedAt: "2023-05-10T00:56:55.746559",
createdBy: "example10@gmail.com",
modifiedBy: "example10@gmail.com",
phone: "010-1010-1010",
reward_points: 0,
memberStatus: "MEMBER_ACTIVE",
memberShip: "BASIC",
birthDate: "2000-01-01",
usageCount: 0,
favoriteId: 1,
isEmailVerified: true,
isSellerVerifed: true,
businessRegistrationNumber: "123-12-12345",
},
];
export const dummyChats = [
{
id: 1,
customer: false,
content: "ํฌํฌํฌํฌํํฌํฌํฌํฌํฌํฌํฌ",
},
{
id: 2,
customer: true,
content: "ํฌํฌํฌํฌํํฌํฌํฌํฌํฌํฌํฌ",
},
{
id: 3,
customer: true,
content: "ํฌํฌํฌํฌํํฌํฌํฌํฌํฌํฌํฌ",
},
{
id: 4,
customer: true,
content: "ํฌํฌํฌํฌํํฌํฌํฌํฌํฌํฌํฌ",
},
];
card2.jsx
import styled from "@emotion/styled";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPhone, faMap, faUser } from "@fortawesome/free-solid-svg-icons";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
import { useState } from "react";
const Container = styled.div`
background-color: transparent;
width: 250px;
height: 350px;
perspective: 1000px;
border-radius: 10px;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
transition: border-radius 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
&:hover .inner {
transform: rotateY(180deg);
}
`;
const Inner = styled.div`
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s;
transform-style: preserve-3d;
`;
const Front = styled.div`
position: absolute;
width: 100%;
height: 100%;
border-radius: 2em;
backface-visibility: hidden;
background-color: ${(props) =>
props.isDark ? "var(--white-50)" : "var(--white)"};
color: var(--black-700);
border: none;
display: flex;
flex-direction: column;
align-items: center;
`;
const Img = styled.div`
display: flex;
align-items: center;
border: none;
border-radius: 30px;
width: 100%;
height: 200px;
background-image: url(${(props) => props.bgphoto});
background-size: cover;
background-position: center;
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
`;
const Name = styled.div`
margin-bottom: 10px;
font-size: 18px;
`;
const Selection = styled.div`
margin: 30px 0 10px 0;
font-size: 13px;
/* color : #DF2E38; */
`;
const Price = styled.div`
/* margin: 30px 0 10px 0; */
font-size: 25px;
`;
const Back = styled.div`
position: absolute;
width: 100%;
height: 100%;
border-radius: 2em;
backface-visibility: hidden;
background-color: ${(props) =>
props.isDark ? "var(--white-50)" : "var(--white)"};
border: none;
transform: rotateY(180deg);
padding: 11px;
`;
const Info = styled.div`
width: 100%;
height: 100%;
letter-spacing: 1px;
display: grid;
grid-template-rows: 3fr 1fr;
align-items: center;
justify-content: center;
text-align: center; // ์ถ๊ฐ
`;
const Descriptions = styled.div`
width: 250px;
padding: 0 10px;
/* height: 300px; */
display: flex;
justify-content: center;
align-items: center;
text-align: center; // ์ถ๊ฐ
color: var(--black-700);
`;
const Description = styled.div`
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
text-align: center; // ์ถ๊ฐ
`;
const Icons = styled.div`
display: flex;
justify-content: space-around;
align-items: center;
color: var(--black-700);
margin-bottom: 100px;
`;
const Icon = styled(FontAwesomeIcon)`
font-size: 25px;
cursor: pointer;
`;
const loremIpsum = "์ง๊ธ ๋ฐ๋ก ์์ฝํ์ธ์!";
export default function Card2({ campground }) {
const isDark = useSelector((state) => state.modeReducer);
const [infoType, setInfoType] = useState(null);
const handleInfoType = (clickedType) => {
setInfoType((prev) => clickedType);
};
const getInfo = (type) => {
switch (type) {
case "seller":
return `ํ๋งค์: ์์ ํ์!`;
case "call":
return `์์ฌ๋ฒํธ: ${campground.productPhone}`;
case "location":
return `์์น: ${campground.location}`;
default:
return campground.content;
}
};
return (
<Container>
<Inner className="inner">
<Front isDark={isDark}>
<Img
bgphoto={
campground.imageUrl === "http://~"
? "https://yeyak.seoul.go.kr/cmsdata/web_upload/svc/20230329/1680050914280HZAYFX8GLLMTVZI2H6BD0WGPV_IM02.jpg"
: campground.imageUrl
}
/>
<Selection>
{campground.capacity},{campground.productPrice}
</Selection>
<Name>{campground.productName}</Name>
<Price>{campground.productPrice}</Price>
</Front>
<Back isDark={isDark}>
<Info>
<Link to={`/${campground.id}`}>
<Descriptions isDark={isDark}>
<Description>{getInfo(infoType)}</Description>
</Descriptions>
</Link>
<Icons isDark={isDark}>
<Icon onClick={() => handleInfoType("seller")} icon={faUser} />
<Icon onClick={() => handleInfoType("call")} icon={faPhone} />
<Icon onClick={() => handleInfoType("location")} icon={faMap} />
</Icons>
</Info>
</Back>
</Inner>
</Container>
);
}
Main.JSX
import styled from "@emotion/styled";
import { useSelector } from "react-redux";
import { campgrounds } from "../Dummy/DummyDatas";
import { useEffect, useRef, useState } from "react";
import Card2 from "../Components/Card2";
import { FaChevronUp } from "react-icons/fa";
const Loader = styled.h1`
font-size: 50px;
font-weight: bold;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
`;
const Container = styled.main`
max-width: 1200px;
margin: 0 auto;
width: 100%;
height: auto;
display: grid;
grid-template-columns: 1fr;
@media screen and (min-width: 900px) {
grid-template-columns: repeat(2, 1fr);
}
@media screen and (min-width: 1100px) {
grid-template-columns: repeat(3, 1fr);
}
@media screen and (min-width: 1300px) {
grid-template-columns: repeat(4, 1fr);
}
gap: 20px;
justify-items: center;
padding: 50px 0;
padding-top: 200px;
`;
const ContextArea = styled.div`
width: 100%;
margin-top: 50px;
position: absolute;
padding: 35px 0;
top: 0;
left: 0;
`;
const Title = styled.h2`
margin-left: 150px !important;
font-family: "Noto Sans KR", sans-serif;
color: ${(props) => (props.isDark ? "var(--white-50)" : "var(--black-700)")};
`;
const ScrollBtn = styled.div`
width: 120px;
height: 70px;
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
`;
const TempWrapper = styled.div`
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
`;
// ๊ด์ธก์ ์ ์ฉํ ์ ์๋ ์ต์
const options = {
root: null,
rootMargin: "0px",
threshold: 1.0,
};
export default function Main() {
const isDark = useSelector((state) => state.modeReducer);
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
// ํ๊ฒ ์์ ์ง์
let containerRef = useRef(null);
useEffect(() => {
(async () => {
setIsLoading((prev) => true);
// ๋์ค์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์์ผ ํจ
setData((prev) => [...campgrounds.data]);
setIsLoading((prev) => false);
})();
}, []);
// ๋ฌดํ ์คํฌ๋กค์ ์ํ useEffect
useEffect(() => {
(async () => {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
// ๋ฐ์ดํฐ ๋ ๋ถ๋ฌ์ค๊ธฐ
}
}, options);
if (containerRef.current) {
observer.observe(containerRef.current);
}
return () => {
observer.disconnect();
};
})();
}, [containerRef]);
return isLoading ? (
<Loader>isLoading...</Loader>
) : (
<>
<ContextArea isDark={isDark}>
<Title isDark={isDark}>์ง๊ธ ๋น์ฅ ์บ ํ์ ๋ ๋๋ณด์ธ์.โบ</Title>
</ContextArea>
<Container>
{data.map((campground) => (
<Card2 key={campground.id + ""} campground={campground} />
))}
</Container>
<ScrollBtn onClick={() => window.scrollTo(0, 0)} ref={containerRef}>
<FaChevronUp size={40} />
</ScrollBtn>
</>
);
}
์คํํ๋ฉด