source: frontend/src/screens/ProductScreenBootstrap.js@ b612ab1

Last change on this file since b612ab1 was b612ab1, checked in by Nace Gjorgjievski <nace.gorgievski123@…>, 22 months ago

Basic functions added

  • Property mode set to 100644
File size: 7.1 KB
Line 
1import axios from "axios";
2import React, { useContext, useEffect, useReducer } from "react";
3import { Helmet } from "react-helmet-async";
4import { useNavigate, useParams } from "react-router-dom";
5import Footer from "../components/Footer";
6import "bootstrap/dist/css/bootstrap.min.css";
7import Header from "../components/Header";
8import icon1 from "../Images/icon3.svg";
9import ShoppingBasketIcon from "@mui/icons-material/ShoppingCart";
10import "../styles/ProductScreen.css";
11import Container from "react-bootstrap/Container";
12import Row from "react-bootstrap/Row";
13import Col from "react-bootstrap/Col";
14import Button from "react-bootstrap/Button";
15import Table from "react-bootstrap/Table";
16import LoadingBox from "../components/LoadingBox";
17import MessageBox from "../components/MessageBox";
18import { getError } from "../components/utils";
19import { Store } from "../Store";
20
21const reducer = (state, action) => {
22 switch (action.type) {
23 case "FETCH_REQUEST":
24 return { ...state, loading: true };
25 case "FETCH_SUCCESS":
26 return { ...state, product: action.payload, loading: false };
27 case "FETCH_FAIL":
28 return { ...state, loading: false, error: action.payload };
29 default:
30 return state;
31 }
32};
33
34function ProductScreen() {
35 const navigate = useNavigate();
36 const params = useParams();
37 const { slug } = params;
38
39 const [{ loading, error, product }, dispatch] = useReducer(reducer, {
40 product: [],
41 loading: true,
42 error: "",
43 });
44
45 useEffect(() => {
46 const fetchData = async () => {
47 dispatch({ type: "FETCH_REQUEST" });
48 try {
49 const result = await axios.get(`/api/products/slug/${slug}`);
50 dispatch({ type: "FETCH_SUCCESS", payload: result.data });
51 } catch (err) {
52 dispatch({ type: "FETCH_FAIL", payload: getError(err) });
53 }
54 };
55 fetchData();
56 }, [slug]);
57
58 const handleClick = (event) => {
59 let tmp = document.querySelector("#tmp");
60 if (tmp != null) {
61 tmp.parentNode.removeChild(tmp);
62 if (document.querySelector("#tmp") != null) {
63 let tmp = document.querySelector("#tmp");
64 tmp.parentNode.removeChild(tmp);
65 }
66 }
67 if (event.target.textContent === "Опис") {
68 let pre = document.createElement("pre");
69 pre.setAttribute("id", "tmp");
70 pre.textContent = product.description;
71 event.target.appendChild(pre);
72 } else if (event.target.textContent === "Монтажа") {
73 let table = document.createElement("table");
74 let thModel = document.createElement("th");
75 let thPrice = document.createElement("th");
76 let tdName = document.createElement("td");
77 let tdPrice = document.createElement("td");
78 let tr1 = document.createElement("tr");
79 let tr2 = document.createElement("tr");
80 thModel.innerHTML = "Модел";
81 thPrice.innerHTML = "Цена";
82 tdName.innerHTML = product.name;
83 tdPrice.innerHTML = product.priceMontaza;
84 tr1.appendChild(thModel);
85 tr1.appendChild(thPrice);
86 tr2.appendChild(tdName);
87 tr2.appendChild(tdPrice);
88 table.appendChild(tr1);
89 table.appendChild(tr2);
90 table.setAttribute("id", "tmp");
91 let p = document.createElement("p");
92 p.innerHTML = "Цената за монтажа е посочена на секој производ посебно.";
93 p.setAttribute("id", "tmp");
94
95 event.target.appendChild(table);
96 event.target.appendChild(p);
97 } else {
98 let p = document.createElement("p");
99 let a = document.createElement("a");
100 let img = document.createElement("img");
101 if (event.target.textContent === "Димензии") {
102 a.setAttribute("href", product.dimension);
103 img.src = product.dimension;
104 } else {
105 a.setAttribute("href", product.scheme);
106 img.src = product.scheme;
107 }
108 p.appendChild(img);
109 a.setAttribute("id", "tmp");
110 a.appendChild(p);
111 event.target.appendChild(a);
112 }
113 };
114
115 const changePhoto = (event) => {
116 let main = document.getElementById("main");
117 main.setAttribute("src", event.target.src);
118 };
119
120 const { state, dispatch: ctxDispatch } = useContext(Store);
121 const { cart } = state;
122 const addToCartHandler = async () => {
123 const existItem = cart.cartItems.find((x) => x._id === product._id);
124 const quantity = existItem ? existItem.quantity + 1 : 1;
125 const { data } = await axios.get(`/api/products/${product._id}`);
126 if (data.countInStock < quantity) {
127 window.alert("Sorry. Product is out of stock");
128 return;
129 }
130 ctxDispatch({
131 type: "CART_ADD_ITEM",
132 payload: { ...product, quantity },
133 });
134 navigate("/cart");
135 };
136
137 return loading ? (
138 <LoadingBox />
139 ) : error ? (
140 <MessageBox variant="danger">{error}</MessageBox>
141 ) : (
142 <div>
143 <Helmet>
144 <title>{product.name}</title>
145 </Helmet>
146 <div>
147 <Container>
148 <Row>
149 <Col>
150 <Row>
151 <img id="main" src={product.image} alt={product.name}></img>
152 </Row>
153 <Row className="imgRow">
154 <img
155 id="sec"
156 src={product.image}
157 alt={product.name}
158 onClick={changePhoto}
159 ></img>
160
161 <img
162 id="sec"
163 src={product.sideImage}
164 alt={product.name}
165 onClick={changePhoto}
166 ></img>
167 </Row>
168
169 {/*</div>*/}
170 </Col>
171 <Col sm>
172 <Row>
173 <h2 id="name">{product.name}</h2>
174 </Row>
175 <Row>
176 <h2 id="price">{product.price} ден</h2>
177 <span>
178 <img id="icon" src={icon1} alt="10-day-delivery"></img>
179 Бесплатна достава: 10 дена
180 </span>
181 </Row>
182 <Row>
183 <Button
184 onClick={addToCartHandler}
185 className="addToCartBtn"
186 variant="danger"
187 >
188 <ShoppingBasketIcon />
189 ДОДАЈ ВО КОШНИЧКА
190 </Button>
191 </Row>
192 <Row>
193 <Table id="table">
194 <tbody>
195 <tr>
196 <td>
197 <div onClick={handleClick}>Опис</div>
198 </td>
199 </tr>
200 <tr>
201 <td>
202 <div onClick={handleClick}>Димензии</div>
203 </td>
204 </tr>
205 <tr>
206 <td>
207 <div onClick={handleClick}>Монтажа</div>
208 </td>
209 </tr>
210 <tr>
211 <td>
212 <div onClick={handleClick}>Шема за монтажа</div>
213 </td>
214 </tr>
215 </tbody>
216 </Table>
217 </Row>
218 </Col>
219 </Row>
220 </Container>
221 </div>
222 </div>
223 );
224}
225
226export default ProductScreen;
Note: See TracBrowser for help on using the repository browser.