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