Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
oceanofglitta committed Feb 7, 2023
2 parents 7b7cb32 + 292f12f commit 93ebf37
Show file tree
Hide file tree
Showing 10 changed files with 235 additions and 84 deletions.
5 changes: 5 additions & 0 deletions frontend/src/bootstrap-custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -6256,6 +6256,7 @@ textarea.form-control-lg {

.d-none {
display: none !important;
height: 100%;
}

.shadow {
Expand Down Expand Up @@ -10793,6 +10794,10 @@ textarea.form-control-lg {
top: 10%;
}

.link {
text-decoration: none;
}

.swiper-button-next,
.swiper-button-prev {
height:10px;
Expand Down
51 changes: 22 additions & 29 deletions frontend/src/pages/DetailPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,28 @@ import ItemSwiper from '../products/ItemSwiper';
import axios from 'axios';
import StarRate from '../products/StarRate';
import { useParams } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import base64 from 'base-64';
import ReactDOM from 'react-dom';
import loading from '../landing/loading.gif';
import Heart from '../products/Heart';

// 상세 제품 페이지
function Detail() {
const [ product, setProduct ] = useState([]);
const [ similar, setSimilar ] = useState([]);
const [ wishProducts, setWishProducts ] = useState([]);
const [clicked, setClicked] = useState(false);
const [ clicked, setClicked ] = useState(false);
const [activated, setActivated] = useState(5);
const theitemid = useParams()['itemid'];

const handleClick = () => {
const heart = document.getElementById("like"+item_id).getElementsByTagName("path")[0];
if(clicked) {
axios.get("http://34.64.87.78:8000/unwishing/"+ localStorage.getItem("token") + "/" + theitemid);
heart.setAttribute("d", "M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z");
setClicked(false);
} else {
axios.get("http://34.64.87.78:8000/wishing/"+ localStorage.getItem("token") + "/" + theitemid);
heart.setAttribute("d", "M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z");
setClicked(true);
}
};

const item_id = useParams()['itemid'];
const [ avg, setAvg ] = useState(0);
const item_id = Number(useParams()['itemid']);

useEffect(() => {
const controller = new AbortController();
ReactDOM.render(<><br/><img src={loading}></img></>, document.getElementById('cloudCon'));
ReactDOM.render(<><br/><img src={loading} alt='loading'></img></>, document.getElementById('cloudCon'));
axios.get("http://34.64.87.78:8000/wishes/" + localStorage.getItem("token"))
.then(response => {
setWishProducts(response.data);
setClicked(wishProducts.includes(Number(item_id)));
.then(response => response.data)
.then(data => {
setWishProducts(data);
setClicked(data.includes(item_id));
})
.catch( error => console.log(error) );

Expand All @@ -50,27 +36,31 @@ function Detail() {
setProduct(data);
})
.catch( error => console.log(error) );

axios.post(`http://115.85.181.95:30002/recommend/similar/item?item_id=${item_id}&top_k=10`)
.then(response => response.data)
.then(data => {
setSimilar(data);
})
.catch( error => console.log(error) );

axios({
method:'GET',
url:`http://115.85.181.95:30002/wordcloud/?item_id=${item_id}&split=${5}`,
// responseType:'blob'
})
.then(response => response.data)
.then(data => {
const Example = ({ data }) => <img src={`data:image/jpeg;base64,${data}`} />
const Example = ({ data }) => <img src={`data:image/jpeg;base64,${data}`} alt='wordcloud'/>
ReactDOM.render(<Example data={data} />, document.getElementById('cloudCon'))
})
.catch( error => console.log(error) );


return () => {
controller.abort();
}
}, []);
}, [item_id]);

const onClickButton = (value) => {
setActivated(value)
Expand All @@ -81,10 +71,14 @@ function Detail() {
})
.then(response => response.data)
.then(data => {
const Example = ({ data }) => <img src={`data:image/jpeg;base64,${data}`} />
const Example = ({ data }) => <img src={`data:image/jpeg;base64,${data}`} alt='wordcloud'/>
ReactDOM.render(<Example data={data} />, document.getElementById('cloudCon'))
})
.catch( error => console.log(error) );
axios.post('http://localhost:8000/review/'+item_id, wishProducts)
.then(response => response.data)
.then(data => setAvg(data))
.catch(error => console.log(error))
}

return (
Expand All @@ -106,8 +100,6 @@ function Detail() {
<br/>
<small className="category">{ product.category1 }</small>



<PriceBox>
<span>
{[product.selling_price].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
Expand All @@ -126,9 +118,10 @@ function Detail() {
<span>배송비 포함 <strong>{(product.selling_price + product.delivery_fee).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')}</strong></span>
</span>
</TotalPrice>
<p>{`유저와 비슷한 유저가 평가한 점수입니다.\n ${parseInt(avg*100)}%`}</p>
<ButtonBox>
<CartBtn>
<FontAwesomeIcon icon={clicked?["fas", "heart"]:["far", "heart"]} id={ `like${item_id}`} onClick={ handleClick } className={"like"}/>
<Heart liked={ clicked } id={ item_id }/>
</CartBtn>
<BuyBtn onClick={() => {window.open('https://ohou.se/productions/' + item_id)}}>오늘의집에서 보기</BuyBtn>
</ButtonBox>
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/pages/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ function Login(){
email: email,
password: password,
});
console.log(response.data)
localStorage.setItem("token", response.data);
console.log(localStorage.getItem("token"))

history.push('/products');
window.location.reload();
} catch (e) {
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/pages/Mypage.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ function Mypage() {
return (
<div>
{/* jumbotron */}
<div class="bg-light p-5 rounded-lg">
<div class="bg-light p-5 rounded-lg">
<br/>
<h1 class="display-4">마이페이지</h1>
{/* <p class="lead">반가워요</p> */}
<hr class="my-4" />
Expand Down Expand Up @@ -93,7 +94,7 @@ function Product(props) {

return (
<div className={"card shadow-sm card" + field}>
<a href={ "#/detail/" + id } className="link" target="_blank">
<a href={ "#/detail/" + id } className="link" target="blank">
<img
className="card-img-top bg-dark cover"
height="200"
Expand Down
53 changes: 53 additions & 0 deletions frontend/src/products/FilterBudgetLeft.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useState } from "react";

function FilterBudgetLeft({ getFilter }) {
const [ budget, setBudget ] = useState(100000);
const [ category, setCategory ] = useState([]);
const categories = ['가구', '주방용품', '수납·정리', '생활용품', '패브릭', '공구·DIY', '데코·식물', '조명'];

return (
<>
<ul className="list-group list-group-flush rounded">
<li className="list-group-item hideMenu">
<h5 className="mt-1 mb-2">Your Budget</h5>
<div className="d-grid d-block mb-3">
<div className="form-floating mb-2">
<input
type="number"
className="form-control budget"
placeholder="Min"
defaultValue={ budget }
onChange= {(event)=> setBudget(event.target.valueAsNumber)}
/>
<label htmlFor="floatingInput">Budget</label>
</div>
<h5 className="mt-1 mb-2">Category</h5>
<div className="filterCategory">
{ categories.map((cat,index) => {
return (
<>
<button value={ cat } className='deactivate category_item' key={`category${index}`}onClick={ (event) => {
const ca = event.target.value;
const click = event.target.className;
if(click === 'activate category_item') {
setCategory(category.filter(c => c !== ca));
event.target.className = 'deactivate category_item';
} else {
setCategory([...category, ca]);
event.target.className = 'activate category_item';
}
} }>{ cat }</button>
</>
)
})}
</div>
<br/>
</div>
</li>
<button className="btn btn-dark apply" onClick={ () => getFilter(budget, category) }>Apply</button>
</ul>
</>
);
}

export default FilterBudgetLeft;
5 changes: 4 additions & 1 deletion frontend/src/products/FilterMenuLeft.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ function FilterMenuLeft({ getFilter }) {
const categories = ['가구', '주방용품', '수납·정리', '생활용품', '패브릭', '공구·DIY', '데코·식물', '조명'];

return (
<>
<ul className="list-group list-group-flush rounded">
<li className="list-group-item">
<li className="list-group-item hideMenu">
<h5 className="mt-1 mb-2">Price Range</h5>
<div className="d-grid d-block mb-3">
<div className="form-floating mb-2">
Expand Down Expand Up @@ -66,7 +67,9 @@ function FilterMenuLeft({ getFilter }) {
<button className="btn btn-secondary apply" onClick={ () => getFilter(minprice, maxprice, category) }>Apply</button>
</div>
</li>
<button className="btn btn-dark apply" onClick={ () => getFilter(minprice, maxprice, category) }>Apply</button>
</ul>
</>
);
}

Expand Down
25 changes: 25 additions & 0 deletions frontend/src/products/Heart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import axios from "axios";

function Heart({ liked, id }) {
const handleClick = () => {
const heart = document.getElementById("like"+id).getElementsByTagName("path")[0];
if(liked) {
axios.get("http://34.64.87.78:8000/unwishing/"+ localStorage.getItem("token") + "/" + id);
heart.setAttribute("d", "M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z");
liked = false;
} else {
axios.get("http://34.64.87.78:8000/wishing/"+ localStorage.getItem("token") + "/" + id);
heart.setAttribute("d", "M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z");
liked = true;
}
};

if(liked) {
return <FontAwesomeIcon icon={["fas", "heart"]} id={ `like${id}` } className={"like"} onClick={ handleClick }/>
} else {
return <FontAwesomeIcon icon={["far", "heart"]} id={ `like${id}` } className={"like"} onClick={ handleClick }/>
}
}

export default Heart;
14 changes: 12 additions & 2 deletions frontend/src/products/ItemSwiper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@ import "swiper/swiper.min.css";
import "swiper/components/navigation/navigation.min.css";
import SwiperCore, { Navigation } from "swiper";
import Product from "./Product";
import { useState, useEffect } from "react";

function ItemSwiper(props) {
const [ clicked, setClicked ] = useState([])
const wishProducts = props.wishProducts;
const products = props.products;
const field = props.field;

useEffect(() => {
const temp = []
Array.from(products).map((product) => {
temp.push(wishProducts.includes(product.item_ids))
})
setClicked(temp)
}, [wishProducts])

return (
<>
<Swiper
Expand All @@ -23,13 +33,13 @@ function ItemSwiper(props) {
slidesPerView: 5,
},
}}
id={field}
id={"swiper"+field}
>
{
products.map((product, index) => {
return (
<SwiperSlide key={field + index}>
<Product product={ product } field={field + index} wish={ wishProducts.includes(product.item_id) }/>
<Product product={ product } field={field + index} wish={ clicked[index] }/>
</SwiperSlide>
)
})
Expand Down
27 changes: 5 additions & 22 deletions frontend/src/products/Product.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useState, useEffect } from "react";
import axios from "axios";
import StarRate from "./StarRate";
import Heart from "./Heart";

function Product(props) {
const [ clicked, setClicked ] = useState(false);

const product = props.product;
const id = product.item_ids;
const name = product.titles;
Expand All @@ -14,25 +10,10 @@ function Product(props) {
const Image = product.img_urls;
const brand = product.brands;
const field = props.field;

useEffect(() => {setClicked(props.wish)});

const handleClick = () => {
const heart = document.getElementById("like"+id).getElementsByTagName("path")[0];
if(clicked) {
axios.get("http://34.64.87.78:8000/unwishing/"+ localStorage.getItem("token") + "/" + id);
heart.setAttribute("d", "M458.4 64.3C400.6 15.7 311.3 23 256 79.3 200.7 23 111.4 15.6 53.6 64.3-21.6 127.6-10.6 230.8 43 285.5l175.4 178.7c10 10.2 23.4 15.9 37.6 15.9 14.3 0 27.6-5.6 37.6-15.8L469 285.6c53.5-54.7 64.7-157.9-10.6-221.3zm-23.6 187.5L259.4 430.5c-2.4 2.4-4.4 2.4-6.8 0L77.2 251.8c-36.5-37.2-43.9-107.6 7.3-150.7 38.9-32.7 98.9-27.8 136.5 10.5l35 35.7 35-35.7c37.8-38.5 97.8-43.2 136.5-10.6 51.1 43.1 43.5 113.9 7.3 150.8z");
setClicked(false);
} else {
axios.get("http://34.64.87.78:8000/wishing/"+ localStorage.getItem("token") + "/" + id);
heart.setAttribute("d", "M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z");
setClicked(true);
}
};

return (
<div className={"card shadow-sm card" + field}>
<a href={ "#/detail/" + id } className="link" target="_blank">
<a href={ "#/detail/" + id } className="link" target="blank">
<img
className="card-img-top bg-dark cover"
height="200"
Expand All @@ -42,14 +23,16 @@ function Product(props) {
/>
</a>
<div className="card-body">
<a href={ "#/detail/" + id } className="link" target="blank">
<h5 className="card-title text-center text-dark text-truncate title">
{ name }
</h5>
</a>
<p className="card-text text-center text-muted mb-0 brand">{ brand }</p>
<p className="card-text text-center text-muted mb-0 price">{ '₩' + [price].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',') }</p>
<StarRate className="card-text text-center text-muted mb-0 star" star={ star } id={ id }/>
<div className="d-grid d-block text-center">
<FontAwesomeIcon icon={clicked ? ["fas", "heart"] : ["far", "heart"]} id={ `like${id}`} onClick={ handleClick } className={"like"}/>
<Heart liked={ props.wish } id={ id }/>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 93ebf37

Please sign in to comment.