Changeset 55ed171 for frontend


Ignore:
Timestamp:
10/15/22 15:28:57 (2 years ago)
Author:
Nace Gjorgjievski <nace.gorgievski123@…>
Branches:
master
Children:
113029b
Parents:
ee05663
Message:

Full Admin Functionality Added

Location:
frontend
Files:
39 added
13 edited

Legend:

Unmodified
Added
Removed
  • frontend/package-lock.json

    ree05663 r55ed171  
    2222        "bootstrap": "^5.2.0",
    2323        "font-awesome": "^4.7.0",
     24        "jquery": "^3.6.1",
    2425        "react": "^18.2.0",
    2526        "react-bootstrap": "^2.5.0",
    2627        "react-dom": "^18.2.0",
    2728        "react-helmet-async": "^1.3.0",
     29        "react-router-bootstrap": "^0.26.2",
    2830        "react-router-dom": "^6.3.0",
    2931        "react-scripts": "5.0.1",
    3032        "react-toastify": "^9.0.8",
     33        "slugify": "^1.6.5",
    3134        "web-vitals": "^2.1.4"
    3235      }
     
    1172811731      }
    1172911732    },
     11733    "node_modules/jquery": {
     11734      "version": "3.6.1",
     11735      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
     11736      "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
     11737    },
    1173011738    "node_modules/js-tokens": {
    1173111739      "version": "4.0.0",
     
    1457514583      }
    1457614584    },
     14585    "node_modules/react-router-bootstrap": {
     14586      "version": "0.26.2",
     14587      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.2.tgz",
     14588      "integrity": "sha512-YlpI9Xi+Uqp6zFAUO8D/wu6P8mr1ujqq+0V5MhJG1kx9dr/95fAMoGk4J+/CsysOkwtR3tYSac4DDWmHwXvC8w==",
     14589      "dependencies": {
     14590        "prop-types": "^15.7.2"
     14591      },
     14592      "peerDependencies": {
     14593        "react": ">=16.13.1",
     14594        "react-router-dom": ">=6.0.0"
     14595      }
     14596    },
    1457714597    "node_modules/react-router-dom": {
    1457814598      "version": "6.3.0",
     
    1543415454      "engines": {
    1543515455        "node": ">=8"
     15456      }
     15457    },
     15458    "node_modules/slugify": {
     15459      "version": "1.6.5",
     15460      "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.5.tgz",
     15461      "integrity": "sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ==",
     15462      "engines": {
     15463        "node": ">=8.0.0"
    1543615464      }
    1543715465    },
     
    2573725765      }
    2573825766    },
     25767    "jquery": {
     25768      "version": "3.6.1",
     25769      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.1.tgz",
     25770      "integrity": "sha512-opJeO4nCucVnsjiXOE+/PcCgYw9Gwpvs/a6B1LL/lQhwWwpbVEVYDZ1FokFr8PRc7ghYlrFPuyHuiiDNTQxmcw=="
     25771    },
    2573925772    "js-tokens": {
    2574025773      "version": "4.0.0",
     
    2762027653      "requires": {
    2762127654        "history": "^5.2.0"
     27655      }
     27656    },
     27657    "react-router-bootstrap": {
     27658      "version": "0.26.2",
     27659      "resolved": "https://registry.npmjs.org/react-router-bootstrap/-/react-router-bootstrap-0.26.2.tgz",
     27660      "integrity": "sha512-YlpI9Xi+Uqp6zFAUO8D/wu6P8mr1ujqq+0V5MhJG1kx9dr/95fAMoGk4J+/CsysOkwtR3tYSac4DDWmHwXvC8w==",
     27661      "requires": {
     27662        "prop-types": "^15.7.2"
    2762227663      }
    2762327664    },
     
    2825828299      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
    2825928300    },
     28301    "slugify": {
     28302      "version": "1.6.5",
     28303      "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.5.tgz",
     28304      "integrity": "sha512-8mo9bslnBO3tr5PEVFzMPIWwWnipGS0xVbYf65zxDqfNwmzYn1LpiKNrR6DlClusuvo+hDHd1zKpmfAe83NQSQ=="
     28305    },
    2826028306    "sockjs": {
    2826128307      "version": "0.3.24",
  • frontend/package.json

    ree05663 r55ed171  
    1818    "bootstrap": "^5.2.0",
    1919    "font-awesome": "^4.7.0",
     20    "jquery": "^3.6.1",
    2021    "react": "^18.2.0",
    2122    "react-bootstrap": "^2.5.0",
    2223    "react-dom": "^18.2.0",
    2324    "react-helmet-async": "^1.3.0",
     25    "react-router-bootstrap": "^0.26.2",
    2426    "react-router-dom": "^6.3.0",
    2527    "react-scripts": "5.0.1",
    2628    "react-toastify": "^9.0.8",
     29    "slugify": "^1.6.5",
    2730    "web-vitals": "^2.1.4"
    2831  },
  • frontend/src/App.css

    ree05663 r55ed171  
     1body {
     2  overflow-x: hidden;
     3}
  • frontend/src/App.js

    ree05663 r55ed171  
    2121import OrderHistoryScreen from "./screens/OrderHistoryScreen";
    2222import ProfileScreen from "./screens/ProfileScreen";
    23 
     23import AdminDashboardScreen from "./screens/AdminDashboardScreen";
     24import ListProducts from "./components/ListProducts";
     25import AdminAddProductScreen from "./screens/AdminAddProductScreen";
     26import AdminProductsScreen from "./screens/AdminProductsScreen";
     27import AdminEditProductScreen from "./screens/AdminEditProductScreen";
     28import AdminOrdersScreen from "./screens/AdminOrdersScreen";
     29import AdminOrderScreen from "./screens/AdminOrderScreen";
    2430function App() {
    2531  const { state } = useContext(Store);
    2632  const { cart } = state;
     33  //<Route path="/search" element={<AdminProductsScreen />} />
    2734  return (
    2835    <BrowserRouter>
     
    4451        <Route path="/order/:id" element={<OrderScreen />} />
    4552        <Route path="/products" element={<CategoryScreen />} />
     53        <Route path="/admin/dashboard" element={<AdminDashboardScreen />} />
     54        <Route path="/admin/addProduct" element={<AdminAddProductScreen />} />
     55        <Route path="/admin/products" element={<AdminProductsScreen />} />
     56        <Route path="/admin/orders" element={<AdminOrdersScreen />} />
     57        <Route path="/admin/order/:id" element={<AdminOrderScreen />} />
     58        <Route
     59          path="/admin/product/:slug"
     60          element={<AdminEditProductScreen />}
     61        />
    4662      </Routes>
    4763
  • frontend/src/components/Header.js

    ree05663 r55ed171  
    518518      <div className="header__right">
    519519        <div className="header__buttons">
    520           {userInfo ? (
     520          {userInfo && userInfo.isAdmin && (
    521521            <NavDropdown
    522522              title={
     
    541541              <NavDropdown.Item
    542542                onClick={() => {
    543                   navigate("/orderhistory");
     543                  navigate("/admin/dashboard");
    544544                }}
    545545              >
    546                 Нарачки
     546                Dashboard
    547547              </NavDropdown.Item>
    548548
     
    556556              </NavDropdown.Item>
    557557            </NavDropdown>
    558           ) : (
     558          )}
     559          {userInfo && !userInfo.isAdmin && (
     560            <NavDropdown
     561              title={
     562                <span>
     563                  <AccountCircleIcon
     564                    className="header__login"
     565                    fontSize="large"
     566                  />
     567                  <p>{userInfo.name}</p>
     568                </span>
     569              }
     570              id="basic-nav-dropdown"
     571            >
     572              <NavDropdown.Item
     573                onClick={() => {
     574                  navigate("/profile");
     575                }}
     576              >
     577                Профил
     578              </NavDropdown.Item>
     579
     580              <NavDropdown.Item
     581                onClick={() => {
     582                  navigate("/orderhistory");
     583                }}
     584              >
     585                Нарачки
     586              </NavDropdown.Item>
     587
     588              <NavDropdown.Divider />
     589              <NavDropdown.Item
     590                className="drowdown-item"
     591                to="#signout"
     592                onClick={signoutHandler}
     593              >
     594                Одјави се
     595              </NavDropdown.Item>
     596            </NavDropdown>
     597          )}
     598          {!userInfo && (
    559599            <Link
    560600              to={"/signin"}
  • frontend/src/components/Product.js

    ree05663 r55ed171  
    1515  return (
    1616    <div className="product__container">
    17       <Link to={`/product/${product.slug}`}>
    18         <div className="product__img">
    19           <img src={product.image} alt="product"></img>
     17      <Link to={`/product/${product.slug}`} style={{ height: "165.91px" }}>
     18        <div className="product__img" style={{ height: "100%" }}>
     19          <img
     20            src={product.image}
     21            alt="product"
     22            style={{ height: "100%" }}
     23          ></img>
    2024        </div>
    2125      </Link>
  • frontend/src/screens/CardPaymentScreen.js

    ree05663 r55ed171  
    4141  cart.totalPrice = cart.itemsPrice + cart.shippingPrice;
    4242
     43  const [cardNumber, setCardNumber] = useState("");
     44  const handleChange = (event) => {
     45    const result = event.target.value.replace(/[^0-9]/gi, "");
     46    setCardNumber(result);
     47  };
     48  const [ccvNumber, setCcvNumber] = useState("");
     49  const handleChangeCCV = (event) => {
     50    const result = event.target.value.replace(/[^0-9]/gi, "");
     51    console.log(event.currentTarget.validity.valid);
     52
     53    setCcvNumber(result);
     54  };
    4355  const paymentHandler = async (event) => {
    4456    event.preventDefault();
    4557    const form = event.currentTarget;
    4658    if (form.checkValidity() === false) {
     59      event.preventDefault();
     60      event.stopPropagation();
     61    }
     62    if (cardNumber.length !== 16) {
    4763      event.preventDefault();
    4864      event.stopPropagation();
     
    6379            isPaid: true,
    6480            paidAt: Date.now(),
     81            isConfirmed: true,
     82            contactNumber: userInfo.contact,
    6583          },
    6684          {
     
    95113          <Form.Group id="nameInput">
    96114            <Form.Label>Име и Презиме</Form.Label>
    97             <Form.Control
    98               type="text"
    99               //value={holderName}
    100               // onChange={(e) => setHolderName(e.target.value)}
    101               required
    102             ></Form.Control>
     115            <Form.Control type="text" required></Form.Control>
    103116          </Form.Group>
    104117          <Form.Group>
     
    106119            <Form.Control
    107120              type="text"
    108               //value={cardNumber}
    109               //onChange={(e) => setCardNumber(e.target.value)}
     121              minLength="16"
     122              maxLength="16"
     123              value={cardNumber}
     124              onChange={handleChange}
    110125              required
    111126            ></Form.Control>
     
    115130            <Form.Control
    116131              type="text"
    117               //value={cvv}
    118               //onChange={(e) => setCvv(e.target.value)}
     132              minLength={3}
     133              maxLength={3}
     134              value={ccvNumber}
     135              onChange={handleChangeCCV}
    119136              required
    120137            ></Form.Control>
  • frontend/src/screens/OrderHistoryScreen.js

    ree05663 r55ed171  
    1010import CheckIcon from "@mui/icons-material/Check";
    1111import ClearIcon from "@mui/icons-material/Clear";
     12import PhonePausedIcon from "@mui/icons-material/PhonePaused";
     13import LocalShippingIcon from "@mui/icons-material/LocalShipping";
    1214const reducer = (state, action) => {
    1315  switch (action.type) {
     
    4951
    5052  return (
    51     <div className="pageContainer shipPC">
     53    <div className="pageContainer shipPC" style={{ justifyContent: "normal" }}>
    5254      <Helmet>
    5355        <title>Историја на нарачки</title>
     
    8284                  {order.isDelivered ? (
    8385                    <CheckIcon></CheckIcon>
     86                  ) : order.isShipped ? (
     87                    <LocalShippingIcon></LocalShippingIcon>
    8488                  ) : (
    85                     <ClearIcon></ClearIcon>
     89                    <PhonePausedIcon></PhonePausedIcon>
    8690                  )}
    8791                </td>
  • frontend/src/screens/OrderScreen.js

    ree05663 r55ed171  
    8484                  Доставено на {order.deliveredAt}
    8585                </MessageBox>
     86              ) : order.isShipped ? (
     87                <MessageBox variant="primary">
     88                  Вашата нарачка е испратена.
     89                </MessageBox>
     90              ) : order.isConfirmed ? (
     91                <MessageBox variant="primary">
     92                  Вашата нарачка се процесира.
     93                </MessageBox>
    8694              ) : (
    87                 <MessageBox variant="danger">Не е доставено</MessageBox>
     95                <MessageBox variant="danger">
     96                  Потребно е да ја потврдите нарачката. Ќе бидете контактирани
     97                  преку телефонскиот број оставен за контакт.
     98                </MessageBox>
    8899              )}
    89100            </Card.Body>
  • frontend/src/screens/PlaceOrderScreen.js

    ree05663 r55ed171  
    6060          shippingPrice: cart.shippingPrice,
    6161          totalPrice: cart.totalPrice,
     62          isConfirmed: false,
     63          contactNumber: userInfo.contact,
    6264        },
    6365        {
  • frontend/src/screens/ProductScreen.js

    ree05663 r55ed171  
    7272                <img src={product.sideImage} alt={product.name}></img>
    7373              </div>
     74              <div className="sideImg">
     75                <img src={product.sideImage2} alt={product.name}></img>
     76              </div>
    7477            </div>
    7578          </div>
  • frontend/src/screens/ProductScreenBootstrap.js

    ree05663 r55ed171  
    165165                  onClick={changePhoto}
    166166                ></img>
     167
     168                <img
     169                  id="sec"
     170                  src={product.sideImage2}
     171                  alt={product.name}
     172                  onClick={changePhoto}
     173                ></img>
    167174              </Row>
    168175
  • frontend/src/screens/SigninScreen.js

    ree05663 r55ed171  
    3232      ctxDispatch({ type: "USER_SIGNIN", payload: data });
    3333      localStorage.setItem("userInfo", JSON.stringify(data));
    34       navigate(redirect || "/");
     34      if (data.isAdmin) navigate("/admin/dashboard");
     35      else navigate(redirect || "/");
    3536    } catch (err) {
    3637      toast.error(getError(err));
Note: See TracChangeset for help on using the changeset viewer.