Skip to content

Commit 66d54da

Browse files
committed
fixes for imagedetails
1 parent ebced21 commit 66d54da

File tree

3 files changed

+362
-72
lines changed

3 files changed

+362
-72
lines changed

frontend/src/components/ExplorePageSection1/CardDetailPage.jsx

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { useState, useEffect } from "react";
1+
import { useEffect, useState } from "react";
22
import { useParams, Link } from "react-router-dom";
33
import Breadcrumb from "./Breadcrumb";
44
import styles from "./CardDetailPage.module.css";
55
import { fetchPinById } from "../../services/pinService";
6+
import ShopItem from "./ShopItem";
67

78
const CardDetailPage = () => {
89
const { id } = useParams();
910
const [pin, setPin] = useState(null);
1011
const [loading, setLoading] = useState(true);
1112
const [relatedPins, setRelatedPins] = useState([]);
12-
const [error, setError] = useState(null);
1313

1414
useEffect(() => {
1515
const loadPin = async () => {
@@ -18,106 +18,103 @@ const CardDetailPage = () => {
1818
const fetchedPin = await fetchPinById(id);
1919
setPin(fetchedPin);
2020

21-
// Load related pins
22-
try {
23-
const res = await fetch(
24-
`http://localhost:4000/api/pins/${id}/related`
25-
);
26-
if (res.ok) {
27-
const related = await res.json();
28-
setRelatedPins(related);
29-
} else {
30-
console.error("Could not load related pins");
31-
setRelatedPins([]);
32-
}
33-
} catch (error) {
34-
console.error("Error loading related pins:", error);
21+
// Load related pins (optional)
22+
23+
const res = await fetch(`/api/pins/${id}/related`);
24+
if (res.ok) {
25+
const related = await res.json();
26+
setRelatedPins(related);
27+
} else {
28+
console.error("Could not load related pins");
3529
setRelatedPins([]);
3630
}
3731
} catch (error) {
38-
console.error("Error loading pin:", error);
39-
setError("Failed to load pin details");
32+
console.error("Error loading pin or related pins:", error);
4033
} finally {
4134
setLoading(false);
4235
}
4336
};
4437
loadPin();
4538
}, [id]);
4639

40+
const categories = [
41+
{ name: "Explore", link: "/explore" },
42+
{ name: "Electronics", link: "/electronics" },
43+
{ name: "Cell Phones And Accessories", link: "/phones-accessories" },
44+
{ name: "Phone Accessories", link: "/phone-accessories" }
45+
];
46+
4747
if (loading) {
4848
return <div className={styles.cardDetailPage}>Loading...</div>;
4949
}
5050

51-
if (error) {
52-
return <div className={styles.cardDetailPage}>{error}</div>;
53-
}
54-
5551
if (!pin) {
5652
return <div className={styles.cardDetailPage}>Pin not found!</div>;
5753
}
5854

59-
const breadcrumbItems = [
60-
{ name: "Explore", link: "/explore" },
61-
{
62-
name: pin.category?.title || "Category",
63-
link: `/category/${pin.category?.id}`
64-
}
65-
];
66-
6755
return (
68-
<div className={styles.cardDetailPage}>
69-
<Breadcrumb categories={breadcrumbItems} />
56+
<>
57+
<div className={styles.cardDetailPage}>
58+
<Breadcrumb categories={categories} />
59+
{/* Show the ShopItem component here */}
60+
61+
<ShopItem imageSrc={pin.imageUrl} />
62+
63+
{/*
7064
<div className={styles.cardImageContainer}>
7165
<img src={pin.imageUrl} alt={pin.altText || pin.title} />
7266
<div className={styles.cardOverlay}>
7367
<h1>{pin.title}</h1>
7468
<p>{pin.description}</p>
7569
</div>
7670
</div>
77-
<h3>{pin.tags?.map(tag => tag.name).join(", ")}</h3>
71+
*/}
7872

79-
<div className={styles.galleryContainer}>
80-
<div className={styles.gallery}>
81-
{relatedPins.length > 0 ? (
82-
relatedPins.map(pin => (
83-
<div key={pin.id} className={styles.imageContainer}>
84-
<div className={styles.imageWrapper}>
85-
<img
86-
src={pin.imageUrl}
87-
alt={pin.altText || pin.title}
88-
className={styles.image}
89-
/>
90-
<Link to={`/pin/${pin.id}`} className={styles.overlay}>
91-
<span className={styles.overlayText}>Open</span>
92-
<div className={styles.overlayButtons}>
93-
<img
94-
src="/images/share-icon.svg"
95-
alt="Share"
96-
className={styles.shareIcon}
97-
/>
98-
<img
99-
src="/image/more-icon.svg"
100-
alt="More"
101-
className={styles.moreIcon}
102-
/>
103-
</div>
104-
</Link>
105-
</div>
106-
<div className={styles.tags}>
107-
{pin.tags?.map((tag, tagIndex) => (
108-
<div key={tagIndex} className={styles.tag}>
109-
{tag.name}
110-
</div>
111-
))}
73+
<h3>{pin.tags?.map(tag => tag.name).join(", ")}</h3>
74+
75+
<div className={styles.galleryContainer}>
76+
<div className={styles.gallery}>
77+
{relatedPins.length > 0 ? (
78+
relatedPins.map(pin => (
79+
<div key={pin.id} className={styles.imageContainer}>
80+
<div className={styles.imageWrapper}>
81+
<img
82+
src={pin.imageUrl}
83+
alt={pin.altText || pin.title}
84+
className={styles.image}
85+
/>
86+
<Link to={`/pin/${pin.id}`} className={styles.overlay}>
87+
<span className={styles.overlayText}>Open</span>
88+
<div className={styles.overlayButtons}>
89+
<img
90+
src="/images/share-icon.svg"
91+
alt="Share"
92+
className={styles.shareIcon}
93+
/>
94+
<img
95+
src="/image/more-icon.svg"
96+
alt="More"
97+
className={styles.moreIcon}
98+
/>
99+
</div>
100+
</Link>
101+
</div>
102+
<div className={styles.tags}>
103+
{pin.tags?.map((tag, tagIndex) => (
104+
<div key={tagIndex} className={styles.tag}>
105+
{tag.name}
106+
</div>
107+
))}
108+
</div>
112109
</div>
113-
</div>
114-
))
115-
) : (
116-
<p>No related pins found</p>
117-
)}
110+
))
111+
) : (
112+
<p>No related pins found</p>
113+
)}
114+
</div>
118115
</div>
119116
</div>
120-
</div>
117+
</>
121118
);
122119
};
123120

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import React, { useState, useRef, useEffect } from "react";
2+
import { IoMdArrowDropdown } from "react-icons/io";
3+
import PinDetailComponent from "../../components/PinDetailComponent";
4+
import CommentSection from "./CommentSection";
5+
import styles from "./ShopItem.module.css";
6+
7+
const suggestions = [
8+
"Art journal",
9+
"Collage art",
10+
"Art inspo",
11+
"Creative",
12+
"Create board"
13+
];
14+
15+
const ShopItem = ({ imageSrc }) => {
16+
// let imgId = 0;
17+
const [menuOpen, setMenuOpen] = useState(false);
18+
const [search, setSearch] = useState("");
19+
const popupRef = useRef(null);
20+
const [pins, setPins] = useState([]);
21+
const [id, setId] = useState([]);
22+
const [loading, setLoading] = useState(true);
23+
const [error, setError] = useState(null);
24+
25+
useEffect(() => {
26+
const fetchPins = async () => {
27+
try {
28+
setLoading(true);
29+
setError(null);
30+
31+
const response = await fetch("http://localhost:4000/api/pins");
32+
33+
if (!response.ok) {
34+
throw new Error(`HTTP error! status: ${response.status}`);
35+
}
36+
37+
const data = await response.json();
38+
const pins = data.pins;
39+
const foundPin = pins.find(pin => pin.imageUrl === imageSrc);
40+
41+
if (foundPin) {
42+
const imgId = foundPin.id;
43+
setId(imgId);
44+
setPins(foundPin);
45+
} else {
46+
console.error("No pin found with that link.");
47+
}
48+
} catch (e) {
49+
console.error("Failed to fetch pins:", e);
50+
setError("Failed to load pins. Please try again later.");
51+
} finally {
52+
setLoading(false);
53+
}
54+
};
55+
fetchPins();
56+
}, []);
57+
58+
// Close dropdown on outside click
59+
useEffect(() => {
60+
function handleClickOutside(event) {
61+
if (popupRef.current && !popupRef.current.contains(event.target)) {
62+
setMenuOpen(false);
63+
}
64+
}
65+
document.addEventListener("mousedown", handleClickOutside);
66+
return () => {
67+
document.removeEventListener("mousedown", handleClickOutside);
68+
};
69+
}, [popupRef]);
70+
71+
const filteredSuggestions = suggestions.filter(item =>
72+
item.toLowerCase().includes(search.toLowerCase())
73+
);
74+
75+
// Tags for the Pinterest-style tag list
76+
const hashtags = [
77+
"#inktober",
78+
"#inktober24",
79+
"#inktober2024",
80+
"#day16",
81+
"#inktoberday16",
82+
"#grungy"
83+
];
84+
85+
return (
86+
<div className={styles["shop-item"]}>
87+
{/* Left side - Image */}
88+
<div className={styles["shop-item-image"]}>
89+
<img src={imageSrc || "https://picsum.photos/300/300"} alt="Product" />
90+
</div>
91+
92+
{/* Right side - Content details */}
93+
<div className={styles["shop-item-details"]}>
94+
{/* Profile and Save buttons - updated to match design */}
95+
<div className={styles["profile-wrapper"]} ref={popupRef}>
96+
<button
97+
className={styles["profile-button"]}
98+
onClick={() => setMenuOpen(!menuOpen)}
99+
>
100+
Profile <IoMdArrowDropdown />
101+
</button>
102+
{menuOpen && (
103+
<div className={styles["profile-popup"]}>
104+
<input
105+
type="text"
106+
className={styles["search-input"]}
107+
placeholder="Search"
108+
value={search}
109+
onChange={e => setSearch(e.target.value)}
110+
/>
111+
<ul className={styles.suggestions}>
112+
{filteredSuggestions.map((item, index) => (
113+
<li key={index} className={styles["suggestion-item"]}>
114+
<button>+ {item}</button>
115+
</li>
116+
))}
117+
</ul>
118+
</div>
119+
)}
120+
<button className={styles["Save-button"]}>Save</button>
121+
</div>
122+
{/* Product info */}
123+
<p className={styles.brand}>{pins.title}</p>
124+
<p className={styles.title}>{pins.description}</p>
125+
<div className={styles["shop-item-description"]}>
126+
{/* Pin details */}
127+
<PinDetailComponent />
128+
129+
{/* Tags */}
130+
<div className={styles["tag-list"]}>
131+
{hashtags.map((tag, index) => (
132+
<span
133+
key={index}
134+
className={styles.tag}
135+
onClick={() => console.info(`Clicked ${tag}`)}
136+
>
137+
{tag}
138+
</span>
139+
))}
140+
</div>
141+
142+
{/* This flexible spacer pushes the comment section to bottom */}
143+
<div className={styles["content-spacer"]}></div>
144+
145+
{/* Comment section at the very bottom where the photo ends */}
146+
<CommentSection imgId={id} />
147+
</div>
148+
</div>
149+
</div>
150+
);
151+
};
152+
153+
export default ShopItem;

0 commit comments

Comments
 (0)