Skip to content

Commit 6f9383e

Browse files
committed
add skelton in info and build tabs
1 parent bf90afd commit 6f9383e

3 files changed

Lines changed: 102 additions & 24 deletions

File tree

src/pages/Feature/Tabs/PropertyConstruction/Tabs/components/ChoosingEnvironment.jsx

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import styled from "styled-components";
33
import { FeatureContext } from "../../../../Context/FeatureProvider";
44

55
import useRequest from "../../../../../../services/Hooks/useRequest";
6-
import Eye from "../../../../../../assets/svg/eye.svg?react";
6+
import Eye from "../../../../../../assets/svg/eye.svg?react";
7+
import { Skeleton } from "../../../../../../components/Skeleton";
78

89
import PreviewModel from "./PreviewModel";
910
import { useSelectedEnvironment } from "../../../../../../services/reducers/SelectedEnvironmentContext";
@@ -12,7 +13,6 @@ const Container = styled.div`
1213
gap: 10px;
1314
grid-template-columns: repeat(2, minmax(0, 1fr));
1415
display: grid;
15-
1616
width: 100%;
1717
1818
@media (max-width: 1024px) {
@@ -83,19 +83,32 @@ const SelectorEnvironment = styled.button`
8383
}
8484
`;
8585

86+
// اسکلتون برای آیتم‌ها
87+
const SkeletonImgHolder = styled.div`
88+
width: 100%;
89+
height: 180px;
90+
border-radius: 10px;
91+
position: relative;
92+
93+
@media (max-width: 768px) {
94+
height: 120px;
95+
}
96+
`;
97+
8698
const ChoosingEnvironment = () => {
8799
const [feature] = useContext(FeatureContext);
88100
const { Request, HTTP_METHOD } = useRequest();
89101
const [data, setData] = useState([]);
90102
const [preview, setPreview] = useState(null);
91103
const [showModal, setShowModal] = useState(false);
92-
93104
const [coordinates, setCoordinates] = useState([]);
94105
const [activeIndex, setActiveIndex] = useState(null);
95106
const { addSelectedEnvironment, hiddenModel, setHiddenModel, isSelectable } =
96107
useSelectedEnvironment() || {};
97108
const [page, setPage] = useState(1);
98109
const [loading, setLoading] = useState(false);
110+
const [initialLoading, setInitialLoading] = useState(true);
111+
99112
useEffect(() => {
100113
const fetchData = async () => {
101114
setLoading(true);
@@ -106,9 +119,11 @@ const ChoosingEnvironment = () => {
106119
);
107120
setData((prevData) => [...prevData, ...res.data.data]);
108121
setCoordinates([res.data.feature.coordinates]);
109-
setLoading(false);
110122
} catch (err) {
123+
console.error(err);
124+
} finally {
111125
setLoading(false);
126+
setInitialLoading(false);
112127
}
113128
};
114129
fetchData();
@@ -124,8 +139,14 @@ const ChoosingEnvironment = () => {
124139
}
125140
};
126141
const container = document.querySelector("#scrollable-container");
127-
container.addEventListener("scroll", handleScroll);
128-
return () => container.removeEventListener("scroll", handleScroll);
142+
if (container) {
143+
container.addEventListener("scroll", handleScroll);
144+
}
145+
return () => {
146+
if (container) {
147+
container.removeEventListener("scroll", handleScroll);
148+
}
149+
};
129150
}, [loading]);
130151

131152
const handleSelectorClick = (index) => {
@@ -141,18 +162,30 @@ const ChoosingEnvironment = () => {
141162
}
142163
};
143164

165+
// اسکلتون لودینگ اولیه
166+
if (initialLoading) {
167+
return (
168+
<Container id="scrollable-container">
169+
{Array.from({ length: 6 }).map((_, index) => (
170+
<SkeletonImgHolder key={index}>
171+
<Skeleton width="100%" height="180px" radius="10px" />
172+
</SkeletonImgHolder>
173+
))}
174+
</Container>
175+
);
176+
}
177+
144178
return (
145179
<>
146180
<Container id="scrollable-container">
147181
{data &&
148-
data.map((data, index) => {
182+
data.map((item, index) => {
149183
return (
150-
<ImgHolder key={data.id}>
151-
<Img src={data.images[0].url} alt="" />
152-
184+
<ImgHolder key={item.id}>
185+
<Img src={item.images?.[0]?.url} alt="" />
153186
<ViewHolder
154187
onClick={() => {
155-
setPreview(data);
188+
setPreview(item);
156189
setShowModal(true);
157190
}}
158191
>
@@ -166,14 +199,23 @@ const ChoosingEnvironment = () => {
166199
);
167200
})}
168201
</Container>
202+
203+
{/* اسکلتون لودینگ بیشتر (اینفینیتی اسکرول) */}
204+
{loading && data.length > 0 && (
205+
<Container>
206+
{Array.from({ length: 2 }).map((_, index) => (
207+
<SkeletonImgHolder key={`loading-${index}`}>
208+
<Skeleton width="100%" height="180px" radius="10px" />
209+
</SkeletonImgHolder>
210+
))}
211+
</Container>
212+
)}
213+
169214
{showModal && preview && (
170-
<PreviewModel
171-
data={[preview]}
172-
setShowModal={setShowModal}
173-
/>
215+
<PreviewModel data={[preview]} setShowModal={setShowModal} />
174216
)}
175217
</>
176218
);
177219
};
178220

179-
export default ChoosingEnvironment;
221+
export default ChoosingEnvironment;

src/pages/Feature/Tabs/info-tab/Album.jsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import {
1111
ToastSuccess,
1212
getFieldTranslationByNames,
1313
} from "../../../../services/Utility";
14+
import { Skeleton } from "../../../../components/Skeleton";
15+
1416
const AlbumWrapper = styled.div`
1517
display: grid;
16-
1718
grid-template-columns: 1fr 1fr 1fr;
1819
align-items: center;
1920
gap: 20px;
@@ -93,13 +94,20 @@ const IconWrapper = styled.div`
9394
}
9495
`;
9596

96-
const Album = ({ feature, setFeature }) => {
97+
// اسکلتون برای آیتم‌های آلبوم
98+
const SkeletonImageWrapper = styled.div`
99+
width: 100%;
100+
height: 150px;
101+
border-radius: 10px;
102+
background-color: ${(props) => props.theme.colors.newColors.otherColors.gray};
103+
`;
104+
105+
const Album = ({ feature, setFeature, isLoading }) => {
97106
const [user] = useContext(UserContext);
98107
const [open, setOpen] = useState(false);
99108
const [activeImage, setActiveImage] = useState(feature?.images?.[0] || null);
100109
const { Request, HTTP_METHOD, checkSecurity } = useRequest();
101110
const inputRef = useRef();
102-
// if (feature?.owner_id === userId) return SellTabPanel;
103111

104112
const handleImageUpload = (event) => {
105113
if (!checkSecurity()) return;
@@ -151,6 +159,22 @@ const Album = ({ feature, setFeature }) => {
151159
});
152160
};
153161

162+
// اسکلتون لودینگ
163+
if (isLoading) {
164+
return (
165+
<AlbumWrapper>
166+
{Array.from({ length: 4 }).map((_, index) => (
167+
<SkeletonImageWrapper key={index}>
168+
<Skeleton width="100%" height="150px" radius="10px" />
169+
</SkeletonImageWrapper>
170+
))}
171+
<UploadMore>
172+
<span>+</span>
173+
</UploadMore>
174+
</AlbumWrapper>
175+
);
176+
}
177+
154178
return (
155179
<div>
156180
<AlbumWrapper>
@@ -205,4 +229,4 @@ const Album = ({ feature, setFeature }) => {
205229
);
206230
};
207231

208-
export default Album;
232+
export default Album;
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useContext } from "react";
1+
import { useContext, useState, useEffect } from "react";
22
import { FeatureContext } from "../../Context/FeatureProvider";
33
import { Album, FirstRow, SecondRow, ThirdRow } from "../index";
44
import Container from "../../../../components/Common/Container";
@@ -8,21 +8,33 @@ const Div = styled.div`
88
display: flex;
99
flex-direction: column;
1010
gap: 20px;
11-
1211
`;
1312

1413
const InfoTab = () => {
1514
const [feature, setFeature] = useContext(FeatureContext);
15+
const [loading, setLoading] = useState(true);
16+
17+
useEffect(() => {
18+
// وقتی feature اومد، لودینگ رو false کن
19+
if (feature) {
20+
setLoading(false);
21+
}
22+
}, [feature]);
23+
1624
return (
1725
<Container>
1826
<Div>
1927
<FirstRow feature={feature} />
2028
<SecondRow feature={feature} />
2129
<ThirdRow feature={feature} />
2230
</Div>
23-
<Album feature={feature} setFeature={setFeature} />
31+
<Album
32+
feature={feature}
33+
setFeature={setFeature}
34+
isLoading={loading}
35+
/>
2436
</Container>
2537
);
2638
};
2739

28-
export default InfoTab;
40+
export default InfoTab;

0 commit comments

Comments
 (0)