commit
3181bba877
@ -0,0 +1,24 @@ |
||||
# Logs |
||||
logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
pnpm-debug.log* |
||||
lerna-debug.log* |
||||
|
||||
node_modules |
||||
dist |
||||
dist-ssr |
||||
*.local |
||||
|
||||
# Editor directories and files |
||||
.vscode/* |
||||
!.vscode/extensions.json |
||||
.idea |
||||
.DS_Store |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.sw? |
@ -0,0 +1,8 @@ |
||||
# React + Vite |
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. |
||||
|
||||
Currently, two official plugins are available: |
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh |
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh |
@ -0,0 +1,38 @@ |
||||
import js from '@eslint/js' |
||||
import globals from 'globals' |
||||
import react from 'eslint-plugin-react' |
||||
import reactHooks from 'eslint-plugin-react-hooks' |
||||
import reactRefresh from 'eslint-plugin-react-refresh' |
||||
|
||||
export default [ |
||||
{ ignores: ['dist'] }, |
||||
{ |
||||
files: ['**/*.{js,jsx}'], |
||||
languageOptions: { |
||||
ecmaVersion: 2020, |
||||
globals: globals.browser, |
||||
parserOptions: { |
||||
ecmaVersion: 'latest', |
||||
ecmaFeatures: { jsx: true }, |
||||
sourceType: 'module', |
||||
}, |
||||
}, |
||||
settings: { react: { version: '18.3' } }, |
||||
plugins: { |
||||
react, |
||||
'react-hooks': reactHooks, |
||||
'react-refresh': reactRefresh, |
||||
}, |
||||
rules: { |
||||
...js.configs.recommended.rules, |
||||
...react.configs.recommended.rules, |
||||
...react.configs['jsx-runtime'].rules, |
||||
...reactHooks.configs.recommended.rules, |
||||
'react/jsx-no-target-blank': 'off', |
||||
'react-refresh/only-export-components': [ |
||||
'warn', |
||||
{ allowConstantExport: true }, |
||||
], |
||||
}, |
||||
}, |
||||
] |
@ -0,0 +1,14 @@ |
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<link rel="shortcut icon" href="./src/components/logo.jpg" type="image/x-icon"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>DFM</title> |
||||
</head> |
||||
<body> |
||||
<div id="root"></div> |
||||
<script type="module" src="/src/main.jsx"></script> |
||||
</body> |
||||
</html> |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@ |
||||
{ |
||||
"name": "frontend", |
||||
"private": true, |
||||
"version": "0.0.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"build": "vite build", |
||||
"lint": "eslint .", |
||||
"preview": "vite preview" |
||||
}, |
||||
"dependencies": { |
||||
"@fortawesome/fontawesome-free": "^6.7.2", |
||||
"@fortawesome/free-solid-svg-icons": "^6.7.2", |
||||
"@fortawesome/react-fontawesome": "^0.2.2", |
||||
"react": "^18.3.1", |
||||
"react-dom": "^18.3.1", |
||||
"react-icons": "^5.4.0", |
||||
"react-router-dom": "^7.1.1" |
||||
}, |
||||
"devDependencies": { |
||||
"@eslint/js": "^9.17.0", |
||||
"@types/react": "^18.3.18", |
||||
"@types/react-dom": "^18.3.5", |
||||
"@vitejs/plugin-react": "^4.3.4", |
||||
"autoprefixer": "^10.4.20", |
||||
"eslint": "^9.17.0", |
||||
"eslint-plugin-react": "^7.37.2", |
||||
"eslint-plugin-react-hooks": "^5.0.0", |
||||
"eslint-plugin-react-refresh": "^0.4.16", |
||||
"globals": "^15.14.0", |
||||
"postcss": "^8.4.49", |
||||
"tailwindcss": "^3.4.17", |
||||
"vite": "^6.0.5" |
||||
} |
||||
} |
@ -0,0 +1,6 @@ |
||||
export default { |
||||
plugins: { |
||||
tailwindcss: {}, |
||||
autoprefixer: {}, |
||||
}, |
||||
} |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,37 @@ |
||||
import Navbar from "./components/NavBar"; |
||||
import ConsumerHomePage from "./components/ConsumerHomePage"; |
||||
import Cart from "./components/pages/Cart"; |
||||
import Footer from "./components/Footer"; // If the file is named `Footer.js` |
||||
import {Routes,Route} from "react-router-dom" |
||||
import AboutUs from "./components/pages/AboutUs"; |
||||
import Product from "./components/pages/Product"; |
||||
import Shop from "./components/pages/Shop"; |
||||
import Account from "./components/pages/Account"; |
||||
import Login from "./components/pages/Login"; |
||||
import Forgot from "./components/pages/Forgot"; |
||||
// import profile from "./components/pages/Account"; |
||||
function App() { |
||||
return ( |
||||
<> |
||||
<Navbar /> |
||||
<Routes> |
||||
<Route path="/" element={<ConsumerHomePage />} /> |
||||
<Route path="/about" element={<AboutUs />} /> |
||||
<Route path="/Cart" element={<Cart />} /> |
||||
<Route path="/Product" element={<Product />} /> |
||||
<Route path="/Shop" element={<Shop />} /> |
||||
{/* Add more routes as needed */} |
||||
<Route path="/profile" element={<Account />} /> |
||||
<Route path="/Login" element={<Login />} /> |
||||
<Route path="/Forget" element={<Forgot />} /> |
||||
</Routes> |
||||
<Footer /> |
||||
|
||||
</> |
||||
) |
||||
} |
||||
|
||||
export default App; |
||||
|
||||
|
||||
|
@ -0,0 +1,41 @@ |
||||
import React from "react"; |
||||
|
||||
function ConsumerHomePage() { |
||||
return ( |
||||
<main className="container mx-auto px-4 py-12" style={{ backgroundColor: '#FFF7F0', fontFamily: 'Roboto, sans-serif' }}> |
||||
<div className="flex flex-col items-center text-center"> |
||||
<h2 className="text-2xl md:text-3xl font-bold text-gray-900 mb-4"> |
||||
DIGITAL FARMER'S MARKET |
||||
</h2> |
||||
<h1 className="text-4xl md:text-6xl font-bold text-pink-500 mb-8">ORGANIC SHOP</h1><br /> |
||||
<div className="bg-white rounded-lg shadow-md p-4 flex justify-center items-center"> |
||||
<p className="text-gray-700 mt-4 text-sm md:text-base"> |
||||
Connecting farmers directly with consumers for fresh, local produce. Empowering sustainable agriculture with AI insights, real-time market access, and fair pricing—building a better future for all. |
||||
</p> |
||||
</div><br /> |
||||
<button className="bg-pink-500 hover:bg-pink-600 text-white font-bold py-2 px-4 md:py-3 md:px-6 rounded"> |
||||
Get To Know Us |
||||
</button> |
||||
</div> |
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6 mt-12"> |
||||
<div className="bg-white rounded-lg shadow-md p-4 flex justify-center items-center"> |
||||
<img |
||||
src="https://images.unsplash.com/photo-1603462903957-566630607cc7?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fGZyZXNoJTIwdmVnZXRhYmxlfGVufDB8fDB8fHww" |
||||
alt="Farm Vegetables" |
||||
className="w-50 h-50 object-cover rounded" |
||||
/> |
||||
</div> |
||||
<div className="bg-white rounded-lg shadow-md p-4 flex justify-center items-center"> |
||||
<img |
||||
src="https://plus.unsplash.com/premium_photo-1661322640130-f6a1e2c36653?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTN8fGFwcGxlfGVufDB8fDB8fHww" |
||||
alt="Apples" |
||||
className="w-50 h-50 object-cover rounded" |
||||
/> |
||||
</div> |
||||
</div> |
||||
|
||||
</main> |
||||
); |
||||
} |
||||
|
||||
export default ConsumerHomePage; |
@ -0,0 +1,19 @@ |
||||
import React from 'react'; |
||||
import {Link} from "react-router-dom"; |
||||
|
||||
const Footer = () => { |
||||
return ( |
||||
<footer className="bg-gray-800 text-white py-4"> |
||||
<div className="container mx-auto text-center"> |
||||
<p>© 2025 Digital Farmer's Market. All Rights Reserved.</p> |
||||
<div className="flex justify-center space-x-4 mt-2"> |
||||
<Link to="/about" className="hover:text-gray-400">About Us</Link> |
||||
<a href="#" className="hover:text-gray-400">Contact</a> |
||||
<a href="#" className="hover:text-gray-400">Privacy Policy</a> |
||||
</div> |
||||
</div> |
||||
</footer> |
||||
); |
||||
}; |
||||
|
||||
export default Footer; |
@ -0,0 +1,72 @@ |
||||
import React, { useState } from "react"; |
||||
import farmVegetables from './logo.jpg'; |
||||
import {Link} from "react-router-dom"; |
||||
|
||||
function Navbar() { |
||||
const [isMenuOpen, setIsMenuOpen] = useState(false); |
||||
|
||||
const handleToggleMenu = () => { |
||||
setIsMenuOpen(!isMenuOpen); |
||||
}; |
||||
const handleMenuClick = () => { |
||||
setIsMenuOpen(false); |
||||
}; |
||||
return ( |
||||
<header className="bg-white shadow-md"> |
||||
<div className="container mx-auto px-4 py-4 flex justify-between items-center"> |
||||
<div className="flex items-center"> |
||||
<img |
||||
src={farmVegetables} // Using the imported image |
||||
alt="wheat-icon" |
||||
className="w-8 h-8" |
||||
/> |
||||
<h1 className="text-xl font-bold ml-4">DFM</h1> |
||||
</div> |
||||
<nav className="hidden md:flex space-x-6 font-medium"> |
||||
<Link to ="/" className="hover:text-gray-900">Home</Link> |
||||
<Link to="/shop" className="hover:text-gray-900">Shop</Link> |
||||
<Link to="/cart" className="hover:text-gray-900">Cart</Link> |
||||
<Link to="/product" className="hover:text-gray-900">Product</Link> |
||||
<Link to ="/profile" className="hover:text-gray-900">Account</Link> |
||||
<Link to ="/login" className="hover:text-gray-900">Login</Link> |
||||
<Link to ="/forget" className="hover:text-gray-900">Forget</Link> |
||||
</nav> |
||||
<button |
||||
className="md:hidden text-gray-900" |
||||
onClick={handleToggleMenu} |
||||
> |
||||
<svg |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
fill="none" |
||||
viewBox="0 0 24 24" |
||||
strokeWidth="2" |
||||
stroke="currentColor" |
||||
className="w-6 h-6" |
||||
> |
||||
<path |
||||
strokeLinecap="round" |
||||
strokeLinejoin="round" |
||||
d="M4 6h16M4 12h16m-7 6h7" |
||||
/> |
||||
</svg> |
||||
</button> |
||||
</div> |
||||
|
||||
{isMenuOpen && ( |
||||
<div className="md:hidden bg-white shadow-md"> |
||||
<nav className="flex flex-col space-y-4 px-4 py-4"> |
||||
<a href="/about" onClick={handleMenuClick} className="hover:text-gray-900">About</a> |
||||
<a href="#shop" onClick={handleMenuClick} className="hover:text-gray-900">Shop</a> |
||||
<a href="/cart" onClick={handleMenuClick} className="hover:text-gray-900">Cart</a> |
||||
<a href="/product" onClick={handleMenuClick} className="hover:text-gray-900">Product</a> |
||||
<a href ="/" onClick={handleMenuClick} className="hover:text-gray-900">Home</a> |
||||
<a href ="/profile" onClick={handleMenuClick} className="hover:text-gray-900">Account</a> |
||||
<a href ="/login" onClick={handleMenuClick} className="hover:text-gray-900">Login</a> |
||||
</nav> |
||||
</div> |
||||
)} |
||||
</header> |
||||
); |
||||
} |
||||
|
||||
export default Navbar; |
After Width: | Height: | Size: 54 KiB |
@ -0,0 +1,59 @@ |
||||
import React from "react"; |
||||
import Team from "./team.jpg" |
||||
const AboutUs = () => { |
||||
return ( |
||||
<div className="flex flex-col items-center p-4"> |
||||
<div className="max-w-4xl w-full bg-white p-8 rounded-lg shadow-md"> |
||||
<h1 className="text-center mb-4 text-3xl font-playfair text-[#4a2c2a]"> |
||||
About Us |
||||
</h1> |
||||
<p className="text-center mb-8"> |
||||
Welcome to Digital Farmer's Market |
||||
</p> |
||||
<p className="text-center mb-8"> |
||||
We connect Nepalese farmers directly with consumers, providing a fair |
||||
and transparent marketplace for fresh, locally grown produce. By |
||||
eliminating middlemen, we ensure farmers receive fair prices and |
||||
consumers access high-quality food. |
||||
</p> |
||||
<hr className="my-8" /> |
||||
<h2 className="text-center mb-8 text-2xl font-playfair text-[#4a2c2a]"> |
||||
Why Choose Us? |
||||
</h2> |
||||
<div className="flex flex-col md:flex-row justify-around text-center mb-8"> |
||||
<div className="mb-8 md:mb-0"> |
||||
<p className="text-4xl font-bold mb-2">1.</p> |
||||
<p>Fair Pricing: Farmers set their own prices, ensuring fair compensation.</p> |
||||
</div> |
||||
<div className="mb-8 md:mb-0"> |
||||
<p className="text-4xl font-bold mb-2">2.</p> |
||||
<p>Fresh Produce: Enjoy high-quality, locally grown food.</p> |
||||
</div> |
||||
<div> |
||||
<p className="text-4xl font-bold mb-2">3.</p> |
||||
<p>Sustainability: We promote sustainable farming practices and reduce food waste.</p> |
||||
</div> |
||||
</div> |
||||
<hr className="my-8" /> |
||||
<h2 className="text-center mb-8 text-2xl font-playfair text-[#4a2c2a]"> |
||||
Meet Our Team |
||||
</h2> |
||||
<p className="text-center mb-8"> |
||||
Our team of five passionate individuals is dedicated to transforming |
||||
the agricultural landscape in Nepal. With diverse backgrounds in |
||||
agriculture, technology, and entrepreneurship, we’re united by a |
||||
common goal: to empower farmers and support sustainable agriculture. |
||||
</p> |
||||
<div className="flex justify-center"> |
||||
<img |
||||
src={Team} |
||||
alt="Team of five individuals standing together, smiling, with a text 'TEAM DeltaX' at the bottom" |
||||
className="rounded-lg shadow-md w-full max-w-md" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default AboutUs; |
@ -0,0 +1,458 @@ |
||||
// const Profile = () => { |
||||
// return ( |
||||
// <div className="min-h-screen flex items-center justify-center bg-black"> |
||||
// <div className="bg-black p-4 md:p-8 rounded-lg shadow-lg max-w-4xl w-full flex flex-col md:flex-row"> |
||||
// {/* Left Section */} |
||||
// <div className="md:w-1/2 p-4 md:p-8"> |
||||
// <div className="mb-4 md:mb-8 h-16 w-16 bg-black border border-black-700 rounded-full flex items-center justify-center"> |
||||
// <span className="text-white font-bold text-lg">DFM</span> |
||||
// </div> |
||||
// <h1 className="text-2xl md:text-4xl font-bold text-white mb-2 md:mb-4"> |
||||
// Create New Account |
||||
// </h1> |
||||
// <p className="text-sm md:text-lg text-gray-400"> |
||||
// Already Registered?{" "} |
||||
// <a href="#" className="text-orange-500 hover:text-orange-700"> |
||||
// Login |
||||
// </a> |
||||
// </p> |
||||
// </div> |
||||
|
||||
// {/* Right Section */} |
||||
// <div className="md:w-1/2 p-4 md:p-8 bg-black border border-gray-700 rounded-lg"> |
||||
// <h2 className="text-xl md:text-2xl font-bold text-white mb-4 md:mb-6"> |
||||
// Sign Up |
||||
// </h2> |
||||
// <form> |
||||
// <div className="mb-2 md:mb-4"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="name" |
||||
// > |
||||
// NAME |
||||
// </label> |
||||
// <input |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="name" |
||||
// type="text" |
||||
// placeholder="Enter your name" |
||||
// /> |
||||
// </div> |
||||
|
||||
// <div className="mb-2 md:mb-4"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="email" |
||||
// > |
||||
// EMAIL |
||||
// </label> |
||||
// <input |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="email" |
||||
// type="email" |
||||
// placeholder="Enter your email" |
||||
// /> |
||||
// </div> |
||||
|
||||
// <div className="mb-2 md:mb-4"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="password" |
||||
// > |
||||
// PASSWORD |
||||
// </label> |
||||
// <input |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="password" |
||||
// type="password" |
||||
// placeholder="Enter your password" |
||||
// /> |
||||
// </div> |
||||
|
||||
// <div className="mb-2 md:mb-4"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="dob" |
||||
// > |
||||
// DATE OF BIRTH |
||||
// </label> |
||||
// <input |
||||
// type="date" |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="dob" |
||||
// /> |
||||
// </div> |
||||
|
||||
// <div className="mb-4 md:mb-6"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="who" |
||||
// > |
||||
// WHO ARE YOU? |
||||
// </label> |
||||
// <select |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="who" |
||||
// > |
||||
// <option>Select</option> |
||||
// <option>Farmer</option> |
||||
// <option>Consumer</option> |
||||
// </select> |
||||
// </div> |
||||
|
||||
// <div className="mb-4 md:mb-6"> |
||||
// <label |
||||
// className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
// htmlFor="district" |
||||
// > |
||||
// DISTRICT |
||||
// </label> |
||||
// <select |
||||
// className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
// id="district" |
||||
// > |
||||
// <option>Select District</option> |
||||
// <option>Achham</option> |
||||
// <option>Arghakhanchi</option> |
||||
// <option>Baglung</option> |
||||
// <option>Baitadi</option> |
||||
// <option>Bajhang</option> |
||||
// <option>Bajura</option> |
||||
// <option>Banke</option> |
||||
// <option>Bara</option> |
||||
// <option>Bardiya</option> |
||||
// <option>Bhaktapur</option> |
||||
// <option>Bhojpur</option> |
||||
// <option>Chitwan</option> |
||||
// <option>Dadeldhura</option> |
||||
// <option>Dailekh</option> |
||||
// <option>Dang</option> |
||||
// <option>Darchula</option> |
||||
// <option>Dhading</option> |
||||
// <option>Dhankuta</option> |
||||
// <option>Dhanusha</option> |
||||
// <option>Dolakha</option> |
||||
// <option>Dolpa</option> |
||||
// <option>Doti</option> |
||||
// <option>Eastern Rukum</option> |
||||
// <option>Gorkha</option> |
||||
// <option>Gulmi</option> |
||||
// <option>Humla</option> |
||||
// <option>Ilam</option> |
||||
// <option>Jajarkot</option> |
||||
// <option>Jhapa</option> |
||||
// <option>Jumla</option> |
||||
// <option>Kailali</option> |
||||
// <option>Kalikot</option> |
||||
// <option>Kanchanpur</option> |
||||
// <option>Kathmandu</option> |
||||
// <option>Kavrepalanchok</option> |
||||
// <option>Khotang</option> |
||||
// <option>Lalitpur</option> |
||||
// <option>Lamjung</option> |
||||
// <option>Mahottari</option> |
||||
// <option>Makwanpur</option> |
||||
// <option>Manang</option> |
||||
// <option>Morang</option> |
||||
// <option>Mugu</option> |
||||
// <option>Mustang</option> |
||||
// <option>Myagdi</option> |
||||
// <option>Nawalpur</option> |
||||
// <option>Nuwakot</option> |
||||
// <option>Okhaldhunga</option> |
||||
// <option>Palpa</option> |
||||
// <option>Panchthar</option> |
||||
// <option>Parasi</option> |
||||
// <option>Parbat</option> |
||||
// <option>Parsa</option> |
||||
// <option>Pyuthan</option> |
||||
// <option>Ramechhap</option> |
||||
// <option>Rasuwa</option> |
||||
// <option>Rautahat</option> |
||||
// <option>Rolpa</option> |
||||
// <option>Rupandehi</option> |
||||
// <option>Salyan</option> |
||||
// <option>Sankhuwasabha</option> |
||||
// <option>Saptari</option> |
||||
// <option>Sarlahi</option> |
||||
// <option>Sindhuli</option> |
||||
// <option>Sindhupalchok</option> |
||||
// <option>Siraha</option> |
||||
// <option>Solukhumbu</option> |
||||
// <option>Sunsari</option> |
||||
// <option>Surkhet</option> |
||||
// <option>Syangja</option> |
||||
// <option>Tanahun</option> |
||||
// <option>Taplejung</option> |
||||
// <option>Tehrathum</option> |
||||
// <option>Udayapur</option> |
||||
// <option>Western Rukum</option> |
||||
// </select> |
||||
// </div> |
||||
|
||||
// <button className="w-full p-2 md:p-3 rounded-lg bg-orange-500 text-white font-bold hover:bg-orange-600"> |
||||
// Sign Up |
||||
// </button> |
||||
// </form> |
||||
// </div> |
||||
// </div> |
||||
// </div> |
||||
// ); |
||||
// }; |
||||
|
||||
// export default Profile; |
||||
|
||||
import { useState } from 'react'; |
||||
|
||||
const Profile = () => { |
||||
const [formData, setFormData] = useState({ |
||||
name: '', |
||||
email: '', |
||||
password: '', |
||||
dob: '', |
||||
who: '', |
||||
district: '' |
||||
}); |
||||
|
||||
const handleChange = (e) => { |
||||
setFormData({ |
||||
...formData, |
||||
[e.target.id]: e.target.value |
||||
}); |
||||
}; |
||||
|
||||
const handleSubmit = async (e) => { |
||||
e.preventDefault(); |
||||
try { |
||||
const response = await fetch('http://127.0.0.1:8000/create/', { |
||||
method: 'POST', |
||||
headers: { |
||||
'Content-Type': 'application/json' |
||||
}, |
||||
body: JSON.stringify(formData) |
||||
}); |
||||
if (response.ok) { |
||||
const data = await response.json(); |
||||
console.log('Success:', data); |
||||
} else { |
||||
console.error('Error:', response.statusText); |
||||
} |
||||
} catch (error) { |
||||
console.error('Error:', error); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div className="min-h-screen flex items-center justify-center bg-black"> |
||||
<div className="bg-black p-4 md:p-8 rounded-lg shadow-lg max-w-4xl w-full flex flex-col md:flex-row"> |
||||
{/* Left Section */} |
||||
<div className="md:w-1/2 p-4 md:p-8"> |
||||
<div className="mb-4 md:mb-8 h-16 w-16 bg-black border border-black-700 rounded-full flex items-center justify-center"> |
||||
<span className="text-white font-bold text-lg">DFM</span> |
||||
</div> |
||||
<h1 className="text-2xl md:text-4xl font-bold text-white mb-2 md:mb-4"> |
||||
Create New Account |
||||
</h1> |
||||
<p className="text-sm md:text-lg text-gray-400"> |
||||
Already Registered?{" "} |
||||
<a href="#" className="text-orange-500 hover:text-orange-700"> |
||||
Login |
||||
</a> |
||||
</p> |
||||
</div> |
||||
|
||||
{/* Right Section */} |
||||
<div className="md:w-1/2 p-4 md:p-8 bg-black border border-gray-700 rounded-lg"> |
||||
<h2 className="text-xl md:text-2xl font-bold text-white mb-4 md:mb-6"> |
||||
Sign Up |
||||
</h2> |
||||
<form onSubmit={handleSubmit}> |
||||
<div className="mb-2 md:mb-4"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="name" |
||||
> |
||||
NAME |
||||
</label> |
||||
<input |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="name" |
||||
type="text" |
||||
placeholder="Enter your name" |
||||
value={formData.name} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
<div className="mb-2 md:mb-4"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="email" |
||||
> |
||||
EMAIL |
||||
</label> |
||||
<input |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="email" |
||||
type="email" |
||||
placeholder="Enter your email" |
||||
value={formData.email} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
<div className="mb-2 md:mb-4"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="password" |
||||
> |
||||
PASSWORD |
||||
</label> |
||||
<input |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="password" |
||||
type="password" |
||||
placeholder="Enter your password" |
||||
value={formData.password} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
<div className="mb-2 md:mb-4"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="dob" |
||||
> |
||||
DATE OF BIRTH |
||||
</label> |
||||
<input |
||||
type="date" |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="dob" |
||||
value={formData.dob} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
<div className="mb-4 md:mb-6"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="who" |
||||
> |
||||
WHO ARE YOU? |
||||
</label> |
||||
<select |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="who" |
||||
value={formData.who} |
||||
onChange={handleChange} |
||||
> |
||||
<option>Select</option> |
||||
<option>Farmer</option> |
||||
<option>Consumer</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div className="mb-4 md:mb-6"> |
||||
<label |
||||
className="block text-xs md:text-sm font-bold text-gray-400 mb-1 md:mb-2" |
||||
htmlFor="district" |
||||
> |
||||
DISTRICT |
||||
</label> |
||||
<select |
||||
className="w-full p-2 md:p-3 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="district" |
||||
value={formData.district} |
||||
onChange={handleChange} |
||||
> |
||||
<option>Select District</option> |
||||
<option>Achham</option> |
||||
<option>Arghakhanchi</option> |
||||
<option>Baglung</option> |
||||
<option>Baitadi</option> |
||||
<option>Bajhang</option> |
||||
<option>Bajura</option> |
||||
<option>Banke</option> |
||||
<option>Bara</option> |
||||
<option>Bardiya</option> |
||||
<option>Bhaktapur</option> |
||||
<option>Bhojpur</option> |
||||
<option>Chitwan</option> |
||||
<option>Dadeldhura</option> |
||||
<option>Dailekh</option> |
||||
<option>Dang</option> |
||||
<option>Darchula</option> |
||||
<option>Dhading</option> |
||||
<option>Dhankuta</option> |
||||
<option>Dhanusha</option> |
||||
<option>Dolakha</option> |
||||
<option>Dolpa</option> |
||||
<option>Doti</option> |
||||
<option>Eastern Rukum</option> |
||||
<option>Gorkha</option> |
||||
<option>Gulmi</option> |
||||
<option>Humla</option> |
||||
<option>Ilam</option> |
||||
<option>Jajarkot</option> |
||||
<option>Jhapa</option> |
||||
<option>Jumla</option> |
||||
<option>Kailali</option> |
||||
<option>Kalikot</option> |
||||
<option>Kanchanpur</option> |
||||
<option>Kathmandu</option> |
||||
<option>Kavrepalanchok</option> |
||||
<option>Khotang</option> |
||||
<option>Lalitpur</option> |
||||
<option>Lamjung</option> |
||||
<option>Mahottari</option> |
||||
<option>Makwanpur</option> |
||||
<option>Manang</option> |
||||
<option>Morang</option> |
||||
<option>Mugu</option> |
||||
<option>Mustang</option> |
||||
<option>Myagdi</option> |
||||
<option>Nawalpur</option> |
||||
<option>Nuwakot</option> |
||||
<option>Okhaldhunga</option> |
||||
<option>Palpa</option> |
||||
<option>Panchthar</option> |
||||
<option>Parasi</option> |
||||
<option>Parbat</option> |
||||
<option>Parsa</option> |
||||
<option>Pyuthan</option> |
||||
<option>Ramechhap</option> |
||||
<option>Rasuwa</option> |
||||
<option>Rautahat</option> |
||||
<option>Rolpa</option> |
||||
<option>Rupandehi</option> |
||||
<option>Salyan</option> |
||||
<option>Sankhuwasabha</option> |
||||
<option>Saptari</option> |
||||
<option>Sarlahi</option> |
||||
<option>Sindhuli</option> |
||||
<option>Sindhupalchok</option> |
||||
<option>Siraha</option> |
||||
<option>Solukhumbu</option> |
||||
<option>Sunsari</option> |
||||
<option>Surkhet</option> |
||||
<option>Syangja</option> |
||||
<option>Tanahun</option> |
||||
<option>Taplejung</option> |
||||
<option>Tehrathum</option> |
||||
<option>Udayapur</option> |
||||
<option>Western Rukum</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<button className="w-full p-2 md:p-3 rounded-lg bg-orange-500 text-white font-bold hover:bg-orange-600"> |
||||
Sign Up |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default Profile; |
@ -0,0 +1,26 @@ |
||||
// Parent Component |
||||
const App = () => { |
||||
const [cart, setCart] = useState([]); |
||||
|
||||
const addToCart = (product) => { |
||||
if (product.quantity > 0) { |
||||
const existingProductIndex = cart.findIndex(item => item.name === product.name); |
||||
if (existingProductIndex > -1) { |
||||
const newCart = [...cart]; |
||||
newCart[existingProductIndex].quantity += product.quantity; |
||||
setCart(newCart); |
||||
} else { |
||||
setCart([...cart, { ...product }]); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div> |
||||
<Shop addToCart={addToCart} /> |
||||
<Cart cart={cart} setCart={setCart} /> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default addToCart; |
After Width: | Height: | Size: 82 KiB |
@ -0,0 +1,69 @@ |
||||
import React from 'react'; |
||||
|
||||
const Cart = ({ cart, setCart }) => { |
||||
const handleRemove = (itemToRemove) => { |
||||
setCart(cart.filter(item => item.name !== itemToRemove.name)); |
||||
}; |
||||
|
||||
const calculateTotal = () => { |
||||
return cart.reduce((acc, item) => acc + item.price * item.quantity, 0); |
||||
}; |
||||
|
||||
return ( |
||||
<div className="p-4 max-w-lg mx-auto bg-zinc-900 text-zinc-100"> |
||||
<div className="flex items-center justify-between mb-4"> |
||||
<button className="text-white" onClick={() => console.log("Back to Shop")}> |
||||
<i className="fas fa-arrow-left"></i> Back |
||||
</button> |
||||
<h1 className="text-xl font-bold">My Cart</h1> |
||||
<button className="text-white"> |
||||
<i className="fas fa-bars"></i> |
||||
</button> |
||||
</div> |
||||
<div className="space-y-4"> |
||||
{cart.length === 0 ? ( |
||||
<p>Your cart is empty.</p> |
||||
) : ( |
||||
cart.map((item, index) => ( |
||||
<div key={item.name} className="flex items-center space-x-4"> |
||||
<img |
||||
src={item.image} |
||||
alt={item.name} |
||||
className="w-16 h-16 object-cover" |
||||
/> |
||||
<div className="flex-1"> |
||||
<h2 className="text-lg font-bold">{item.name}</h2> |
||||
<p className="text-sm text-gray-400">Price: NPR {item.price}</p> |
||||
<p className="text-sm"> |
||||
Quantity: <span className="text-red-500">{item.quantity}</span> |
||||
</p> |
||||
</div> |
||||
<button className="text-red-500" onClick={() => handleRemove(item)}>Remove</button> |
||||
</div> |
||||
)) |
||||
)} |
||||
</div> |
||||
<div className="bg-gray-800 p-4 mt-6 rounded-lg"> |
||||
<div className="flex justify-between items-center mb-2"> |
||||
<h2 className="text-lg font-bold">Order Summary</h2> |
||||
</div> |
||||
<div className="space-y-2"> |
||||
<div className="flex justify-between"> |
||||
<p className="text-sm">Sub Total</p> |
||||
<p className="text-sm">NPR {calculateTotal()}</p> |
||||
</div> |
||||
<hr className="border-gray-700" /> |
||||
<div className="flex justify-between font-bold"> |
||||
<p className="text-lg">Total</p> |
||||
<p className="text-lg">NPR {calculateTotal()}</p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<button className="bg-gray-800 w-full py-3 mt-6 rounded-lg text-lg font-bold" onClick={() => alert("Proceeding to checkout...")}> |
||||
Check Out |
||||
</button> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default Cart; |
@ -0,0 +1,88 @@ |
||||
const Forgot = () => { |
||||
return ( |
||||
<div className="bg-black min-h-screen flex items-center justify-center relative"> |
||||
{/* Background Image */} |
||||
<img |
||||
alt="Background image of a train station" |
||||
className="absolute w-full h-full object-cover opacity-30" |
||||
/> |
||||
|
||||
{/* Content Container */} |
||||
<div className="relative z-10 flex flex-col md:flex-row items-center md:items-start justify-center w-full max-w-4xl p-6"> |
||||
{/* Left Section */} |
||||
<div className="text-white md:w-1/2 mb-6 md:mb-0 text-center md:text-left"> |
||||
<img |
||||
src="https://placehold.co/100x50" |
||||
alt="DFM Logo" |
||||
className="mb-6 mx-auto md:mx-0" |
||||
/> |
||||
<h1 className="text-4xl font-bold mb-2">Forgot The Password</h1> |
||||
<p className="text-lg">New Password</p> |
||||
</div> |
||||
|
||||
{/* Right Section */} |
||||
<div className="bg-white bg-opacity-10 p-8 rounded-lg w-full md:w-1/2"> |
||||
<h2 className="text-white text-2xl font-bold mb-6 text-center md:text-left">Create</h2> |
||||
<form> |
||||
{/* Old Password Input */} |
||||
<div className="mb-4"> |
||||
<label |
||||
htmlFor="old-password" |
||||
className="block text-white text-sm font-bold mb-2" |
||||
> |
||||
OLD PASSWORD |
||||
</label> |
||||
<input |
||||
type="password" |
||||
id="old-password" |
||||
placeholder="" |
||||
className="w-full p-3 rounded bg-gray-200 bg-opacity-20 text-white" |
||||
/> |
||||
</div> |
||||
|
||||
{/* Email Input */} |
||||
<div className="mb-4"> |
||||
<label |
||||
htmlFor="email" |
||||
className="block text-white text-sm font-bold mb-2" |
||||
> |
||||
EMAIL |
||||
</label> |
||||
<input |
||||
type="email" |
||||
id="email" |
||||
className="w-full p-3 rounded bg-gray-200 bg-opacity-20 text-white" |
||||
/> |
||||
</div> |
||||
|
||||
{/* New Password Input */} |
||||
<div className="mb-6"> |
||||
<label |
||||
htmlFor="new-password" |
||||
className="block text-white text-sm font-bold mb-2" |
||||
> |
||||
NEW PASSWORD |
||||
</label> |
||||
<input |
||||
type="password" |
||||
id="new-password" |
||||
placeholder="" |
||||
className="w-full p-3 rounded bg-gray-200 bg-opacity-20 text-white" |
||||
/> |
||||
</div> |
||||
|
||||
{/* Submit Button */} |
||||
<button |
||||
type="submit" |
||||
className="w-full bg-orange-500 text-white p-3 rounded font-bold" |
||||
> |
||||
Send |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default Forgot; |
@ -0,0 +1,166 @@ |
||||
// const Login = () => { |
||||
// return ( |
||||
// <div |
||||
// className="flex flex-col md:flex-row items-center justify-center min-h-screen p-4 bg-black" |
||||
// > |
||||
// {/* Logo Section */} |
||||
// <div className="absolute top-10 left-10 flex items-center"> |
||||
// <span className="text-white text-xl font-bold">DFM</span> |
||||
// </div> |
||||
|
||||
// {/* Heading Section */} |
||||
// <div className="text-white text-left mb-10 md:mb-0 md:mr-20"> |
||||
// <h1 className="text-5xl font-bold">Login</h1> |
||||
// <p className="mt-2">Sign in to continue</p> |
||||
// </div> |
||||
|
||||
// {/* Login Form */} |
||||
// <div className="bg-white bg-opacity-10 p-10 rounded-lg shadow-lg w-full max-w-md"> |
||||
// <h2 className="text-white text-3xl font-bold mb-6">Sign in</h2> |
||||
// <form> |
||||
// {/* Email Input */} |
||||
// <div className="mb-4"> |
||||
// <label |
||||
// className="block text-white text-sm font-bold mb-2" |
||||
// htmlFor="email" |
||||
// > |
||||
// EMAIL |
||||
// </label> |
||||
// <input |
||||
// className="w-full px-3 py-2 text-gray-700 bg-gray-200 rounded-lg focus:outline-none focus:shadow-outline" |
||||
// id="email" |
||||
// type="email" |
||||
// value="hello@reallygreatsite.com" |
||||
// readOnly |
||||
// /> |
||||
// </div> |
||||
|
||||
// {/* Password Input */} |
||||
// <div className="mb-6"> |
||||
// <label |
||||
// className="block text-white text-sm font-bold mb-2" |
||||
// htmlFor="password" |
||||
// > |
||||
// PASSWORD |
||||
// </label> |
||||
// <input |
||||
// className="w-full px-3 py-2 text-gray-700 bg-gray-200 rounded-lg focus:outline-none focus:shadow-outline" |
||||
// id="password" |
||||
// type="password" |
||||
// value="" |
||||
// readOnly |
||||
// /> |
||||
// </div> |
||||
|
||||
// {/* Login Button */} |
||||
// <div className="flex items-center justify-center"> |
||||
// <button |
||||
// className="bg-orange-500 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" |
||||
// type="button" |
||||
// > |
||||
// Login |
||||
// </button> |
||||
// </div> |
||||
// </form> |
||||
// </div> |
||||
// </div> |
||||
// ); |
||||
// }; |
||||
|
||||
// export default Login; |
||||
|
||||
import { useState } from 'react'; |
||||
const Login = () => { |
||||
const [formData, setFormData] = useState({ |
||||
username: '', |
||||
password: '' |
||||
}); |
||||
|
||||
const handleChange = (e) => { |
||||
setFormData({ |
||||
...formData, |
||||
[e.target.name]: e.target.value |
||||
}); |
||||
}; |
||||
|
||||
const handleSubmit = async (e) => { |
||||
e.preventDefault(); |
||||
try { |
||||
const response = await fetch('http://127.0.0.1:8000/login/', { |
||||
method: 'POST', |
||||
headers: { |
||||
'Content-Type': 'application/json' |
||||
}, |
||||
body: JSON.stringify(formData) |
||||
}); |
||||
if (response.ok) { |
||||
const data = await response.json(); |
||||
console.log('Success:', data); |
||||
// Handle successful login (e.g., redirect to another page) |
||||
} else { |
||||
console.error('Error:', response.statusText); |
||||
} |
||||
} catch (error) { |
||||
console.error('Error:', error); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div className="flex flex-col md:flex-row items-center justify-center min-h-screen p-4 bg-black"> |
||||
{/* Logo Section */} |
||||
<div className="absolute top-10 left-10 flex items-center"> |
||||
<span className="text-white text-xl font-bold">DFM</span> |
||||
</div> |
||||
|
||||
{/* Heading Section */} |
||||
<div className="text-white text-left mb-10 md:mb-0 md:mr-20"> |
||||
<h1 className="text-5xl font-bold">Login</h1> |
||||
<p className="mt-2">Sign in to continue</p> |
||||
</div> |
||||
|
||||
{/* Login Form */} |
||||
<div className="bg-white bg-opacity-10 p-10 rounded-lg shadow-lg w-full max-w-md"> |
||||
<h2 className="text-white text-3xl font-bold mb-6">Sign in</h2> |
||||
<form onSubmit={handleSubmit}> |
||||
{/* Username Input */} |
||||
<div className="mb-4"> |
||||
<label className="block text-white text-sm font-bold mb-2" htmlFor="username"> |
||||
Username |
||||
</label> |
||||
<input |
||||
className="w-full p-2 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="username" |
||||
name="username" |
||||
type="text" |
||||
placeholder="Enter your username" |
||||
value={formData.username} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
{/* Password Input */} |
||||
<div className="mb-4"> |
||||
<label className="block text-white text-sm font-bold mb-2" htmlFor="password"> |
||||
Password |
||||
</label> |
||||
<input |
||||
className="w-full p-2 rounded-lg bg-black border border-gray-700 text-white focus:outline-none focus:ring-2 focus:ring-orange-500" |
||||
id="password" |
||||
name="password" |
||||
type="password" |
||||
placeholder="Enter your password" |
||||
value={formData.password} |
||||
onChange={handleChange} |
||||
/> |
||||
</div> |
||||
|
||||
<button className="w-full p-2 rounded-lg bg-orange-500 text-white font-bold hover:bg-orange-600"> |
||||
Sign In |
||||
</button> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default Login; |
@ -0,0 +1,27 @@ |
||||
import React, { useState } from 'react'; |
||||
import Shop from './Shop'; |
||||
import Cart from './Cart'; |
||||
|
||||
const App = () => { |
||||
const [cart, setCart] = useState([]); |
||||
|
||||
const addToCart = (product) => { |
||||
const existingProductIndex = cart.findIndex(item => item.name === product.name); |
||||
if (existingProductIndex > -1) { |
||||
const newCart = [...cart]; |
||||
newCart[existingProductIndex].quantity += product.quantity; |
||||
setCart(newCart); |
||||
} else { |
||||
setCart([...cart, { ...product }]); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div> |
||||
<Shop addToCart={addToCart} /> |
||||
<Cart cart={cart} setCart={setCart} /> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default App; |
File diff suppressed because one or more lines are too long
@ -0,0 +1,59 @@ |
||||
import React from "react"; |
||||
|
||||
const ProfilePage = () => { |
||||
return ( |
||||
<div className="flex flex-col items-center p-4"> |
||||
<div className="max-w-4xl w-full bg-white p-8 rounded-lg shadow-md"> |
||||
<h1 className="text-center mb-4 text-3xl font-playfair text-[#4a2c2a]"> |
||||
About Us |
||||
</h1> |
||||
<p className="text-center mb-8"> |
||||
Welcome to Digital Farmer's Market |
||||
</p> |
||||
<p className="text-center mb-8"> |
||||
We connect Nepalese farmers directly with consumers, providing a fair |
||||
and transparent marketplace for fresh, locally grown produce. By |
||||
eliminating middlemen, we ensure farmers receive fair prices and |
||||
consumers access high-quality food. |
||||
</p> |
||||
<hr className="my-8" /> |
||||
<h2 className="text-center mb-8 text-2xl font-playfair text-[#4a2c2a]"> |
||||
Why Choose Us? |
||||
</h2> |
||||
<div className="flex flex-col md:flex-row justify-around text-center mb-8"> |
||||
<div className="mb-8 md:mb-0"> |
||||
<p className="text-4xl font-bold mb-2">1.</p> |
||||
<p>Fair Pricing: Farmers set their own prices, ensuring fair compensation.</p> |
||||
</div> |
||||
<div className="mb-8 md:mb-0"> |
||||
<p className="text-4xl font-bold mb-2">2.</p> |
||||
<p>Fresh Produce: Enjoy high-quality, locally grown food.</p> |
||||
</div> |
||||
<div> |
||||
<p className="text-4xl font-bold mb-2">3.</p> |
||||
<p>Sustainability: We promote sustainable farming practices and reduce food waste.</p> |
||||
</div> |
||||
</div> |
||||
<hr className="my-8" /> |
||||
<h2 className="text-center mb-8 text-2xl font-playfair text-[#4a2c2a]"> |
||||
Meet Our Team |
||||
</h2> |
||||
<p className="text-center mb-8"> |
||||
Our team of five passionate individuals is dedicated to transforming |
||||
the agricultural landscape in Nepal. With diverse backgrounds in |
||||
agriculture, technology, and entrepreneurship, we’re united by a |
||||
common goal: to empower farmers and support sustainable agriculture. |
||||
</p> |
||||
<div className="flex justify-center"> |
||||
<img |
||||
src="https://placehold.co/600x400" |
||||
alt="Team of five individuals standing together, smiling, with a text 'TEAM DeltaX' at the bottom" |
||||
className="rounded-lg shadow-md w-full max-w-md" |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default ProfilePage; |
@ -0,0 +1,182 @@ |
||||
// import React, { useState } from 'react'; |
||||
|
||||
// const productsData = [ |
||||
// { |
||||
// name: "Spinach", |
||||
// price: 30, |
||||
// image: "https://placehold.co/200x200?text=Spinach", |
||||
// quantity: 1, |
||||
// }, |
||||
// { |
||||
// name: "Brinjal", |
||||
// price: 45, |
||||
// image: "https://placehold.co/200x200?text=Brinjal", |
||||
// quantity: 0, |
||||
// }, |
||||
// { |
||||
// name: "Orange", |
||||
// price: 112, |
||||
// image: "https://placehold.co/200x200?text=Orange", |
||||
// quantity: 1, |
||||
// }, |
||||
// { |
||||
// name: "Bittergourd", |
||||
// price: 85, |
||||
// image: "https://placehold.co/200x200?text=Bittergourd", |
||||
// quantity: 0, |
||||
// }, |
||||
// { |
||||
// name: "Beetroot", |
||||
// price: 85, |
||||
// image: "https://placehold.co/200x200?text=Beetroot", |
||||
// quantity: 1, |
||||
// }, |
||||
// { |
||||
// name: "Corn per piece", |
||||
// price: 30, |
||||
// image: "https://placehold.co/200x200?text=Corn", |
||||
// quantity: 0, |
||||
// }, |
||||
// ]; |
||||
|
||||
// function Shop() { |
||||
// const [products, setProducts] = useState(productsData); |
||||
|
||||
// const incrementQuantity = (index) => { |
||||
// const newProducts = [...products]; |
||||
// newProducts[index].quantity += 1; |
||||
// setProducts(newProducts); |
||||
// }; |
||||
|
||||
// const decrementQuantity = (index) => { |
||||
// const newProducts = [...products]; |
||||
// if (newProducts[index].quantity > 0) { |
||||
// newProducts[index].quantity -= 1; |
||||
// setProducts(newProducts); |
||||
// } |
||||
// }; |
||||
|
||||
// return ( |
||||
// <div className="p-4 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4"> |
||||
// {products.map((product, index) => ( |
||||
// <div key={index} className="bg-green-100 p-4 rounded-lg shadow-md"> |
||||
// <img |
||||
// src={product.image} |
||||
// alt={product.name} |
||||
// className="w-full h-40 object-cover rounded-lg mb-4" |
||||
// /> |
||||
// <h2 className="text-lg font-bold mb-2">{product.name}</h2> |
||||
// <p className="text-gray-700 mb-4">NPR {product.price}</p> |
||||
// <div className="flex items-center justify-between"> |
||||
// <button |
||||
// className="bg-gray-300 text-gray-700 px-2 py-1 rounded" |
||||
// onClick={() => decrementQuantity(index)} |
||||
// > |
||||
// - |
||||
// </button> |
||||
// <span className="mx-2">{product.quantity}</span> |
||||
// <button |
||||
// className="bg-gray-300 text-gray-700 px-2 py-1 rounded" |
||||
// onClick={() => incrementQuantity(index)} |
||||
// > |
||||
// + |
||||
// </button> |
||||
// </div> |
||||
// <button className="bg-blue-500 text-white my-3 py-2 px-4 rounded"> |
||||
// Add to Cart |
||||
// </button> |
||||
// </div> |
||||
// ))} |
||||
// </div> |
||||
// ); |
||||
// } |
||||
|
||||
// export default Shop; |
||||
|
||||
|
||||
import React, { useState } from 'react'; |
||||
|
||||
const productsData = [ |
||||
{ name: "Spinach", price: 30, image: "https://placehold.co/200x200?text=Spinach", quantity: 1 }, |
||||
{ name: "Brinjal", price: 45, image: "https://placehold.co/200x200?text=Brinjal", quantity: 0 }, |
||||
{ name: "Orange", price: 112, image: "https://placehold.co/200x200?text=Orange", quantity: 1 }, |
||||
{ name: "Bittergourd", price: 85, image: "https://placehold.co/200x200?text=Bittergourd", quantity: 0 }, |
||||
{ name: "Beetroot", price: 85, image: "https://placehold.co/200x200?text=Beetroot", quantity: 0 }, |
||||
{ name: "Corn per piece", price: 30, image: "https://placehold.co/200x200?text=Corn", quantity: 0 }, |
||||
]; |
||||
|
||||
function Shop({ addToCart }) { |
||||
const [products, setProducts] = useState(productsData); |
||||
const [searchQuery, setSearchQuery] = useState(''); |
||||
|
||||
const filteredProducts = products.filter(product => |
||||
product.name.toLowerCase().includes(searchQuery.toLowerCase()) |
||||
); |
||||
|
||||
const incrementQuantity = (index) => { |
||||
const newProducts = [...products]; |
||||
newProducts[index].quantity += 1; |
||||
setProducts(newProducts); |
||||
}; |
||||
|
||||
const decrementQuantity = (index) => { |
||||
const newProducts = [...products]; |
||||
if (newProducts[index].quantity > 0) { |
||||
newProducts[index].quantity -= 1; |
||||
setProducts(newProducts); |
||||
} |
||||
}; |
||||
|
||||
return ( |
||||
<div className="p-4"> |
||||
<input |
||||
type="text" |
||||
placeholder="Search products..." |
||||
value={searchQuery} |
||||
onChange={(e) => setSearchQuery(e.target.value)} |
||||
className="mb-4 p-2 border border-gray-300 rounded" |
||||
/> |
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4"> |
||||
{filteredProducts.map((product, index) => ( |
||||
<div key={index} className="bg-green-100 p-4 rounded-lg shadow-md"> |
||||
<img |
||||
src={product.image} |
||||
alt={product.name} |
||||
className="w-full h-40 object-cover rounded-lg mb-4" |
||||
/> |
||||
<h2 className="text-lg font-bold mb-2">{product.name}</h2> |
||||
<p className="text-gray-700 mb-4">NPR {product.price}</p> |
||||
<div className="flex items-center justify-between mb-4"> |
||||
<button |
||||
className="bg-gray-300 text-gray-700 px-2 py-1 rounded" |
||||
onClick={() => decrementQuantity(index)} |
||||
> |
||||
- |
||||
</button> |
||||
<span className="mx-2">{product.quantity}</span> |
||||
<button |
||||
className="bg-gray-300 text-gray-700 px-2 py-1 rounded" |
||||
onClick={() => incrementQuantity(index)} |
||||
> |
||||
+ |
||||
</button> |
||||
</div> |
||||
<button |
||||
className="bg-blue-500 text-white w-full py-2 rounded" |
||||
onClick={() => { |
||||
if (product.quantity > 0) { |
||||
addToCart({ ...product, quantity: product.quantity }); |
||||
incrementQuantity(index); // Reset quantity after adding to cart |
||||
} |
||||
}} |
||||
> |
||||
Add to Cart |
||||
</button> |
||||
</div> |
||||
))} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default Shop; |
After Width: | Height: | Size: 271 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 53 KiB |
@ -0,0 +1,3 @@ |
||||
@tailwind base; |
||||
@tailwind components; |
||||
@tailwind utilities; |
@ -0,0 +1,13 @@ |
||||
import { StrictMode } from 'react' |
||||
import { createRoot } from 'react-dom/client' |
||||
import './index.css' |
||||
import App from './App.jsx' |
||||
import {BrowserRouter} from "react-router-dom"; |
||||
|
||||
createRoot(document.getElementById('root')).render( |
||||
<StrictMode> |
||||
<BrowserRouter> |
||||
<App /> |
||||
</BrowserRouter> |
||||
</StrictMode>, |
||||
) |
@ -0,0 +1,12 @@ |
||||
/** @type {import('tailwindcss').Config} */ |
||||
export default { |
||||
content: [ |
||||
"./index.html", |
||||
"./src/**/*.{js,ts,jsx,tsx}", |
||||
], |
||||
theme: { |
||||
extend: {}, |
||||
}, |
||||
plugins: [], |
||||
} |
||||
|
@ -0,0 +1,7 @@ |
||||
import { defineConfig } from 'vite' |
||||
import react from '@vitejs/plugin-react' |
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({ |
||||
plugins: [react()], |
||||
}) |
@ -0,0 +1,64 @@ |
||||
# My Fullstack App |
||||
|
||||
This project is a fullstack application that consists of a Django backend and a React frontend. The backend is built using Django and connects to a MongoDB database, while the frontend is developed using React with Vite as the bundler and Tailwind CSS for styling. |
||||
|
||||
## Project Structure |
||||
|
||||
``` |
||||
my-fullstack-app |
||||
├── backend |
||||
│ ├── manage.py |
||||
│ ├── requirements.txt |
||||
│ ├── backend |
||||
│ │ ├── __init__.py |
||||
│ │ ├── settings.py |
||||
│ │ ├── urls.py |
||||
│ │ └── wsgi.py |
||||
│ └── app |
||||
│ ├── __init__.py |
||||
│ ├── models.py |
||||
│ ├── views.py |
||||
│ └── urls.py |
||||
├── frontend |
||||
│ ├── index.html |
||||
│ ├── package.json |
||||
│ ├── postcss.config.js |
||||
│ ├── tailwind.config.js |
||||
│ ├── tsconfig.json |
||||
│ ├── vite.config.ts |
||||
│ └── src |
||||
│ ├── main.tsx |
||||
│ ├── App.tsx |
||||
│ └── index.css |
||||
└── README.md |
||||
``` |
||||
|
||||
## Backend Setup |
||||
|
||||
1. Navigate to the `backend` directory. |
||||
2. Install the required packages listed in `requirements.txt` using pip. |
||||
3. Run the Django server using the command: |
||||
``` |
||||
python manage.py runserver |
||||
``` |
||||
|
||||
## Frontend Setup |
||||
|
||||
1. Navigate to the `frontend` directory. |
||||
2. Install the dependencies using npm: |
||||
``` |
||||
npm install |
||||
``` |
||||
3. Start the development server using: |
||||
``` |
||||
npm run dev |
||||
``` |
||||
|
||||
## Technologies Used |
||||
|
||||
- **Backend**: Django, MongoDB |
||||
- **Frontend**: React, Vite, Tailwind CSS |
||||
|
||||
## License |
||||
|
||||
This project is licensed under the MIT License. |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
@ -0,0 +1,6 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class AppConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'app' |
Binary file not shown.
@ -0,0 +1,3 @@ |
||||
from django.db import models |
||||
|
||||
# Create your models here. |
@ -0,0 +1,12 @@ |
||||
from rest_framework import serializers |
||||
from .models import ExampleModel |
||||
from django.contrib.auth.models import User |
||||
|
||||
class LoginSerializer(serializers.Serializer): |
||||
username = serializers.CharField() |
||||
password = serializers.CharField() |
||||
|
||||
class ExampleModelSerializer(serializers.ModelSerializer): |
||||
class Meta: |
||||
model = ExampleModel |
||||
fields = '__all__' |
@ -0,0 +1,3 @@ |
||||
from django.test import TestCase |
||||
|
||||
# Create your tests here. |
@ -0,0 +1,8 @@ |
||||
# filepath: backend/app/urls.py |
||||
|
||||
from django.urls import path |
||||
from . import views |
||||
|
||||
urlpatterns = [ |
||||
path('login/', views.login_view, name='login_view'), |
||||
] |
@ -0,0 +1,29 @@ |
||||
from rest_framework import status |
||||
from rest_framework.decorators import api_view |
||||
from rest_framework.response import Response |
||||
from .models import ExampleModel |
||||
from django.contrib.auth import authenticate |
||||
from .serializers import LoginSerializer |
||||
from .serializers import ExampleModelSerializer |
||||
|
||||
@api_view(['POST']) |
||||
def create_example(request): |
||||
if request.method == 'POST': |
||||
serializer = ExampleModelSerializer(data=request.data) |
||||
if serializer.is_valid(): |
||||
serializer.save() |
||||
return Response(serializer.data, status=status.HTTP_201_CREATED) |
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
||||
|
||||
@api_view(['POST']) |
||||
def login_view(request): |
||||
serializer = LoginSerializer(data=request.data) |
||||
if serializer.is_valid(): |
||||
username = serializer.data['username'] |
||||
password = serializer.data['password'] |
||||
user = authenticate(username=username, password=password) |
||||
if user is not None: |
||||
return Response({"message": "Login successful"}, status=status.HTTP_200_OK) |
||||
else: |
||||
return Response({"error": "Invalid credentials"}, status=status.HTTP_400_BAD_REQUEST) |
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,16 @@ |
||||
""" |
||||
ASGI config for backend project. |
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``. |
||||
|
||||
For more information on this file, see |
||||
https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ |
||||
""" |
||||
|
||||
import os |
||||
|
||||
from django.core.asgi import get_asgi_application |
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') |
||||
|
||||
application = get_asgi_application() |
@ -0,0 +1,125 @@ |
||||
""" |
||||
Django settings for backend project. |
||||
|
||||
Generated by 'django-admin startproject' using Django 5.1.4. |
||||
|
||||
For more information on this file, see |
||||
https://docs.djangoproject.com/en/5.1/topics/settings/ |
||||
|
||||
For the full list of settings and their values, see |
||||
https://docs.djangoproject.com/en/5.1/ref/settings/ |
||||
""" |
||||
|
||||
from pathlib import Path |
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'. |
||||
BASE_DIR = Path(__file__).resolve().parent.parent |
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production |
||||
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ |
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret! |
||||
SECRET_KEY = 'django-insecure-p23p8*=sjfthi+5w2qk%!-qag1d3s6o6vkq#c#izan5tnf5_uc' |
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production! |
||||
DEBUG = True |
||||
|
||||
ALLOWED_HOSTS = [] |
||||
|
||||
|
||||
# Application definition |
||||
|
||||
INSTALLED_APPS = [ |
||||
'django.contrib.admin', |
||||
'django.contrib.auth', |
||||
'django.contrib.contenttypes', |
||||
'django.contrib.sessions', |
||||
'django.contrib.messages', |
||||
'django.contrib.staticfiles', |
||||
'rest_framework', # Add this line |
||||
'app', # Ensure this is correctly listed |
||||
] |
||||
|
||||
MIDDLEWARE = [ |
||||
'django.middleware.security.SecurityMiddleware', |
||||
'django.contrib.sessions.middleware.SessionMiddleware', |
||||
'django.middleware.common.CommonMiddleware', |
||||
'django.middleware.csrf.CsrfViewMiddleware', |
||||
'django.contrib.auth.middleware.AuthenticationMiddleware', |
||||
'django.contrib.messages.middleware.MessageMiddleware', |
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware', |
||||
] |
||||
|
||||
ROOT_URLCONF = 'backend.urls' |
||||
|
||||
TEMPLATES = [ |
||||
{ |
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates', |
||||
'DIRS': [], |
||||
'APP_DIRS': True, |
||||
'OPTIONS': { |
||||
'context_processors': [ |
||||
'django.template.context_processors.debug', |
||||
'django.template.context_processors.request', |
||||
'django.contrib.auth.context_processors.auth', |
||||
'django.contrib.messages.context_processors.messages', |
||||
], |
||||
}, |
||||
}, |
||||
] |
||||
|
||||
WSGI_APPLICATION = 'backend.wsgi.application' |
||||
|
||||
|
||||
# Database |
||||
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases |
||||
|
||||
DATABASES = { |
||||
'default': { |
||||
'ENGINE': 'django.db.backends.sqlite3', |
||||
'NAME': BASE_DIR / 'db.sqlite3', |
||||
} |
||||
} |
||||
|
||||
|
||||
# Password validation |
||||
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators |
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [ |
||||
{ |
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', |
||||
}, |
||||
{ |
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', |
||||
}, |
||||
{ |
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', |
||||
}, |
||||
{ |
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', |
||||
}, |
||||
] |
||||
|
||||
|
||||
# Internationalization |
||||
# https://docs.djangoproject.com/en/5.1/topics/i18n/ |
||||
|
||||
LANGUAGE_CODE = 'en-us' |
||||
|
||||
TIME_ZONE = 'UTC' |
||||
|
||||
USE_I18N = True |
||||
|
||||
USE_TZ = True |
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images) |
||||
# https://docs.djangoproject.com/en/5.1/howto/static-files/ |
||||
|
||||
STATIC_URL = 'static/' |
||||
|
||||
# Default primary key field type |
||||
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field |
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' |
@ -0,0 +1,22 @@ |
||||
""" |
||||
URL configuration for backend project. |
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see: |
||||
https://docs.djangoproject.com/en/5.1/topics/http/urls/ |
||||
Examples: |
||||
Function views |
||||
1. Add an import: from my_app import views |
||||
2. Add a URL to urlpatterns: path('', views.home, name='home') |
||||
Class-based views |
||||
1. Add an import: from other_app.views import Home |
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') |
||||
Including another URLconf |
||||
1. Import the include() function: from django.urls import include, path |
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) |
||||
""" |
||||
from django.contrib import admin |
||||
from django.urls import path |
||||
|
||||
urlpatterns = [ |
||||
path('admin/', admin.site.urls), |
||||
] |
@ -0,0 +1,16 @@ |
||||
""" |
||||
WSGI config for backend project. |
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``. |
||||
|
||||
For more information on this file, see |
||||
https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ |
||||
""" |
||||
|
||||
import os |
||||
|
||||
from django.core.wsgi import get_wsgi_application |
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') |
||||
|
||||
application = get_wsgi_application() |
@ -0,0 +1,22 @@ |
||||
#!/usr/bin/env python |
||||
"""Django's command-line utility for administrative tasks.""" |
||||
import os |
||||
import sys |
||||
|
||||
|
||||
def main(): |
||||
"""Run administrative tasks.""" |
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings') |
||||
try: |
||||
from django.core.management import execute_from_command_line |
||||
except ImportError as exc: |
||||
raise ImportError( |
||||
"Couldn't import Django. Are you sure it's installed and " |
||||
"available on your PYTHONPATH environment variable? Did you " |
||||
"forget to activate a virtual environment?" |
||||
) from exc |
||||
execute_from_command_line(sys.argv) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
Loading…
Reference in new issue