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 + 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.
+ ) : (
+
+
+
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
+
+
+
+ Name |
+ Email |
+ City |
+ State |
+ Zip Code |
+ Action |
+ |
+
+
+
+ {customers.map(customer => {
+ return (
+
+ {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 (
+
+ );
+}
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
+
+
+ )
+}
+
+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 (
+
+ )
+}
+
+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 (
+
+
+
+ Find the most suitable fertilizer from the below
+
+
+
+
+ Name |
+ Weight |
+ Price |
+ Type |
+ Manufacturing Date |
+ |
+
+
+
+ {filteredFertilizers.length === 0 ? (
+
+
+ No values to display
+ |
+
+ ) : (
+ filteredFertilizers.map((fertilizer) => (
+
+ {fertilizer.name} |
+ {fertilizer.weight} KG |
+ LKR {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
+
+
+
+ Name |
+ Weight |
+ Price |
+ Type |
+ MFD |
+ Action |
+ |
+
+
+
+ {fertilizers.map(fertilizer => {
+ return (
+
+ {fertilizer.name} |
+ {fertilizer.weight} KG |
+ LKR {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.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