diff --git a/package.json b/package.json deleted file mode 100644 index a5f7a1d..0000000 --- a/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "greenstore", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@vitejs/plugin-react": "^3.1.0", - "vite": "^4.2.0" - } -} diff --git a/src/App.jsx b/src/App.jsx deleted file mode 100644 index 2ba469d..0000000 --- a/src/App.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' - -function App() { - const [count, setCount] = useState(0) - - return ( -
-
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.jsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

-
- ) -} - -export default App diff --git a/src/components/Navbar.css b/src/components/Navbar.css new file mode 100644 index 0000000..961dd3c --- /dev/null +++ b/src/components/Navbar.css @@ -0,0 +1,66 @@ +.navbar { + background-color: #f0f0f0; + padding: 10px; +} + +.navbar__left { + display: flex; + align-items: center; +} + +.navbar__logo { + font-size: 1.5rem; + color: #333; + text-decoration: none; +} + +.navbar__right { + list-style: none; + display: flex; + align-items: center; + margin-left: auto; +} + +.navbar__item { + position: relative; + margin-right: 10px; +} + +.navbar__link { + color: #333; + text-decoration: none; + padding: 10px; +} + +.dropdown-toggle { + cursor: pointer; +} + +.dropdown-menu { + display: none; + position: absolute; + top: 100%; + left: 0; + background-color: #fff; + padding: 10px; + list-style: none; + z-index: 1; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-menu li { + margin-bottom: 5px; +} + +.dropdown-menu li a { + color: #333; + text-decoration: none; + padding: 5px; +} + +.dropdown-menu li a:hover { + background-color: #f0f0f0; +} diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx new file mode 100644 index 0000000..bb99f79 --- /dev/null +++ b/src/components/Navbar.jsx @@ -0,0 +1,104 @@ +import React, { useState } from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import { FaShoppingCart } from 'react-icons/fa'; +import './Navbar.css'; + +function Navbar() { + const [isDropdownOpen, setDropdownOpen] = useState(false); + const navigate = useNavigate(); + + const toggleDropdown = () => { + setDropdownOpen(!isDropdownOpen); + }; + + const closeDropdown = () => { + setDropdownOpen(false); + }; + + const handleCartClick = () => { + navigate('/cart'); + }; + + const handleLogout = () => { + // Perform logout logic here + // Example: Clear authentication token, reset user state, etc. + localStorage.removeItem('token'); // Remove authentication token from localStorage + // Reset any user-related state or perform additional logout actions + + navigate('/'); // Navigate to the homepage or any desired route after logout + }; + + return ( + + ); +} + +export default Navbar; diff --git a/src/components/cart/CartPage.jsx b/src/components/cart/CartPage.jsx new file mode 100644 index 0000000..38f52ae --- /dev/null +++ b/src/components/cart/CartPage.jsx @@ -0,0 +1,175 @@ +import { useEffect, useState } from 'react'; +import axios from 'axios'; +import jwtDecode from 'jwt-decode'; +import { useNavigate } from 'react-router'; +import '../../styles/cart/Cart.css'; + + + +const Cart = () => { + const [cart, setCart] = useState(null); + const [token, setToken] = useState(''); + const [id, setId] = useState(''); + + const navigate = useNavigate(); + + useEffect(() => { + const loginWithToken = async () => { + try { + const storedToken = localStorage.getItem('token'); + if (storedToken) { + setToken(storedToken); + } + } catch (error) { + console.error(error); + } + }; + + loginWithToken(); + }, []); + + useEffect(() => { + const getCartFromToken = async () => { + try { + if (token) { + const decodedToken = jwtDecode(token); + const customerId = decodedToken.customer._id; + + setId(customerId); + // Make the API request to fetch the cart data + const response = await axios.get(`http://localhost:8070/cart/${customerId}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + setCart(response.data); + } + } catch (error) { + console.error(error); + } + }; + + getCartFromToken(); + }, [token]); + + const updateCartItemQuantity = async (itemId, newQuantity) => { + try { + // Make the API request to update the quantity of an item in the cart + const response = await axios.patch( + `http://localhost:8070/cart/${cart._id}/items/${itemId}`, + { quantity: newQuantity }, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + + // Update the cart object with the updated item + const updatedCart = { ...cart }; + const updatedItemIndex = updatedCart.items.findIndex((item) => item._id === itemId); + if (updatedItemIndex !== -1) { + updatedCart.items[updatedItemIndex].quantity = newQuantity; + setCart(updatedCart); + } + } catch (error) { + console.error(error); + } + }; + + const handleInputChange = (itemId, e) => { + const newQuantity = e.target.value; + updateCartItemQuantity(itemId, newQuantity); + }; + + const removeCartItem = async (itemId) => { + try { + // Make the API request to remove an item from the cart + await axios.delete(`http://localhost:8070/cart/${id}/items/${itemId}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + // Fetch the updated cart data after removing the item + const response = await axios.get(`http://localhost:8070/cart/${id}`, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + setCart(response.data); + } catch (error) { + console.error(error); + } + }; + + const calculateTotalPrice = () => { + if (cart && cart.items) { + return cart.items.reduce((total, item) => total + item.product.price * item.quantity, 0).toFixed(2); + } + return '0.00'; + }; + + const handleBackClick = () => { + // Perform any necessary actions when the back button is clicked + console.log('Back button clicked'); + navigate('/report'); + }; + + const handleProceedPayment = () => { + // Perform any necessary actions when the proceed to payment button is clicked + console.log('Proceed to payment button clicked'); + }; + + if (cart === null) { + return
Loading...
; + } + + return ( +
+ +

Cart

+ {cart.items && cart.items.length === 0 ? ( +

Your cart is empty.

+ ) : ( +
+ + + + + + + + + + + {cart.items.map((item) => ( + + + + + + + ))} + +
ProductQuantityPriceAction
{item.product.name} + handleInputChange(item._id, e)} + /> + ${(item.product.price * item.quantity).toFixed(2)} + +
+

Total Price: ${calculateTotalPrice()}

+ + +
+ )} +
+ ); +}; + +export default Cart; diff --git a/src/components/customer/CustomerEdit.jsx b/src/components/customer/CustomerEdit.jsx new file mode 100644 index 0000000..ad01589 --- /dev/null +++ b/src/components/customer/CustomerEdit.jsx @@ -0,0 +1,84 @@ +import { useEffect, useState } from 'react'; +import "../../styles/customer/CustomerRegistrationForm.css"; +import axios from 'axios'; +import { Link, useParams } from 'react-router-dom'; + +export default function CustomerEditForm() { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [city, setCity] = useState(''); + const [state, setState] = useState(''); + const [zipCode, setZipCode] = useState(''); + + const { id } = useParams(); + + useEffect(() => { + const fetchUserData = async () => { + try { + const response = await axios.get(`http://localhost:8070/customers/${id}`); + const userData = response.data; + setName(userData.name); + setEmail(userData.email); + setPassword(userData.password); + setCity(userData.city); + setState(userData.state); + setZipCode(userData.zipCode); + console.log(userData); + } catch (error) { + console.log(error); + } + }; + + fetchUserData(); + }, [id]); + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + const updatedCustomer = { name, email, password, city, state, zipCode }; + const response = await axios.patch(`http://localhost:8070/customers/${id}`, updatedCustomer); + console.log(response); + alert(`${updatedCustomer.name} Updated`); + } catch (error) { + console.log(error); + } + }; + + + return ( +
+ View Customers + +

Update Data

+
+ + + + + + + + +
+
+ ); +} diff --git a/src/components/customer/CustomerList.jsx b/src/components/customer/CustomerList.jsx new file mode 100644 index 0000000..4914914 --- /dev/null +++ b/src/components/customer/CustomerList.jsx @@ -0,0 +1,70 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { Link } from 'react-router-dom'; + +function CustomerList() { + const [customers, setCustomers] = useState([]); + + useEffect(() => { + axios.get('http://localhost:8070/customers/') + .then(response => { + setCustomers(response.data); + console.log(customers); + }) + .catch(error => { + console.log(error); + }) + }, []); + + const handleDelete = (id) => { + axios.delete(`http://localhost:8070/customers/${id}`) + .then(() => { + setCustomers(customers => customers.filter(customer => customer._id !== id)); + alert("Customer deleted successfully"); + }) + .catch(error => { + console.log(error); + }); + }; + + + return ( +
+

Customers

+ + + + + + + + + + + + + + {customers.map(customer => { + return ( + + + + + + + + + + ) + })} + +
NameEmailCityStateZip CodeAction
{customer.name}{customer.email}{customer.city}{customer.state}{customer.zipCode} + Show Details + + +
+
+ ) +} + +export default CustomerList; diff --git a/src/components/customer/CustomerLoginForm.jsx b/src/components/customer/CustomerLoginForm.jsx new file mode 100644 index 0000000..cf43fdf --- /dev/null +++ b/src/components/customer/CustomerLoginForm.jsx @@ -0,0 +1,76 @@ +import { useState } from 'react'; +import axios from 'axios'; +import { useNavigate } from 'react-router-dom'; + +export default function CustomerLoginForm() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [userType, setUserType] = useState('Customer'); + const [error, setError] = useState(''); + const navigate = useNavigate(); + + const handleSubmit = (event) => { + event.preventDefault(); + + // Perform client-side validation + if (!email || !password) { + setError('Please enter your email and password.'); + return; + } + + // Send login request to the server + axios + .post('http://localhost:8070/login/', { email, password, userType }) + .then((response) => { + console.log(response.data); // Handle the successful login here + if (response.data.message === 'Login successful') { + setError(''); + + localStorage.setItem('token', response.data.token); // Set the token in localStorage + navigate('/report'); + } else { + setError('Invalid email or password. Please try again.'); + } + }) + .catch((error) => { + setError('Invalid email or password. Please try again.'); // Handle the login error here + }); + }; + + return ( +
+

Customer Login

+
+ +
+ + +
+ +
+ + setEmail(event.target.value)} + /> +
+
+ + setPassword(event.target.value)} + /> +
+
+ +
+ {error &&
{error}
} +
+
+ ); +} diff --git a/src/components/customer/CustomerRegistrationForm.jsx b/src/components/customer/CustomerRegistrationForm.jsx new file mode 100644 index 0000000..44f4ae9 --- /dev/null +++ b/src/components/customer/CustomerRegistrationForm.jsx @@ -0,0 +1,67 @@ +import { useState } from 'react'; +import "../../styles/customer/CustomerRegistrationForm.css"; +import axios from 'axios'; +import { Link } from 'react-router-dom'; + +export default function CustomerRegistrationForm() { + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [city, setCity] = useState(''); + const [state, setState] = useState(''); + const [zipCode, setZipCode] = useState(''); + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + const customer = { name, email, password, city, state, zipCode }; + const response = await axios.post('http://localhost:8070/customers/create', customer); + console.log(response); + alert(`${customer.name} Added`); + setName(""); + setEmail(""); + setPassword(""); + setCity(""); + setState(""); + setZipCode(""); + + + } catch (error) { + console.log(error); + } + }; + + return ( +
+ View Customers +

Customer Register Form

+
+ + + + + + + +
+
+ ); +} diff --git a/src/components/fertilizers/FertilizerEdit.jsx b/src/components/fertilizers/FertilizerEdit.jsx new file mode 100644 index 0000000..ab7b8e5 --- /dev/null +++ b/src/components/fertilizers/FertilizerEdit.jsx @@ -0,0 +1,85 @@ +import { useEffect, useState } from 'react'; +import axios from 'axios'; +import "../../styles/fertilizer/FertilizerForm.css"; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; +import { Link, useParams } from 'react-router-dom'; + +function FertilizerEditForm() { + const [name, setName] = useState(''); + const [weight, setWeight] = useState(''); + const [price, setPrice] = useState(''); + const [type, setType] = useState(''); + const [manufacturingDate, setManufacturingDate] = useState(''); + const [createdDate, setCreatedDate] = useState(''); + + const { id } = useParams(); + + useEffect(() => { + const fetchFertilizerData = async () => { + try { + const response = await axios.get(`http://localhost:8070/fertilizers/${id}`); + const fertilizerData = response.data; + setName(fertilizerData.name); + setWeight(fertilizerData.weight); + setPrice(fertilizerData.price); + setType(fertilizerData.type); + setManufacturingDate(new Date(fertilizerData.manufacturingDate)); + setCreatedDate(new Date(fertilizerData.createdDate)); + } catch (error) { + console.log(error); + } + }; + + fetchFertilizerData(); + }, [id]); + + const handleSubmit = async (event) => { + event.preventDefault(); + try { + const updatedFertilizer = { name, weight, price,type, manufacturingDate, createdDate }; + const response = await axios.patch(`http://localhost:8070/fertilizers/${id}`, updatedFertilizer); + console.log(response); + alert(`${updatedFertilizer.name} Updated`); + } catch (error) { + console.log(error); + } + }; + + return ( +
+ View Fertilizers + +

Update Fertilizer Data

+
+
+ + setName(event.target.value)} required /> +
+
+ + setWeight(event.target.value)} required /> +
+
+ + setPrice(event.target.value)} required /> +
+
+ + setType(event.target.value)} required /> +
+
+ + setManufacturingDate(date)} dateFormat="dd/MM/yyyy" required/> +
+
+ + setCreatedDate(date)} dateFormat="dd/MM/yyyy" required/> +
+ +
+
+ ) +} + +export default FertilizerEditForm; diff --git a/src/components/fertilizers/FertilizerForm.jsx b/src/components/fertilizers/FertilizerForm.jsx new file mode 100644 index 0000000..20b6c13 --- /dev/null +++ b/src/components/fertilizers/FertilizerForm.jsx @@ -0,0 +1,74 @@ +import React, { useState } from 'react'; +import axios from 'axios'; +import "../../styles/fertilizer/FertilizerForm.css"; +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; + + +function FertilizerForm() { + const [name, setName] = useState(''); + const [weight, setWeight] = useState(''); + const [price, setPrice] = useState(''); + const [type, setType] = useState(''); + const [manufacturingDate, setManufacturingDate] = useState(''); + const [createdDate, setCreatedDate] = useState(''); + + const handleSubmit = async (event) => { + event.preventDefault(); + try { + const fertilizer = { name, weight, price, type, manufacturingDate, createdDate }; + const response = await axios.post('http://localhost:8070/fertilizers/create', fertilizer); + console.log(response); + alert(`${fertilizer.name} Added`); + setName(""); + setWeight(""); + setPrice(""); + setType(""); + setManufacturingDate(""); + setCreatedDate(""); + + + } catch (error) { + console.log(error); + } + } + + return ( +
+
+

Add Fertilizer

+
+
+ + setName(event.target.value)} required /> +
+
+ + setWeight(event.target.value)} required /> +
+
+ + setPrice(event.target.value)} required /> +
+
+ + setType(event.target.value)} required /> +
+ +
+ + setManufacturingDate(date)} dateFormat="dd/MM/yyyy" required/> + +
+
+ + setCreatedDate(date)} dateFormat="dd/MM/yyyy" required/> +
+ +
+
+
+ ) +} + +export default FertilizerForm; diff --git a/src/components/fertilizers/FertilizerGenTable.jsx b/src/components/fertilizers/FertilizerGenTable.jsx new file mode 100644 index 0000000..0f7c747 --- /dev/null +++ b/src/components/fertilizers/FertilizerGenTable.jsx @@ -0,0 +1,61 @@ +const fertilizers = { + tomato: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Fruiting: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + }, + lettuce: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Heading: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + }, + cucumber: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Flowering: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Fruiting: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + }, + bell_pepper: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Flowering: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Fruiting: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + }, + zucchini: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Flowering: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Fruiting: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + }, + carrot: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Rooting: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + }, + broccoli: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Flowering: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + }, + spinach: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Heading: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + }, + corn: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Tasseling: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Pollinating: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + }, + pumpkin: { + Seedling: { type: "Nitrogen", amount: "0.5", frequency: "Every 2 weeks" }, + Vegetative: { type: "Nitrogen", amount: "1", frequency: "Every 2 weeks" }, + Flowering: { type: "Phosphorus", amount: "1", frequency: "Every 2 weeks" }, + Fruiting: { type: "Potassium", amount: "1", frequency: "Every 2 weeks" }, + } + + // Add more plants and growth stages as needed +}; + +export default fertilizers; diff --git a/src/components/fertilizers/FertilizerGenerator.jsx b/src/components/fertilizers/FertilizerGenerator.jsx new file mode 100644 index 0000000..2396939 --- /dev/null +++ b/src/components/fertilizers/FertilizerGenerator.jsx @@ -0,0 +1,186 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import fertilizers from "./FertilizerGenTable"; +import "../../styles/fertilizer/FertilizerGen.css"; +import jwt_decode from "jwt-decode"; + +const FertilizerGeneratorForm = () => { + const [plantName, setPlantName] = useState(""); + const [growthStage, setGrowthStage] = useState(""); + const [time, setTime] = useState(""); + const [fertilizerType, setFertilizerType] = useState(""); + const [fertilizerAmount, setFertilizerAmount] = useState(""); + const [fertilizerFrequency, setFertilizerFrequency] = useState(""); + const [filteredFertilizers, setFilteredFertilizers] = useState([]); + + + const fetchFertilizers = async (type) => { + try { + const response = await axios.get(`http://localhost:8070/fertilizers`); + const filteredData = response.data.filter((fertilizer) => + fertilizer.type.toLowerCase() === type.toLowerCase() + ); + setFilteredFertilizers(filteredData); + } catch (error) { + console.error(error); + } + }; + + const addToCart = async (fertilizerId) => { + try { + const token = localStorage.getItem("token"); + + if (token) { + const decodedToken = jwt_decode(token); + const customerId = decodedToken.customer._id; + + console.log(customerId); + + const response = await axios.post( + `http://localhost:8070/cart/${customerId}/add`, + { + customerId, + fertilizerId, + quantity: 1, + } + ); + console.log("Item added to cart:", response.data); + } + } catch (error) { + console.error(error); + } + }; + + const handleSubmit = (event) => { + event.preventDefault(); + + if (fertilizers[plantName] && fertilizers[plantName][growthStage]) { + let { type, amount, frequency } = fertilizers[plantName][growthStage]; + + if (time === "Morning") { + amount *= 1.25; + } else if (time === "Afternoon") { + amount *= 0.75; + } + + setFertilizerType(type); + setFertilizerAmount(amount); + setFertilizerFrequency(frequency); + + fetchFertilizers(type); + } else { + setFertilizerType(""); + setFertilizerAmount(""); + setFertilizerFrequency(""); + } + }; + + return ( +
+
+

Generate Fertilizer

+ + + + + + + + + + + + + + + + + + + + + +
TypeAmountFrequency
{fertilizerType}{fertilizerAmount} pounds{fertilizerFrequency}
+
+

+ Find the most suitable fertilizer from the below +

+ + + + + + + + + + + + + {filteredFertilizers.length === 0 ? ( + + + + ) : ( + filteredFertilizers.map((fertilizer) => ( + + + + + + + + + )) + )} + +
NameWeightPriceTypeManufacturing Date
+ No values to display +
{fertilizer.name}{fertilizer.weight} KGLKR {fertilizer.price}{fertilizer.type}{fertilizer.manufacturingDate} + + +
+
+ ); +}; + +export default FertilizerGeneratorForm; diff --git a/src/components/fertilizers/FertilizerList.jsx b/src/components/fertilizers/FertilizerList.jsx new file mode 100644 index 0000000..0344421 --- /dev/null +++ b/src/components/fertilizers/FertilizerList.jsx @@ -0,0 +1,75 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import "../../styles/fertilizer/FertilizerList.css"; + +import { Link } from 'react-router-dom'; + +function Fertilizers() { + const [fertilizers, setFertilizers] = useState([]); + + useEffect(() => { + axios.get('http://localhost:8070/fertilizers/') + .then(response => { + setFertilizers(response.data); + }) + .catch(error => { + console.log(error); + }) + }, []); + + + + const handleDelete = (id) => { + axios.delete(`http://localhost:8070/fertilizers/${id}`) + .then(() => { + setFertilizers(fertilizers => fertilizers.filter(fertilizer => fertilizer._id !== id)); + alert("Customer deleted successfully"); + }) + .catch(error => { + console.log(error); + }); + }; + + return ( +
+
+ Go Back +
+

Fertilizers

+ + + + + + + + + + + + + + {fertilizers.map(fertilizer => { + return ( + + + + + + + + + + ) + })} + +
NameWeightPriceTypeMFDAction
{fertilizer.name}{fertilizer.weight} KGLKR {fertilizer.price}{fertilizer.type}{fertilizer.manufacturingDate} + Show Details + + +
+
+ ) +} + +export default Fertilizers; diff --git a/src/components/fertilizers/FertilizerView.jsx b/src/components/fertilizers/FertilizerView.jsx new file mode 100644 index 0000000..9759965 --- /dev/null +++ b/src/components/fertilizers/FertilizerView.jsx @@ -0,0 +1,48 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import "../../styles/fertilizer/FertilizerList.css"; + +import { Link } from 'react-router-dom'; + +function FertilizerList() { + const [fertilizers, setFertilizers] = useState([]); + + useEffect(() => { + axios.get('http://localhost:8070/fertilizers/') + .then(response => { + setFertilizers(response.data); + }) + .catch(error => { + console.log(error); + }) + }, []); + + + return ( +
+

Recommended Fertilizers

+
+ {fertilizers.map(fertilizer => ( +
+
+ + {fertilizer.name} + +
+
+

{fertilizer.name}

+

${fertilizer.price}

+
+ +
+
+
+ ))} +
+
+ ); +} + +export default FertilizerList; diff --git a/src/components/.gitkeep b/src/routes/.gitkeep similarity index 100% rename from src/components/.gitkeep rename to src/routes/.gitkeep diff --git a/src/routes/AppRoutes.jsx b/src/routes/AppRoutes.jsx new file mode 100644 index 0000000..d3e42c1 --- /dev/null +++ b/src/routes/AppRoutes.jsx @@ -0,0 +1,69 @@ +import React, { useState } from "react"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import FertilizerForm from "../components/fertilizers/FertilizerForm"; +import ViewFertilizers from "../components/fertilizers/FertilizerList"; +import FertilizerGenerator from "../components/fertilizers/FertilizerGenerator"; +import FertilizerEditForm from "../components/fertilizers/FertilizerEdit"; +import CustomerRegistrationForm from "../components/customer/CustomerRegistrationForm"; +import Navbar from "../components/Navbar"; +import CustomerLoginForm from '../components/customer/CustomerLoginForm'; +import CustomerList from "../components/customer/CustomerList"; +import CustomerEditForm from "../components/customer/CustomerEdit"; +import CartPage from "../components/cart/CartPage"; + + +function App() { + + return ( + +
+ + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + + } /> + + +
+ +
+ ); +} + +export default App; diff --git a/src/styles/cart/Cart.css b/src/styles/cart/Cart.css new file mode 100644 index 0000000..187216f --- /dev/null +++ b/src/styles/cart/Cart.css @@ -0,0 +1,75 @@ +.cart-container { + width: 400px; + margin: 0 auto; + padding: 20px; + background-color: #f5f5f5; + border: 1px solid #ddd; + border-radius: 4px; + } + + .cart-header { + font-size: 24px; + font-weight: bold; + margin-bottom: 20px; + } + + .cart-table { + width: 100%; + border-collapse: collapse; + } + + .cart-table th, + .cart-table td { + padding: 10px; + border-bottom: 1px solid #ddd; + text-align: left; + } + + .cart-table th { + background-color: #f9f9f9; + } + + .cart-table td input[type="number"] { + width: 50px; + padding: 5px; + } + + .cart-total { + margin-top: 20px; + text-align: right; + } + + .cart-buttons { + margin-top: 20px; + text-align: right; + } + + .cart-buttons button { + padding: 10px 20px; + background-color: #007bff; + color: #fff; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s; + } + + .cart-buttons button:hover { + background-color: #0056b3; + } + + .cart-empty-message { + font-style: italic; + margin-top: 20px; + } + + .cart-loading { + text-align: center; + margin-top: 50px; + } + + .cart-error { + color: red; + margin-top: 20px; + } + \ No newline at end of file diff --git a/src/routers/.gitkeep b/src/styles/customer/CustomerLogin.css similarity index 100% rename from src/routers/.gitkeep rename to src/styles/customer/CustomerLogin.css diff --git a/src/styles/customer/CustomerRegistrationForm.css b/src/styles/customer/CustomerRegistrationForm.css new file mode 100644 index 0000000..91afa59 --- /dev/null +++ b/src/styles/customer/CustomerRegistrationForm.css @@ -0,0 +1,37 @@ +form { + display: flex; + flex-direction: column; + max-width: 400px; + margin: 0 auto; + } + + label { + margin-top: 10px; + font-size: 16px; + font-weight: bold; + } + + input { + width: 100%; + padding: 10px; + margin-top: 5px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 16px; + } + + button[type="submit"] { + background-color: #8bc34a; + color: #fff; + border: none; + border-radius: 4px; + font-size: 16px; + padding: 10px; + margin-top: 10px; + cursor: pointer; + } + + button[type="submit"]:hover { + background-color: #689f38; + } + \ No newline at end of file diff --git a/src/styles/fertilizer/FertilizerForm.css b/src/styles/fertilizer/FertilizerForm.css new file mode 100644 index 0000000..66c134c --- /dev/null +++ b/src/styles/fertilizer/FertilizerForm.css @@ -0,0 +1,43 @@ +.fertilizer-form-container { + display: flex; + justify-content: center; +} + +.fertilizer-form { + border: 1px solid #ccc; + padding: 20px; + width: 400px; +} + +.form-topic { + text-align: center; +} + +.form-group { + margin-bottom: 10px; +} + +label { + display: block; + margin-bottom: 5px; +} + +input { + width: 100%; + padding: 10px; + border-radius: 5px; + border: 1px solid #ccc; + box-sizing: border-box; +} + +button { + background-color: #4CAF50; + color: white; + padding: 10px 20px; + border: none; + border-radius: 5px; + cursor: pointer; + margin-top: 10px; + margin-bottom: 50px; +} + diff --git a/src/styles/fertilizer/FertilizerGen.css b/src/styles/fertilizer/FertilizerGen.css new file mode 100644 index 0000000..ef54121 --- /dev/null +++ b/src/styles/fertilizer/FertilizerGen.css @@ -0,0 +1,67 @@ +form { + display: flex; + flex-direction: column; + align-items: center; + margin: 50px auto; + width: 80%; + background-color: #F0FFF0; /* Change background color */ + border: 1px solid #008000; /* Add border */ + padding: 20px; + } + + label { + display: flex; + flex-direction: column; + margin: 20px 0; + width: 100%; + max-width: 500px; + color: #008000; /* Change label color */ + } + + select { + margin-top: 5px; + padding: 10px; + border: none; + border-radius: 5px; + font-size: 16px; + background-color: #FFFFFF; /* Change select background color */ + color: #008000; /* Change select color */ + } + + button { + margin-top: 30px; + padding: 10px 20px; + border: none; + border-radius: 5px; + font-size: 18px; + background-color: #008000; /* Change button background color */ + color: #FFFFFF; + cursor: pointer; + } + + button:hover { + background-color: #006400; /* Change button hover color */ + } + + + .buy-button { + background-color: #4caf50; + color: white; + border: none; + padding: 10px 20px; + font-size: 16px; + border-radius: 4px; + cursor: pointer; + } + + .add-to-cart-button { + background-color: #008cba; + color: white; + border: none; + padding: 10px 20px; + font-size: 16px; + border-radius: 4px; + cursor: pointer; + margin-top: 10px; + } + \ No newline at end of file diff --git a/src/styles/fertilizer/FertilizerList.css b/src/styles/fertilizer/FertilizerList.css new file mode 100644 index 0000000..b68d1e3 --- /dev/null +++ b/src/styles/fertilizer/FertilizerList.css @@ -0,0 +1,44 @@ +table { + margin-bottom: 100px; + border-collapse: collapse; + width: 100%; + margin: 0 auto; + } + + th, + td { + padding: 0.5rem; + text-align: left; + border-bottom: 1px solid #ccc; + } + + th { + background-color: #4caf50; + color: #271919; + } + + tr:nth-child(even) { + background-color: #f2f2f2; + } + + tr:hover { + background-color: #e2e2e2; + } + + p { + text-align: center; + font-size: 1.5rem; + font-weight: bold; + } + + .page-title { + text-align: center; + font-size: 2rem; + font-weight: bold; + margin-top: 2rem; + margin-bottom: 2rem; + } + + h1 { + text-align: center; + } \ No newline at end of file